chiark / gitweb /
c2173c7222f192ae6ce5b373b3f7809cfc54539b
[elogind.git] / src / 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 General Public License as published by
10   the Free Software Foundation; either version 2 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   General Public License for more details.
17
18   You should have received a copy of the GNU 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/capability.h>
54
55 #include "macro.h"
56 #include "util.h"
57 #include "ioprio.h"
58 #include "missing.h"
59 #include "log.h"
60 #include "strv.h"
61 #include "label.h"
62 #include "exit-status.h"
63 #include "hashmap.h"
64
65 size_t page_size(void) {
66         static __thread size_t pgsz = 0;
67         long r;
68
69         if (pgsz)
70                 return pgsz;
71
72         assert_se((r = sysconf(_SC_PAGESIZE)) > 0);
73
74         pgsz = (size_t) r;
75
76         return pgsz;
77 }
78
79 bool streq_ptr(const char *a, const char *b) {
80
81         /* Like streq(), but tries to make sense of NULL pointers */
82
83         if (a && b)
84                 return streq(a, b);
85
86         if (!a && !b)
87                 return true;
88
89         return false;
90 }
91
92 usec_t now(clockid_t clock_id) {
93         struct timespec ts;
94
95         assert_se(clock_gettime(clock_id, &ts) == 0);
96
97         return timespec_load(&ts);
98 }
99
100 dual_timestamp* dual_timestamp_get(dual_timestamp *ts) {
101         assert(ts);
102
103         ts->realtime = now(CLOCK_REALTIME);
104         ts->monotonic = now(CLOCK_MONOTONIC);
105
106         return ts;
107 }
108
109 usec_t timespec_load(const struct timespec *ts) {
110         assert(ts);
111
112         return
113                 (usec_t) ts->tv_sec * USEC_PER_SEC +
114                 (usec_t) ts->tv_nsec / NSEC_PER_USEC;
115 }
116
117 struct timespec *timespec_store(struct timespec *ts, usec_t u)  {
118         assert(ts);
119
120         ts->tv_sec = (time_t) (u / USEC_PER_SEC);
121         ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
122
123         return ts;
124 }
125
126 usec_t timeval_load(const struct timeval *tv) {
127         assert(tv);
128
129         return
130                 (usec_t) tv->tv_sec * USEC_PER_SEC +
131                 (usec_t) tv->tv_usec;
132 }
133
134 struct timeval *timeval_store(struct timeval *tv, usec_t u) {
135         assert(tv);
136
137         tv->tv_sec = (time_t) (u / USEC_PER_SEC);
138         tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
139
140         return tv;
141 }
142
143 bool endswith(const char *s, const char *postfix) {
144         size_t sl, pl;
145
146         assert(s);
147         assert(postfix);
148
149         sl = strlen(s);
150         pl = strlen(postfix);
151
152         if (pl == 0)
153                 return true;
154
155         if (sl < pl)
156                 return false;
157
158         return memcmp(s + sl - pl, postfix, pl) == 0;
159 }
160
161 bool startswith(const char *s, const char *prefix) {
162         size_t sl, pl;
163
164         assert(s);
165         assert(prefix);
166
167         sl = strlen(s);
168         pl = strlen(prefix);
169
170         if (pl == 0)
171                 return true;
172
173         if (sl < pl)
174                 return false;
175
176         return memcmp(s, prefix, pl) == 0;
177 }
178
179 bool startswith_no_case(const char *s, const char *prefix) {
180         size_t sl, pl;
181         unsigned i;
182
183         assert(s);
184         assert(prefix);
185
186         sl = strlen(s);
187         pl = strlen(prefix);
188
189         if (pl == 0)
190                 return true;
191
192         if (sl < pl)
193                 return false;
194
195         for(i = 0; i < pl; ++i) {
196                 if (tolower(s[i]) != tolower(prefix[i]))
197                         return false;
198         }
199
200         return true;
201 }
202
203 bool first_word(const char *s, const char *word) {
204         size_t sl, wl;
205
206         assert(s);
207         assert(word);
208
209         sl = strlen(s);
210         wl = strlen(word);
211
212         if (sl < wl)
213                 return false;
214
215         if (wl == 0)
216                 return true;
217
218         if (memcmp(s, word, wl) != 0)
219                 return false;
220
221         return s[wl] == 0 ||
222                 strchr(WHITESPACE, s[wl]);
223 }
224
225 int close_nointr(int fd) {
226         assert(fd >= 0);
227
228         for (;;) {
229                 int r;
230
231                 if ((r = close(fd)) >= 0)
232                         return r;
233
234                 if (errno != EINTR)
235                         return r;
236         }
237 }
238
239 void close_nointr_nofail(int fd) {
240         int saved_errno = errno;
241
242         /* like close_nointr() but cannot fail, and guarantees errno
243          * is unchanged */
244
245         assert_se(close_nointr(fd) == 0);
246
247         errno = saved_errno;
248 }
249
250 void close_many(const int fds[], unsigned n_fd) {
251         unsigned i;
252
253         for (i = 0; i < n_fd; i++)
254                 close_nointr_nofail(fds[i]);
255 }
256
257 int parse_boolean(const char *v) {
258         assert(v);
259
260         if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
261                 return 1;
262         else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
263                 return 0;
264
265         return -EINVAL;
266 }
267
268 int parse_pid(const char *s, pid_t* ret_pid) {
269         unsigned long ul = 0;
270         pid_t pid;
271         int r;
272
273         assert(s);
274         assert(ret_pid);
275
276         if ((r = safe_atolu(s, &ul)) < 0)
277                 return r;
278
279         pid = (pid_t) ul;
280
281         if ((unsigned long) pid != ul)
282                 return -ERANGE;
283
284         if (pid <= 0)
285                 return -ERANGE;
286
287         *ret_pid = pid;
288         return 0;
289 }
290
291 int safe_atou(const char *s, unsigned *ret_u) {
292         char *x = NULL;
293         unsigned long l;
294
295         assert(s);
296         assert(ret_u);
297
298         errno = 0;
299         l = strtoul(s, &x, 0);
300
301         if (!x || *x || errno)
302                 return errno ? -errno : -EINVAL;
303
304         if ((unsigned long) (unsigned) l != l)
305                 return -ERANGE;
306
307         *ret_u = (unsigned) l;
308         return 0;
309 }
310
311 int safe_atoi(const char *s, int *ret_i) {
312         char *x = NULL;
313         long l;
314
315         assert(s);
316         assert(ret_i);
317
318         errno = 0;
319         l = strtol(s, &x, 0);
320
321         if (!x || *x || errno)
322                 return errno ? -errno : -EINVAL;
323
324         if ((long) (int) l != l)
325                 return -ERANGE;
326
327         *ret_i = (int) l;
328         return 0;
329 }
330
331 int safe_atollu(const char *s, long long unsigned *ret_llu) {
332         char *x = NULL;
333         unsigned long long l;
334
335         assert(s);
336         assert(ret_llu);
337
338         errno = 0;
339         l = strtoull(s, &x, 0);
340
341         if (!x || *x || errno)
342                 return errno ? -errno : -EINVAL;
343
344         *ret_llu = l;
345         return 0;
346 }
347
348 int safe_atolli(const char *s, long long int *ret_lli) {
349         char *x = NULL;
350         long long l;
351
352         assert(s);
353         assert(ret_lli);
354
355         errno = 0;
356         l = strtoll(s, &x, 0);
357
358         if (!x || *x || errno)
359                 return errno ? -errno : -EINVAL;
360
361         *ret_lli = l;
362         return 0;
363 }
364
365 /* Split a string into words. */
366 char *split(const char *c, size_t *l, const char *separator, char **state) {
367         char *current;
368
369         current = *state ? *state : (char*) c;
370
371         if (!*current || *c == 0)
372                 return NULL;
373
374         current += strspn(current, separator);
375         *l = strcspn(current, separator);
376         *state = current+*l;
377
378         return (char*) current;
379 }
380
381 /* Split a string into words, but consider strings enclosed in '' and
382  * "" as words even if they include spaces. */
383 char *split_quoted(const char *c, size_t *l, char **state) {
384         char *current, *e;
385         bool escaped = false;
386
387         current = *state ? *state : (char*) c;
388
389         if (!*current || *c == 0)
390                 return NULL;
391
392         current += strspn(current, WHITESPACE);
393
394         if (*current == '\'') {
395                 current ++;
396
397                 for (e = current; *e; e++) {
398                         if (escaped)
399                                 escaped = false;
400                         else if (*e == '\\')
401                                 escaped = true;
402                         else if (*e == '\'')
403                                 break;
404                 }
405
406                 *l = e-current;
407                 *state = *e == 0 ? e : e+1;
408         } else if (*current == '\"') {
409                 current ++;
410
411                 for (e = current; *e; e++) {
412                         if (escaped)
413                                 escaped = false;
414                         else if (*e == '\\')
415                                 escaped = true;
416                         else if (*e == '\"')
417                                 break;
418                 }
419
420                 *l = e-current;
421                 *state = *e == 0 ? e : e+1;
422         } else {
423                 for (e = current; *e; e++) {
424                         if (escaped)
425                                 escaped = false;
426                         else if (*e == '\\')
427                                 escaped = true;
428                         else if (strchr(WHITESPACE, *e))
429                                 break;
430                 }
431                 *l = e-current;
432                 *state = e;
433         }
434
435         return (char*) current;
436 }
437
438 char **split_path_and_make_absolute(const char *p) {
439         char **l;
440         assert(p);
441
442         if (!(l = strv_split(p, ":")))
443                 return NULL;
444
445         if (!strv_path_make_absolute_cwd(l)) {
446                 strv_free(l);
447                 return NULL;
448         }
449
450         return l;
451 }
452
453 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
454         int r;
455         FILE *f;
456         char fn[PATH_MAX], line[LINE_MAX], *p;
457         long unsigned ppid;
458
459         assert(pid > 0);
460         assert(_ppid);
461
462         assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
463         char_array_0(fn);
464
465         if (!(f = fopen(fn, "r")))
466                 return -errno;
467
468         if (!(fgets(line, sizeof(line), f))) {
469                 r = -errno;
470                 fclose(f);
471                 return r;
472         }
473
474         fclose(f);
475
476         /* Let's skip the pid and comm fields. The latter is enclosed
477          * in () but does not escape any () in its value, so let's
478          * skip over it manually */
479
480         if (!(p = strrchr(line, ')')))
481                 return -EIO;
482
483         p++;
484
485         if (sscanf(p, " "
486                    "%*c "  /* state */
487                    "%lu ", /* ppid */
488                    &ppid) != 1)
489                 return -EIO;
490
491         if ((long unsigned) (pid_t) ppid != ppid)
492                 return -ERANGE;
493
494         *_ppid = (pid_t) ppid;
495
496         return 0;
497 }
498
499 int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
500         int r;
501         FILE *f;
502         char fn[PATH_MAX], line[LINE_MAX], *p;
503
504         assert(pid > 0);
505         assert(st);
506
507         assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
508         char_array_0(fn);
509
510         if (!(f = fopen(fn, "r")))
511                 return -errno;
512
513         if (!(fgets(line, sizeof(line), f))) {
514                 r = -errno;
515                 fclose(f);
516                 return r;
517         }
518
519         fclose(f);
520
521         /* Let's skip the pid and comm fields. The latter is enclosed
522          * in () but does not escape any () in its value, so let's
523          * skip over it manually */
524
525         if (!(p = strrchr(line, ')')))
526                 return -EIO;
527
528         p++;
529
530         if (sscanf(p, " "
531                    "%*c "  /* state */
532                    "%*d "  /* ppid */
533                    "%*d "  /* pgrp */
534                    "%*d "  /* session */
535                    "%*d "  /* tty_nr */
536                    "%*d "  /* tpgid */
537                    "%*u "  /* flags */
538                    "%*u "  /* minflt */
539                    "%*u "  /* cminflt */
540                    "%*u "  /* majflt */
541                    "%*u "  /* cmajflt */
542                    "%*u "  /* utime */
543                    "%*u "  /* stime */
544                    "%*d "  /* cutime */
545                    "%*d "  /* cstime */
546                    "%*d "  /* priority */
547                    "%*d "  /* nice */
548                    "%*d "  /* num_threads */
549                    "%*d "  /* itrealvalue */
550                    "%llu "  /* starttime */,
551                    st) != 1)
552                 return -EIO;
553
554         return 0;
555 }
556
557 int write_one_line_file(const char *fn, const char *line) {
558         FILE *f;
559         int r;
560
561         assert(fn);
562         assert(line);
563
564         if (!(f = fopen(fn, "we")))
565                 return -errno;
566
567         if (fputs(line, f) < 0) {
568                 r = -errno;
569                 goto finish;
570         }
571
572         if (!endswith(line, "\n"))
573                 fputc('\n', f);
574
575         fflush(f);
576
577         if (ferror(f)) {
578                 if (errno != 0)
579                         r = -errno;
580                 else
581                         r = -EIO;
582         } else
583                 r = 0;
584
585 finish:
586         fclose(f);
587         return r;
588 }
589
590 int read_one_line_file(const char *fn, char **line) {
591         FILE *f;
592         int r;
593         char t[LINE_MAX], *c;
594
595         assert(fn);
596         assert(line);
597
598         if (!(f = fopen(fn, "re")))
599                 return -errno;
600
601         if (!(fgets(t, sizeof(t), f))) {
602                 r = -errno;
603                 goto finish;
604         }
605
606         if (!(c = strdup(t))) {
607                 r = -ENOMEM;
608                 goto finish;
609         }
610
611         truncate_nl(c);
612
613         *line = c;
614         r = 0;
615
616 finish:
617         fclose(f);
618         return r;
619 }
620
621 int read_full_file(const char *fn, char **contents) {
622         FILE *f;
623         int r;
624         size_t n, l;
625         char *buf = NULL;
626         struct stat st;
627
628         if (!(f = fopen(fn, "re")))
629                 return -errno;
630
631         if (fstat(fileno(f), &st) < 0) {
632                 r = -errno;
633                 goto finish;
634         }
635
636         n = st.st_size > 0 ? st.st_size : LINE_MAX;
637         l = 0;
638
639         for (;;) {
640                 char *t;
641                 size_t k;
642
643                 if (!(t = realloc(buf, n+1))) {
644                         r = -ENOMEM;
645                         goto finish;
646                 }
647
648                 buf = t;
649                 k = fread(buf + l, 1, n - l, f);
650
651                 if (k <= 0) {
652                         if (ferror(f)) {
653                                 r = -errno;
654                                 goto finish;
655                         }
656
657                         break;
658                 }
659
660                 l += k;
661                 n *= 2;
662
663                 /* Safety check */
664                 if (n > 4*1024*1024) {
665                         r = -E2BIG;
666                         goto finish;
667                 }
668         }
669
670         if (buf)
671                 buf[l] = 0;
672         else if (!(buf = calloc(1, 1))) {
673                 r = -errno;
674                 goto finish;
675         }
676
677         *contents = buf;
678         buf = NULL;
679
680         r = 0;
681
682 finish:
683         fclose(f);
684         free(buf);
685
686         return r;
687 }
688
689 int parse_env_file(
690                 const char *fname,
691                 const char *separator, ...) {
692
693         int r = 0;
694         char *contents, *p;
695
696         assert(fname);
697         assert(separator);
698
699         if ((r = read_full_file(fname, &contents)) < 0)
700                 return r;
701
702         p = contents;
703         for (;;) {
704                 const char *key = NULL;
705
706                 p += strspn(p, separator);
707                 p += strspn(p, WHITESPACE);
708
709                 if (!*p)
710                         break;
711
712                 if (!strchr(COMMENTS, *p)) {
713                         va_list ap;
714                         char **value;
715
716                         va_start(ap, separator);
717                         while ((key = va_arg(ap, char *))) {
718                                 size_t n;
719                                 char *v;
720
721                                 value = va_arg(ap, char **);
722
723                                 n = strlen(key);
724                                 if (strncmp(p, key, n) != 0 ||
725                                     p[n] != '=')
726                                         continue;
727
728                                 p += n + 1;
729                                 n = strcspn(p, separator);
730
731                                 if (n >= 2 &&
732                                     strchr(QUOTES, p[0]) &&
733                                     p[n-1] == p[0])
734                                         v = strndup(p+1, n-2);
735                                 else
736                                         v = strndup(p, n);
737
738                                 if (!v) {
739                                         r = -ENOMEM;
740                                         va_end(ap);
741                                         goto fail;
742                                 }
743
744                                 if (v[0] == '\0') {
745                                         /* return empty value strings as NULL */
746                                         free(v);
747                                         v = NULL;
748                                 }
749
750                                 free(*value);
751                                 *value = v;
752
753                                 p += n;
754
755                                 r ++;
756                                 break;
757                         }
758                         va_end(ap);
759                 }
760
761                 if (!key)
762                         p += strcspn(p, separator);
763         }
764
765 fail:
766         free(contents);
767         return r;
768 }
769
770 int load_env_file(
771                 const char *fname,
772                 char ***rl) {
773
774         FILE *f;
775         char **m = 0;
776         int r;
777
778         assert(fname);
779         assert(rl);
780
781         if (!(f = fopen(fname, "re")))
782                 return -errno;
783
784         while (!feof(f)) {
785                 char l[LINE_MAX], *p, *u;
786                 char **t;
787
788                 if (!fgets(l, sizeof(l), f)) {
789                         if (feof(f))
790                                 break;
791
792                         r = -errno;
793                         goto finish;
794                 }
795
796                 p = strstrip(l);
797
798                 if (!*p)
799                         continue;
800
801                 if (strchr(COMMENTS, *p))
802                         continue;
803
804                 if (!(u = normalize_env_assignment(p))) {
805                         log_error("Out of memory");
806                         r = -ENOMEM;
807                         goto finish;
808                 }
809
810                 t = strv_append(m, u);
811                 free(u);
812
813                 if (!t) {
814                         log_error("Out of memory");
815                         r = -ENOMEM;
816                         goto finish;
817                 }
818
819                 strv_free(m);
820                 m = t;
821         }
822
823         r = 0;
824
825         *rl = m;
826         m = NULL;
827
828 finish:
829         if (f)
830                 fclose(f);
831
832         strv_free(m);
833
834         return r;
835 }
836
837 int write_env_file(const char *fname, char **l) {
838
839         char **i;
840         FILE *f;
841         int r;
842
843         f = fopen(fname, "we");
844         if (!f)
845                 return -errno;
846
847         STRV_FOREACH(i, l) {
848                 fputs(*i, f);
849                 fputc('\n', f);
850         }
851
852         fflush(f);
853
854         r = ferror(f) ? -errno : 0;
855         fclose(f);
856
857         return r;
858 }
859
860 char *truncate_nl(char *s) {
861         assert(s);
862
863         s[strcspn(s, NEWLINE)] = 0;
864         return s;
865 }
866
867 int get_process_name(pid_t pid, char **name) {
868         char *p;
869         int r;
870
871         assert(pid >= 1);
872         assert(name);
873
874         if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
875                 return -ENOMEM;
876
877         r = read_one_line_file(p, name);
878         free(p);
879
880         if (r < 0)
881                 return r;
882
883         return 0;
884 }
885
886 int get_process_cmdline(pid_t pid, size_t max_length, char **line) {
887         char *p, *r, *k;
888         int c;
889         bool space = false;
890         size_t left;
891         FILE *f;
892
893         assert(pid >= 1);
894         assert(max_length > 0);
895         assert(line);
896
897         if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
898                 return -ENOMEM;
899
900         f = fopen(p, "r");
901         free(p);
902
903         if (!f)
904                 return -errno;
905
906         if (!(r = new(char, max_length))) {
907                 fclose(f);
908                 return -ENOMEM;
909         }
910
911         k = r;
912         left = max_length;
913         while ((c = getc(f)) != EOF) {
914
915                 if (isprint(c)) {
916                         if (space) {
917                                 if (left <= 4)
918                                         break;
919
920                                 *(k++) = ' ';
921                                 left--;
922                                 space = false;
923                         }
924
925                         if (left <= 4)
926                                 break;
927
928                         *(k++) = (char) c;
929                         left--;
930                 }  else
931                         space = true;
932         }
933
934         if (left <= 4) {
935                 size_t n = MIN(left-1, 3U);
936                 memcpy(k, "...", n);
937                 k[n] = 0;
938         } else
939                 *k = 0;
940
941         fclose(f);
942
943         /* Kernel threads have no argv[] */
944         if (r[0] == 0) {
945                 char *t;
946                 int h;
947
948                 free(r);
949
950                 if ((h = get_process_name(pid, &t)) < 0)
951                         return h;
952
953                 h = asprintf(&r, "[%s]", t);
954                 free(t);
955
956                 if (h < 0)
957                         return -ENOMEM;
958         }
959
960         *line = r;
961         return 0;
962 }
963
964 char *strnappend(const char *s, const char *suffix, size_t b) {
965         size_t a;
966         char *r;
967
968         if (!s && !suffix)
969                 return strdup("");
970
971         if (!s)
972                 return strndup(suffix, b);
973
974         if (!suffix)
975                 return strdup(s);
976
977         assert(s);
978         assert(suffix);
979
980         a = strlen(s);
981
982         if (!(r = new(char, a+b+1)))
983                 return NULL;
984
985         memcpy(r, s, a);
986         memcpy(r+a, suffix, b);
987         r[a+b] = 0;
988
989         return r;
990 }
991
992 char *strappend(const char *s, const char *suffix) {
993         return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
994 }
995
996 int readlink_malloc(const char *p, char **r) {
997         size_t l = 100;
998
999         assert(p);
1000         assert(r);
1001
1002         for (;;) {
1003                 char *c;
1004                 ssize_t n;
1005
1006                 if (!(c = new(char, l)))
1007                         return -ENOMEM;
1008
1009                 if ((n = readlink(p, c, l-1)) < 0) {
1010                         int ret = -errno;
1011                         free(c);
1012                         return ret;
1013                 }
1014
1015                 if ((size_t) n < l-1) {
1016                         c[n] = 0;
1017                         *r = c;
1018                         return 0;
1019                 }
1020
1021                 free(c);
1022                 l *= 2;
1023         }
1024 }
1025
1026 int readlink_and_make_absolute(const char *p, char **r) {
1027         char *target, *k;
1028         int j;
1029
1030         assert(p);
1031         assert(r);
1032
1033         if ((j = readlink_malloc(p, &target)) < 0)
1034                 return j;
1035
1036         k = file_in_same_dir(p, target);
1037         free(target);
1038
1039         if (!k)
1040                 return -ENOMEM;
1041
1042         *r = k;
1043         return 0;
1044 }
1045
1046 int parent_of_path(const char *path, char **_r) {
1047         const char *e, *a = NULL, *b = NULL, *p;
1048         char *r;
1049         bool slash = false;
1050
1051         assert(path);
1052         assert(_r);
1053
1054         if (!*path)
1055                 return -EINVAL;
1056
1057         for (e = path; *e; e++) {
1058
1059                 if (!slash && *e == '/') {
1060                         a = b;
1061                         b = e;
1062                         slash = true;
1063                 } else if (slash && *e != '/')
1064                         slash = false;
1065         }
1066
1067         if (*(e-1) == '/')
1068                 p = a;
1069         else
1070                 p = b;
1071
1072         if (!p)
1073                 return -EINVAL;
1074
1075         if (p == path)
1076                 r = strdup("/");
1077         else
1078                 r = strndup(path, p-path);
1079
1080         if (!r)
1081                 return -ENOMEM;
1082
1083         *_r = r;
1084         return 0;
1085 }
1086
1087
1088 char *file_name_from_path(const char *p) {
1089         char *r;
1090
1091         assert(p);
1092
1093         if ((r = strrchr(p, '/')))
1094                 return r + 1;
1095
1096         return (char*) p;
1097 }
1098
1099 bool path_is_absolute(const char *p) {
1100         assert(p);
1101
1102         return p[0] == '/';
1103 }
1104
1105 bool is_path(const char *p) {
1106
1107         return !!strchr(p, '/');
1108 }
1109
1110 char *path_make_absolute(const char *p, const char *prefix) {
1111         char *r;
1112
1113         assert(p);
1114
1115         /* Makes every item in the list an absolute path by prepending
1116          * the prefix, if specified and necessary */
1117
1118         if (path_is_absolute(p) || !prefix)
1119                 return strdup(p);
1120
1121         if (asprintf(&r, "%s/%s", prefix, p) < 0)
1122                 return NULL;
1123
1124         return r;
1125 }
1126
1127 char *path_make_absolute_cwd(const char *p) {
1128         char *cwd, *r;
1129
1130         assert(p);
1131
1132         /* Similar to path_make_absolute(), but prefixes with the
1133          * current working directory. */
1134
1135         if (path_is_absolute(p))
1136                 return strdup(p);
1137
1138         if (!(cwd = get_current_dir_name()))
1139                 return NULL;
1140
1141         r = path_make_absolute(p, cwd);
1142         free(cwd);
1143
1144         return r;
1145 }
1146
1147 char **strv_path_make_absolute_cwd(char **l) {
1148         char **s;
1149
1150         /* Goes through every item in the string list and makes it
1151          * absolute. This works in place and won't rollback any
1152          * changes on failure. */
1153
1154         STRV_FOREACH(s, l) {
1155                 char *t;
1156
1157                 if (!(t = path_make_absolute_cwd(*s)))
1158                         return NULL;
1159
1160                 free(*s);
1161                 *s = t;
1162         }
1163
1164         return l;
1165 }
1166
1167 char **strv_path_canonicalize(char **l) {
1168         char **s;
1169         unsigned k = 0;
1170         bool enomem = false;
1171
1172         if (strv_isempty(l))
1173                 return l;
1174
1175         /* Goes through every item in the string list and canonicalize
1176          * the path. This works in place and won't rollback any
1177          * changes on failure. */
1178
1179         STRV_FOREACH(s, l) {
1180                 char *t, *u;
1181
1182                 t = path_make_absolute_cwd(*s);
1183                 free(*s);
1184
1185                 if (!t) {
1186                         enomem = true;
1187                         continue;
1188                 }
1189
1190                 errno = 0;
1191                 u = canonicalize_file_name(t);
1192                 free(t);
1193
1194                 if (!u) {
1195                         if (errno == ENOMEM || !errno)
1196                                 enomem = true;
1197
1198                         continue;
1199                 }
1200
1201                 l[k++] = u;
1202         }
1203
1204         l[k] = NULL;
1205
1206         if (enomem)
1207                 return NULL;
1208
1209         return l;
1210 }
1211
1212 int reset_all_signal_handlers(void) {
1213         int sig;
1214
1215         for (sig = 1; sig < _NSIG; sig++) {
1216                 struct sigaction sa;
1217
1218                 if (sig == SIGKILL || sig == SIGSTOP)
1219                         continue;
1220
1221                 zero(sa);
1222                 sa.sa_handler = SIG_DFL;
1223                 sa.sa_flags = SA_RESTART;
1224
1225                 /* On Linux the first two RT signals are reserved by
1226                  * glibc, and sigaction() will return EINVAL for them. */
1227                 if ((sigaction(sig, &sa, NULL) < 0))
1228                         if (errno != EINVAL)
1229                                 return -errno;
1230         }
1231
1232         return 0;
1233 }
1234
1235 char *strstrip(char *s) {
1236         char *e, *l = NULL;
1237
1238         /* Drops trailing whitespace. Modifies the string in
1239          * place. Returns pointer to first non-space character */
1240
1241         s += strspn(s, WHITESPACE);
1242
1243         for (e = s; *e; e++)
1244                 if (!strchr(WHITESPACE, *e))
1245                         l = e;
1246
1247         if (l)
1248                 *(l+1) = 0;
1249         else
1250                 *s = 0;
1251
1252         return s;
1253 }
1254
1255 char *delete_chars(char *s, const char *bad) {
1256         char *f, *t;
1257
1258         /* Drops all whitespace, regardless where in the string */
1259
1260         for (f = s, t = s; *f; f++) {
1261                 if (strchr(bad, *f))
1262                         continue;
1263
1264                 *(t++) = *f;
1265         }
1266
1267         *t = 0;
1268
1269         return s;
1270 }
1271
1272 char *file_in_same_dir(const char *path, const char *filename) {
1273         char *e, *r;
1274         size_t k;
1275
1276         assert(path);
1277         assert(filename);
1278
1279         /* This removes the last component of path and appends
1280          * filename, unless the latter is absolute anyway or the
1281          * former isn't */
1282
1283         if (path_is_absolute(filename))
1284                 return strdup(filename);
1285
1286         if (!(e = strrchr(path, '/')))
1287                 return strdup(filename);
1288
1289         k = strlen(filename);
1290         if (!(r = new(char, e-path+1+k+1)))
1291                 return NULL;
1292
1293         memcpy(r, path, e-path+1);
1294         memcpy(r+(e-path)+1, filename, k+1);
1295
1296         return r;
1297 }
1298
1299 int safe_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid) {
1300         struct stat st;
1301
1302         if (label_mkdir(path, mode) >= 0)
1303                 if (chmod_and_chown(path, mode, uid, gid) < 0)
1304                         return -errno;
1305
1306         if (lstat(path, &st) < 0)
1307                 return -errno;
1308
1309         if ((st.st_mode & 0777) != mode ||
1310             st.st_uid != uid ||
1311             st.st_gid != gid ||
1312             !S_ISDIR(st.st_mode)) {
1313                 errno = EEXIST;
1314                 return -errno;
1315         }
1316
1317         return 0;
1318 }
1319
1320
1321 int mkdir_parents(const char *path, mode_t mode) {
1322         const char *p, *e;
1323
1324         assert(path);
1325
1326         /* Creates every parent directory in the path except the last
1327          * component. */
1328
1329         p = path + strspn(path, "/");
1330         for (;;) {
1331                 int r;
1332                 char *t;
1333
1334                 e = p + strcspn(p, "/");
1335                 p = e + strspn(e, "/");
1336
1337                 /* Is this the last component? If so, then we're
1338                  * done */
1339                 if (*p == 0)
1340                         return 0;
1341
1342                 if (!(t = strndup(path, e - path)))
1343                         return -ENOMEM;
1344
1345                 r = label_mkdir(t, mode);
1346                 free(t);
1347
1348                 if (r < 0 && errno != EEXIST)
1349                         return -errno;
1350         }
1351 }
1352
1353 int mkdir_p(const char *path, mode_t mode) {
1354         int r;
1355
1356         /* Like mkdir -p */
1357
1358         if ((r = mkdir_parents(path, mode)) < 0)
1359                 return r;
1360
1361         if (label_mkdir(path, mode) < 0 && errno != EEXIST)
1362                 return -errno;
1363
1364         return 0;
1365 }
1366
1367 int rmdir_parents(const char *path, const char *stop) {
1368         size_t l;
1369         int r = 0;
1370
1371         assert(path);
1372         assert(stop);
1373
1374         l = strlen(path);
1375
1376         /* Skip trailing slashes */
1377         while (l > 0 && path[l-1] == '/')
1378                 l--;
1379
1380         while (l > 0) {
1381                 char *t;
1382
1383                 /* Skip last component */
1384                 while (l > 0 && path[l-1] != '/')
1385                         l--;
1386
1387                 /* Skip trailing slashes */
1388                 while (l > 0 && path[l-1] == '/')
1389                         l--;
1390
1391                 if (l <= 0)
1392                         break;
1393
1394                 if (!(t = strndup(path, l)))
1395                         return -ENOMEM;
1396
1397                 if (path_startswith(stop, t)) {
1398                         free(t);
1399                         return 0;
1400                 }
1401
1402                 r = rmdir(t);
1403                 free(t);
1404
1405                 if (r < 0)
1406                         if (errno != ENOENT)
1407                                 return -errno;
1408         }
1409
1410         return 0;
1411 }
1412
1413
1414 char hexchar(int x) {
1415         static const char table[16] = "0123456789abcdef";
1416
1417         return table[x & 15];
1418 }
1419
1420 int unhexchar(char c) {
1421
1422         if (c >= '0' && c <= '9')
1423                 return c - '0';
1424
1425         if (c >= 'a' && c <= 'f')
1426                 return c - 'a' + 10;
1427
1428         if (c >= 'A' && c <= 'F')
1429                 return c - 'A' + 10;
1430
1431         return -1;
1432 }
1433
1434 char octchar(int x) {
1435         return '0' + (x & 7);
1436 }
1437
1438 int unoctchar(char c) {
1439
1440         if (c >= '0' && c <= '7')
1441                 return c - '0';
1442
1443         return -1;
1444 }
1445
1446 char decchar(int x) {
1447         return '0' + (x % 10);
1448 }
1449
1450 int undecchar(char c) {
1451
1452         if (c >= '0' && c <= '9')
1453                 return c - '0';
1454
1455         return -1;
1456 }
1457
1458 char *cescape(const char *s) {
1459         char *r, *t;
1460         const char *f;
1461
1462         assert(s);
1463
1464         /* Does C style string escaping. */
1465
1466         if (!(r = new(char, strlen(s)*4 + 1)))
1467                 return NULL;
1468
1469         for (f = s, t = r; *f; f++)
1470
1471                 switch (*f) {
1472
1473                 case '\a':
1474                         *(t++) = '\\';
1475                         *(t++) = 'a';
1476                         break;
1477                 case '\b':
1478                         *(t++) = '\\';
1479                         *(t++) = 'b';
1480                         break;
1481                 case '\f':
1482                         *(t++) = '\\';
1483                         *(t++) = 'f';
1484                         break;
1485                 case '\n':
1486                         *(t++) = '\\';
1487                         *(t++) = 'n';
1488                         break;
1489                 case '\r':
1490                         *(t++) = '\\';
1491                         *(t++) = 'r';
1492                         break;
1493                 case '\t':
1494                         *(t++) = '\\';
1495                         *(t++) = 't';
1496                         break;
1497                 case '\v':
1498                         *(t++) = '\\';
1499                         *(t++) = 'v';
1500                         break;
1501                 case '\\':
1502                         *(t++) = '\\';
1503                         *(t++) = '\\';
1504                         break;
1505                 case '"':
1506                         *(t++) = '\\';
1507                         *(t++) = '"';
1508                         break;
1509                 case '\'':
1510                         *(t++) = '\\';
1511                         *(t++) = '\'';
1512                         break;
1513
1514                 default:
1515                         /* For special chars we prefer octal over
1516                          * hexadecimal encoding, simply because glib's
1517                          * g_strescape() does the same */
1518                         if ((*f < ' ') || (*f >= 127)) {
1519                                 *(t++) = '\\';
1520                                 *(t++) = octchar((unsigned char) *f >> 6);
1521                                 *(t++) = octchar((unsigned char) *f >> 3);
1522                                 *(t++) = octchar((unsigned char) *f);
1523                         } else
1524                                 *(t++) = *f;
1525                         break;
1526                 }
1527
1528         *t = 0;
1529
1530         return r;
1531 }
1532
1533 char *cunescape_length(const char *s, size_t length) {
1534         char *r, *t;
1535         const char *f;
1536
1537         assert(s);
1538
1539         /* Undoes C style string escaping */
1540
1541         if (!(r = new(char, length+1)))
1542                 return r;
1543
1544         for (f = s, t = r; f < s + length; f++) {
1545
1546                 if (*f != '\\') {
1547                         *(t++) = *f;
1548                         continue;
1549                 }
1550
1551                 f++;
1552
1553                 switch (*f) {
1554
1555                 case 'a':
1556                         *(t++) = '\a';
1557                         break;
1558                 case 'b':
1559                         *(t++) = '\b';
1560                         break;
1561                 case 'f':
1562                         *(t++) = '\f';
1563                         break;
1564                 case 'n':
1565                         *(t++) = '\n';
1566                         break;
1567                 case 'r':
1568                         *(t++) = '\r';
1569                         break;
1570                 case 't':
1571                         *(t++) = '\t';
1572                         break;
1573                 case 'v':
1574                         *(t++) = '\v';
1575                         break;
1576                 case '\\':
1577                         *(t++) = '\\';
1578                         break;
1579                 case '"':
1580                         *(t++) = '"';
1581                         break;
1582                 case '\'':
1583                         *(t++) = '\'';
1584                         break;
1585
1586                 case 's':
1587                         /* This is an extension of the XDG syntax files */
1588                         *(t++) = ' ';
1589                         break;
1590
1591                 case 'x': {
1592                         /* hexadecimal encoding */
1593                         int a, b;
1594
1595                         if ((a = unhexchar(f[1])) < 0 ||
1596                             (b = unhexchar(f[2])) < 0) {
1597                                 /* Invalid escape code, let's take it literal then */
1598                                 *(t++) = '\\';
1599                                 *(t++) = 'x';
1600                         } else {
1601                                 *(t++) = (char) ((a << 4) | b);
1602                                 f += 2;
1603                         }
1604
1605                         break;
1606                 }
1607
1608                 case '0':
1609                 case '1':
1610                 case '2':
1611                 case '3':
1612                 case '4':
1613                 case '5':
1614                 case '6':
1615                 case '7': {
1616                         /* octal encoding */
1617                         int a, b, c;
1618
1619                         if ((a = unoctchar(f[0])) < 0 ||
1620                             (b = unoctchar(f[1])) < 0 ||
1621                             (c = unoctchar(f[2])) < 0) {
1622                                 /* Invalid escape code, let's take it literal then */
1623                                 *(t++) = '\\';
1624                                 *(t++) = f[0];
1625                         } else {
1626                                 *(t++) = (char) ((a << 6) | (b << 3) | c);
1627                                 f += 2;
1628                         }
1629
1630                         break;
1631                 }
1632
1633                 case 0:
1634                         /* premature end of string.*/
1635                         *(t++) = '\\';
1636                         goto finish;
1637
1638                 default:
1639                         /* Invalid escape code, let's take it literal then */
1640                         *(t++) = '\\';
1641                         *(t++) = *f;
1642                         break;
1643                 }
1644         }
1645
1646 finish:
1647         *t = 0;
1648         return r;
1649 }
1650
1651 char *cunescape(const char *s) {
1652         return cunescape_length(s, strlen(s));
1653 }
1654
1655 char *xescape(const char *s, const char *bad) {
1656         char *r, *t;
1657         const char *f;
1658
1659         /* Escapes all chars in bad, in addition to \ and all special
1660          * chars, in \xFF style escaping. May be reversed with
1661          * cunescape. */
1662
1663         if (!(r = new(char, strlen(s)*4+1)))
1664                 return NULL;
1665
1666         for (f = s, t = r; *f; f++) {
1667
1668                 if ((*f < ' ') || (*f >= 127) ||
1669                     (*f == '\\') || strchr(bad, *f)) {
1670                         *(t++) = '\\';
1671                         *(t++) = 'x';
1672                         *(t++) = hexchar(*f >> 4);
1673                         *(t++) = hexchar(*f);
1674                 } else
1675                         *(t++) = *f;
1676         }
1677
1678         *t = 0;
1679
1680         return r;
1681 }
1682
1683 char *bus_path_escape(const char *s) {
1684         char *r, *t;
1685         const char *f;
1686
1687         assert(s);
1688
1689         /* Escapes all chars that D-Bus' object path cannot deal
1690          * with. Can be reverse with bus_path_unescape() */
1691
1692         if (!(r = new(char, strlen(s)*3+1)))
1693                 return NULL;
1694
1695         for (f = s, t = r; *f; f++) {
1696
1697                 if (!(*f >= 'A' && *f <= 'Z') &&
1698                     !(*f >= 'a' && *f <= 'z') &&
1699                     !(*f >= '0' && *f <= '9')) {
1700                         *(t++) = '_';
1701                         *(t++) = hexchar(*f >> 4);
1702                         *(t++) = hexchar(*f);
1703                 } else
1704                         *(t++) = *f;
1705         }
1706
1707         *t = 0;
1708
1709         return r;
1710 }
1711
1712 char *bus_path_unescape(const char *f) {
1713         char *r, *t;
1714
1715         assert(f);
1716
1717         if (!(r = strdup(f)))
1718                 return NULL;
1719
1720         for (t = r; *f; f++) {
1721
1722                 if (*f == '_') {
1723                         int a, b;
1724
1725                         if ((a = unhexchar(f[1])) < 0 ||
1726                             (b = unhexchar(f[2])) < 0) {
1727                                 /* Invalid escape code, let's take it literal then */
1728                                 *(t++) = '_';
1729                         } else {
1730                                 *(t++) = (char) ((a << 4) | b);
1731                                 f += 2;
1732                         }
1733                 } else
1734                         *(t++) = *f;
1735         }
1736
1737         *t = 0;
1738
1739         return r;
1740 }
1741
1742 char *path_kill_slashes(char *path) {
1743         char *f, *t;
1744         bool slash = false;
1745
1746         /* Removes redundant inner and trailing slashes. Modifies the
1747          * passed string in-place.
1748          *
1749          * ///foo///bar/ becomes /foo/bar
1750          */
1751
1752         for (f = path, t = path; *f; f++) {
1753
1754                 if (*f == '/') {
1755                         slash = true;
1756                         continue;
1757                 }
1758
1759                 if (slash) {
1760                         slash = false;
1761                         *(t++) = '/';
1762                 }
1763
1764                 *(t++) = *f;
1765         }
1766
1767         /* Special rule, if we are talking of the root directory, a
1768         trailing slash is good */
1769
1770         if (t == path && slash)
1771                 *(t++) = '/';
1772
1773         *t = 0;
1774         return path;
1775 }
1776
1777 bool path_startswith(const char *path, const char *prefix) {
1778         assert(path);
1779         assert(prefix);
1780
1781         if ((path[0] == '/') != (prefix[0] == '/'))
1782                 return false;
1783
1784         for (;;) {
1785                 size_t a, b;
1786
1787                 path += strspn(path, "/");
1788                 prefix += strspn(prefix, "/");
1789
1790                 if (*prefix == 0)
1791                         return true;
1792
1793                 if (*path == 0)
1794                         return false;
1795
1796                 a = strcspn(path, "/");
1797                 b = strcspn(prefix, "/");
1798
1799                 if (a != b)
1800                         return false;
1801
1802                 if (memcmp(path, prefix, a) != 0)
1803                         return false;
1804
1805                 path += a;
1806                 prefix += b;
1807         }
1808 }
1809
1810 bool path_equal(const char *a, const char *b) {
1811         assert(a);
1812         assert(b);
1813
1814         if ((a[0] == '/') != (b[0] == '/'))
1815                 return false;
1816
1817         for (;;) {
1818                 size_t j, k;
1819
1820                 a += strspn(a, "/");
1821                 b += strspn(b, "/");
1822
1823                 if (*a == 0 && *b == 0)
1824                         return true;
1825
1826                 if (*a == 0 || *b == 0)
1827                         return false;
1828
1829                 j = strcspn(a, "/");
1830                 k = strcspn(b, "/");
1831
1832                 if (j != k)
1833                         return false;
1834
1835                 if (memcmp(a, b, j) != 0)
1836                         return false;
1837
1838                 a += j;
1839                 b += k;
1840         }
1841 }
1842
1843 char *ascii_strlower(char *t) {
1844         char *p;
1845
1846         assert(t);
1847
1848         for (p = t; *p; p++)
1849                 if (*p >= 'A' && *p <= 'Z')
1850                         *p = *p - 'A' + 'a';
1851
1852         return t;
1853 }
1854
1855 bool ignore_file(const char *filename) {
1856         assert(filename);
1857
1858         return
1859                 filename[0] == '.' ||
1860                 streq(filename, "lost+found") ||
1861                 streq(filename, "aquota.user") ||
1862                 streq(filename, "aquota.group") ||
1863                 endswith(filename, "~") ||
1864                 endswith(filename, ".rpmnew") ||
1865                 endswith(filename, ".rpmsave") ||
1866                 endswith(filename, ".rpmorig") ||
1867                 endswith(filename, ".dpkg-old") ||
1868                 endswith(filename, ".dpkg-new") ||
1869                 endswith(filename, ".swp");
1870 }
1871
1872 int fd_nonblock(int fd, bool nonblock) {
1873         int flags;
1874
1875         assert(fd >= 0);
1876
1877         if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1878                 return -errno;
1879
1880         if (nonblock)
1881                 flags |= O_NONBLOCK;
1882         else
1883                 flags &= ~O_NONBLOCK;
1884
1885         if (fcntl(fd, F_SETFL, flags) < 0)
1886                 return -errno;
1887
1888         return 0;
1889 }
1890
1891 int fd_cloexec(int fd, bool cloexec) {
1892         int flags;
1893
1894         assert(fd >= 0);
1895
1896         if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1897                 return -errno;
1898
1899         if (cloexec)
1900                 flags |= FD_CLOEXEC;
1901         else
1902                 flags &= ~FD_CLOEXEC;
1903
1904         if (fcntl(fd, F_SETFD, flags) < 0)
1905                 return -errno;
1906
1907         return 0;
1908 }
1909
1910 int close_all_fds(const int except[], unsigned n_except) {
1911         DIR *d;
1912         struct dirent *de;
1913         int r = 0;
1914
1915         if (!(d = opendir("/proc/self/fd")))
1916                 return -errno;
1917
1918         while ((de = readdir(d))) {
1919                 int fd = -1;
1920
1921                 if (ignore_file(de->d_name))
1922                         continue;
1923
1924                 if (safe_atoi(de->d_name, &fd) < 0)
1925                         /* Let's better ignore this, just in case */
1926                         continue;
1927
1928                 if (fd < 3)
1929                         continue;
1930
1931                 if (fd == dirfd(d))
1932                         continue;
1933
1934                 if (except) {
1935                         bool found;
1936                         unsigned i;
1937
1938                         found = false;
1939                         for (i = 0; i < n_except; i++)
1940                                 if (except[i] == fd) {
1941                                         found = true;
1942                                         break;
1943                                 }
1944
1945                         if (found)
1946                                 continue;
1947                 }
1948
1949                 if (close_nointr(fd) < 0) {
1950                         /* Valgrind has its own FD and doesn't want to have it closed */
1951                         if (errno != EBADF && r == 0)
1952                                 r = -errno;
1953                 }
1954         }
1955
1956         closedir(d);
1957         return r;
1958 }
1959
1960 bool chars_intersect(const char *a, const char *b) {
1961         const char *p;
1962
1963         /* Returns true if any of the chars in a are in b. */
1964         for (p = a; *p; p++)
1965                 if (strchr(b, *p))
1966                         return true;
1967
1968         return false;
1969 }
1970
1971 char *format_timestamp(char *buf, size_t l, usec_t t) {
1972         struct tm tm;
1973         time_t sec;
1974
1975         assert(buf);
1976         assert(l > 0);
1977
1978         if (t <= 0)
1979                 return NULL;
1980
1981         sec = (time_t) (t / USEC_PER_SEC);
1982
1983         if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0)
1984                 return NULL;
1985
1986         return buf;
1987 }
1988
1989 char *format_timestamp_pretty(char *buf, size_t l, usec_t t) {
1990         usec_t n, d;
1991
1992         n = now(CLOCK_REALTIME);
1993
1994         if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
1995                 return NULL;
1996
1997         d = n - t;
1998
1999         if (d >= USEC_PER_YEAR)
2000                 snprintf(buf, l, "%llu years and %llu months ago",
2001                          (unsigned long long) (d / USEC_PER_YEAR),
2002                          (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
2003         else if (d >= USEC_PER_MONTH)
2004                 snprintf(buf, l, "%llu months and %llu days ago",
2005                          (unsigned long long) (d / USEC_PER_MONTH),
2006                          (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
2007         else if (d >= USEC_PER_WEEK)
2008                 snprintf(buf, l, "%llu weeks and %llu days ago",
2009                          (unsigned long long) (d / USEC_PER_WEEK),
2010                          (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
2011         else if (d >= 2*USEC_PER_DAY)
2012                 snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
2013         else if (d >= 25*USEC_PER_HOUR)
2014                 snprintf(buf, l, "1 day and %lluh ago",
2015                          (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
2016         else if (d >= 6*USEC_PER_HOUR)
2017                 snprintf(buf, l, "%lluh ago",
2018                          (unsigned long long) (d / USEC_PER_HOUR));
2019         else if (d >= USEC_PER_HOUR)
2020                 snprintf(buf, l, "%lluh %llumin ago",
2021                          (unsigned long long) (d / USEC_PER_HOUR),
2022                          (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
2023         else if (d >= 5*USEC_PER_MINUTE)
2024                 snprintf(buf, l, "%llumin ago",
2025                          (unsigned long long) (d / USEC_PER_MINUTE));
2026         else if (d >= USEC_PER_MINUTE)
2027                 snprintf(buf, l, "%llumin %llus ago",
2028                          (unsigned long long) (d / USEC_PER_MINUTE),
2029                          (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
2030         else if (d >= USEC_PER_SEC)
2031                 snprintf(buf, l, "%llus ago",
2032                          (unsigned long long) (d / USEC_PER_SEC));
2033         else if (d >= USEC_PER_MSEC)
2034                 snprintf(buf, l, "%llums ago",
2035                          (unsigned long long) (d / USEC_PER_MSEC));
2036         else if (d > 0)
2037                 snprintf(buf, l, "%lluus ago",
2038                          (unsigned long long) d);
2039         else
2040                 snprintf(buf, l, "now");
2041
2042         buf[l-1] = 0;
2043         return buf;
2044 }
2045
2046 char *format_timespan(char *buf, size_t l, usec_t t) {
2047         static const struct {
2048                 const char *suffix;
2049                 usec_t usec;
2050         } table[] = {
2051                 { "w", USEC_PER_WEEK },
2052                 { "d", USEC_PER_DAY },
2053                 { "h", USEC_PER_HOUR },
2054                 { "min", USEC_PER_MINUTE },
2055                 { "s", USEC_PER_SEC },
2056                 { "ms", USEC_PER_MSEC },
2057                 { "us", 1 },
2058         };
2059
2060         unsigned i;
2061         char *p = buf;
2062
2063         assert(buf);
2064         assert(l > 0);
2065
2066         if (t == (usec_t) -1)
2067                 return NULL;
2068
2069         if (t == 0) {
2070                 snprintf(p, l, "0");
2071                 p[l-1] = 0;
2072                 return p;
2073         }
2074
2075         /* The result of this function can be parsed with parse_usec */
2076
2077         for (i = 0; i < ELEMENTSOF(table); i++) {
2078                 int k;
2079                 size_t n;
2080
2081                 if (t < table[i].usec)
2082                         continue;
2083
2084                 if (l <= 1)
2085                         break;
2086
2087                 k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix);
2088                 n = MIN((size_t) k, l);
2089
2090                 l -= n;
2091                 p += n;
2092
2093                 t %= table[i].usec;
2094         }
2095
2096         *p = 0;
2097
2098         return buf;
2099 }
2100
2101 bool fstype_is_network(const char *fstype) {
2102         static const char * const table[] = {
2103                 "cifs",
2104                 "smbfs",
2105                 "ncpfs",
2106                 "nfs",
2107                 "nfs4",
2108                 "gfs",
2109                 "gfs2"
2110         };
2111
2112         unsigned i;
2113
2114         for (i = 0; i < ELEMENTSOF(table); i++)
2115                 if (streq(table[i], fstype))
2116                         return true;
2117
2118         return false;
2119 }
2120
2121 int chvt(int vt) {
2122         int fd, r = 0;
2123
2124         if ((fd = open("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
2125                 return -errno;
2126
2127         if (vt < 0) {
2128                 int tiocl[2] = {
2129                         TIOCL_GETKMSGREDIRECT,
2130                         0
2131                 };
2132
2133                 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
2134                         return -errno;
2135
2136                 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
2137         }
2138
2139         if (ioctl(fd, VT_ACTIVATE, vt) < 0)
2140                 r = -errno;
2141
2142         close_nointr_nofail(r);
2143         return r;
2144 }
2145
2146 int read_one_char(FILE *f, char *ret, bool *need_nl) {
2147         struct termios old_termios, new_termios;
2148         char c;
2149         char line[LINE_MAX];
2150
2151         assert(f);
2152         assert(ret);
2153
2154         if (tcgetattr(fileno(f), &old_termios) >= 0) {
2155                 new_termios = old_termios;
2156
2157                 new_termios.c_lflag &= ~ICANON;
2158                 new_termios.c_cc[VMIN] = 1;
2159                 new_termios.c_cc[VTIME] = 0;
2160
2161                 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
2162                         size_t k;
2163
2164                         k = fread(&c, 1, 1, f);
2165
2166                         tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2167
2168                         if (k <= 0)
2169                                 return -EIO;
2170
2171                         if (need_nl)
2172                                 *need_nl = c != '\n';
2173
2174                         *ret = c;
2175                         return 0;
2176                 }
2177         }
2178
2179         if (!(fgets(line, sizeof(line), f)))
2180                 return -EIO;
2181
2182         truncate_nl(line);
2183
2184         if (strlen(line) != 1)
2185                 return -EBADMSG;
2186
2187         if (need_nl)
2188                 *need_nl = false;
2189
2190         *ret = line[0];
2191         return 0;
2192 }
2193
2194 int ask(char *ret, const char *replies, const char *text, ...) {
2195         bool on_tty;
2196
2197         assert(ret);
2198         assert(replies);
2199         assert(text);
2200
2201         on_tty = isatty(STDOUT_FILENO);
2202
2203         for (;;) {
2204                 va_list ap;
2205                 char c;
2206                 int r;
2207                 bool need_nl = true;
2208
2209                 if (on_tty)
2210                         fputs("\x1B[1m", stdout);
2211
2212                 va_start(ap, text);
2213                 vprintf(text, ap);
2214                 va_end(ap);
2215
2216                 if (on_tty)
2217                         fputs("\x1B[0m", stdout);
2218
2219                 fflush(stdout);
2220
2221                 if ((r = read_one_char(stdin, &c, &need_nl)) < 0) {
2222
2223                         if (r == -EBADMSG) {
2224                                 puts("Bad input, please try again.");
2225                                 continue;
2226                         }
2227
2228                         putchar('\n');
2229                         return r;
2230                 }
2231
2232                 if (need_nl)
2233                         putchar('\n');
2234
2235                 if (strchr(replies, c)) {
2236                         *ret = c;
2237                         return 0;
2238                 }
2239
2240                 puts("Read unexpected character, please try again.");
2241         }
2242 }
2243
2244 int reset_terminal(int fd) {
2245         struct termios termios;
2246         int r = 0;
2247         long arg;
2248
2249         /* Set terminal to some sane defaults */
2250
2251         assert(fd >= 0);
2252
2253         /* We leave locked terminal attributes untouched, so that
2254          * Plymouth may set whatever it wants to set, and we don't
2255          * interfere with that. */
2256
2257         /* Disable exclusive mode, just in case */
2258         ioctl(fd, TIOCNXCL);
2259
2260         /* Enable console unicode mode */
2261         arg = K_UNICODE;
2262         ioctl(fd, KDSKBMODE, &arg);
2263
2264         if (tcgetattr(fd, &termios) < 0) {
2265                 r = -errno;
2266                 goto finish;
2267         }
2268
2269         /* We only reset the stuff that matters to the software. How
2270          * hardware is set up we don't touch assuming that somebody
2271          * else will do that for us */
2272
2273         termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2274         termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2275         termios.c_oflag |= ONLCR;
2276         termios.c_cflag |= CREAD;
2277         termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2278
2279         termios.c_cc[VINTR]    =   03;  /* ^C */
2280         termios.c_cc[VQUIT]    =  034;  /* ^\ */
2281         termios.c_cc[VERASE]   = 0177;
2282         termios.c_cc[VKILL]    =  025;  /* ^X */
2283         termios.c_cc[VEOF]     =   04;  /* ^D */
2284         termios.c_cc[VSTART]   =  021;  /* ^Q */
2285         termios.c_cc[VSTOP]    =  023;  /* ^S */
2286         termios.c_cc[VSUSP]    =  032;  /* ^Z */
2287         termios.c_cc[VLNEXT]   =  026;  /* ^V */
2288         termios.c_cc[VWERASE]  =  027;  /* ^W */
2289         termios.c_cc[VREPRINT] =  022;  /* ^R */
2290         termios.c_cc[VEOL]     =    0;
2291         termios.c_cc[VEOL2]    =    0;
2292
2293         termios.c_cc[VTIME]  = 0;
2294         termios.c_cc[VMIN]   = 1;
2295
2296         if (tcsetattr(fd, TCSANOW, &termios) < 0)
2297                 r = -errno;
2298
2299 finish:
2300         /* Just in case, flush all crap out */
2301         tcflush(fd, TCIOFLUSH);
2302
2303         return r;
2304 }
2305
2306 int open_terminal(const char *name, int mode) {
2307         int fd, r;
2308         unsigned c = 0;
2309
2310         /*
2311          * If a TTY is in the process of being closed opening it might
2312          * cause EIO. This is horribly awful, but unlikely to be
2313          * changed in the kernel. Hence we work around this problem by
2314          * retrying a couple of times.
2315          *
2316          * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2317          */
2318
2319         for (;;) {
2320                 if ((fd = open(name, mode)) >= 0)
2321                         break;
2322
2323                 if (errno != EIO)
2324                         return -errno;
2325
2326                 if (c >= 20)
2327                         return -errno;
2328
2329                 usleep(50 * USEC_PER_MSEC);
2330                 c++;
2331         }
2332
2333         if (fd < 0)
2334                 return -errno;
2335
2336         if ((r = isatty(fd)) < 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(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm) {
2389         int fd = -1, notify = -1, r, wd = -1;
2390
2391         assert(name);
2392
2393         /* We use inotify to be notified when the tty is closed. We
2394          * create the watch before checking if we can actually acquire
2395          * it, so that we don't lose any event.
2396          *
2397          * Note: strictly speaking this actually watches for the
2398          * device being closed, it does *not* really watch whether a
2399          * tty loses its controlling process. However, unless some
2400          * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2401          * its tty otherwise this will not become a problem. As long
2402          * as the administrator makes sure not configure any service
2403          * on the same tty as an untrusted user this should not be a
2404          * problem. (Which he probably should not do anyway.) */
2405
2406         if (!fail && !force) {
2407                 if ((notify = inotify_init1(IN_CLOEXEC)) < 0) {
2408                         r = -errno;
2409                         goto fail;
2410                 }
2411
2412                 if ((wd = inotify_add_watch(notify, name, IN_CLOSE)) < 0) {
2413                         r = -errno;
2414                         goto fail;
2415                 }
2416         }
2417
2418         for (;;) {
2419                 if (notify >= 0)
2420                         if ((r = flush_fd(notify)) < 0)
2421                                 goto fail;
2422
2423                 /* We pass here O_NOCTTY only so that we can check the return
2424                  * value TIOCSCTTY and have a reliable way to figure out if we
2425                  * successfully became the controlling process of the tty */
2426                 if ((fd = open_terminal(name, O_RDWR|O_NOCTTY)) < 0)
2427                         return -errno;
2428
2429                 /* First, try to get the tty */
2430                 r = ioctl(fd, TIOCSCTTY, force);
2431
2432                 /* Sometimes it makes sense to ignore TIOCSCTTY
2433                  * returning EPERM, i.e. when very likely we already
2434                  * are have this controlling terminal. */
2435                 if (r < 0 && errno == EPERM && ignore_tiocstty_eperm)
2436                         r = 0;
2437
2438                 if (r < 0 && (force || fail || errno != EPERM)) {
2439                         r = -errno;
2440                         goto fail;
2441                 }
2442
2443                 if (r >= 0)
2444                         break;
2445
2446                 assert(!fail);
2447                 assert(!force);
2448                 assert(notify >= 0);
2449
2450                 for (;;) {
2451                         uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2452                         ssize_t l;
2453                         struct inotify_event *e;
2454
2455                         if ((l = read(notify, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
2456
2457                                 if (errno == EINTR)
2458                                         continue;
2459
2460                                 r = -errno;
2461                                 goto fail;
2462                         }
2463
2464                         e = (struct inotify_event*) inotify_buffer;
2465
2466                         while (l > 0) {
2467                                 size_t step;
2468
2469                                 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2470                                         r = -EIO;
2471                                         goto fail;
2472                                 }
2473
2474                                 step = sizeof(struct inotify_event) + e->len;
2475                                 assert(step <= (size_t) l);
2476
2477                                 e = (struct inotify_event*) ((uint8_t*) e + step);
2478                                 l -= step;
2479                         }
2480
2481                         break;
2482                 }
2483
2484                 /* We close the tty fd here since if the old session
2485                  * ended our handle will be dead. It's important that
2486                  * we do this after sleeping, so that we don't enter
2487                  * an endless loop. */
2488                 close_nointr_nofail(fd);
2489         }
2490
2491         if (notify >= 0)
2492                 close_nointr_nofail(notify);
2493
2494         if ((r = reset_terminal(fd)) < 0)
2495                 log_warning("Failed to reset terminal: %s", strerror(-r));
2496
2497         return fd;
2498
2499 fail:
2500         if (fd >= 0)
2501                 close_nointr_nofail(fd);
2502
2503         if (notify >= 0)
2504                 close_nointr_nofail(notify);
2505
2506         return r;
2507 }
2508
2509 int release_terminal(void) {
2510         int r = 0, fd;
2511         struct sigaction sa_old, sa_new;
2512
2513         if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY)) < 0)
2514                 return -errno;
2515
2516         /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2517          * by our own TIOCNOTTY */
2518
2519         zero(sa_new);
2520         sa_new.sa_handler = SIG_IGN;
2521         sa_new.sa_flags = SA_RESTART;
2522         assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2523
2524         if (ioctl(fd, TIOCNOTTY) < 0)
2525                 r = -errno;
2526
2527         assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2528
2529         close_nointr_nofail(fd);
2530         return r;
2531 }
2532
2533 int sigaction_many(const struct sigaction *sa, ...) {
2534         va_list ap;
2535         int r = 0, sig;
2536
2537         va_start(ap, sa);
2538         while ((sig = va_arg(ap, int)) > 0)
2539                 if (sigaction(sig, sa, NULL) < 0)
2540                         r = -errno;
2541         va_end(ap);
2542
2543         return r;
2544 }
2545
2546 int ignore_signals(int sig, ...) {
2547         struct sigaction sa;
2548         va_list ap;
2549         int r = 0;
2550
2551         zero(sa);
2552         sa.sa_handler = SIG_IGN;
2553         sa.sa_flags = SA_RESTART;
2554
2555         if (sigaction(sig, &sa, NULL) < 0)
2556                 r = -errno;
2557
2558         va_start(ap, sig);
2559         while ((sig = va_arg(ap, int)) > 0)
2560                 if (sigaction(sig, &sa, NULL) < 0)
2561                         r = -errno;
2562         va_end(ap);
2563
2564         return r;
2565 }
2566
2567 int default_signals(int sig, ...) {
2568         struct sigaction sa;
2569         va_list ap;
2570         int r = 0;
2571
2572         zero(sa);
2573         sa.sa_handler = SIG_DFL;
2574         sa.sa_flags = SA_RESTART;
2575
2576         if (sigaction(sig, &sa, NULL) < 0)
2577                 r = -errno;
2578
2579         va_start(ap, sig);
2580         while ((sig = va_arg(ap, int)) > 0)
2581                 if (sigaction(sig, &sa, NULL) < 0)
2582                         r = -errno;
2583         va_end(ap);
2584
2585         return r;
2586 }
2587
2588 int close_pipe(int p[]) {
2589         int a = 0, b = 0;
2590
2591         assert(p);
2592
2593         if (p[0] >= 0) {
2594                 a = close_nointr(p[0]);
2595                 p[0] = -1;
2596         }
2597
2598         if (p[1] >= 0) {
2599                 b = close_nointr(p[1]);
2600                 p[1] = -1;
2601         }
2602
2603         return a < 0 ? a : b;
2604 }
2605
2606 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2607         uint8_t *p;
2608         ssize_t n = 0;
2609
2610         assert(fd >= 0);
2611         assert(buf);
2612
2613         p = buf;
2614
2615         while (nbytes > 0) {
2616                 ssize_t k;
2617
2618                 if ((k = read(fd, p, nbytes)) <= 0) {
2619
2620                         if (k < 0 && errno == EINTR)
2621                                 continue;
2622
2623                         if (k < 0 && errno == EAGAIN && do_poll) {
2624                                 struct pollfd pollfd;
2625
2626                                 zero(pollfd);
2627                                 pollfd.fd = fd;
2628                                 pollfd.events = POLLIN;
2629
2630                                 if (poll(&pollfd, 1, -1) < 0) {
2631                                         if (errno == EINTR)
2632                                                 continue;
2633
2634                                         return n > 0 ? n : -errno;
2635                                 }
2636
2637                                 if (pollfd.revents != POLLIN)
2638                                         return n > 0 ? n : -EIO;
2639
2640                                 continue;
2641                         }
2642
2643                         return n > 0 ? n : (k < 0 ? -errno : 0);
2644                 }
2645
2646                 p += k;
2647                 nbytes -= k;
2648                 n += k;
2649         }
2650
2651         return n;
2652 }
2653
2654 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2655         const uint8_t *p;
2656         ssize_t n = 0;
2657
2658         assert(fd >= 0);
2659         assert(buf);
2660
2661         p = buf;
2662
2663         while (nbytes > 0) {
2664                 ssize_t k;
2665
2666                 if ((k = write(fd, p, nbytes)) <= 0) {
2667
2668                         if (k < 0 && errno == EINTR)
2669                                 continue;
2670
2671                         if (k < 0 && errno == EAGAIN && do_poll) {
2672                                 struct pollfd pollfd;
2673
2674                                 zero(pollfd);
2675                                 pollfd.fd = fd;
2676                                 pollfd.events = POLLOUT;
2677
2678                                 if (poll(&pollfd, 1, -1) < 0) {
2679                                         if (errno == EINTR)
2680                                                 continue;
2681
2682                                         return n > 0 ? n : -errno;
2683                                 }
2684
2685                                 if (pollfd.revents != POLLOUT)
2686                                         return n > 0 ? n : -EIO;
2687
2688                                 continue;
2689                         }
2690
2691                         return n > 0 ? n : (k < 0 ? -errno : 0);
2692                 }
2693
2694                 p += k;
2695                 nbytes -= k;
2696                 n += k;
2697         }
2698
2699         return n;
2700 }
2701
2702 int path_is_mount_point(const char *t) {
2703         struct stat a, b;
2704         char *parent;
2705         int r;
2706
2707         if (lstat(t, &a) < 0) {
2708                 if (errno == ENOENT)
2709                         return 0;
2710
2711                 return -errno;
2712         }
2713
2714         if ((r = parent_of_path(t, &parent)) < 0)
2715                 return r;
2716
2717         r = lstat(parent, &b);
2718         free(parent);
2719
2720         if (r < 0)
2721                 return -errno;
2722
2723         return a.st_dev != b.st_dev;
2724 }
2725
2726 int parse_usec(const char *t, usec_t *usec) {
2727         static const struct {
2728                 const char *suffix;
2729                 usec_t usec;
2730         } table[] = {
2731                 { "sec", USEC_PER_SEC },
2732                 { "s", USEC_PER_SEC },
2733                 { "min", USEC_PER_MINUTE },
2734                 { "hr", USEC_PER_HOUR },
2735                 { "h", USEC_PER_HOUR },
2736                 { "d", USEC_PER_DAY },
2737                 { "w", USEC_PER_WEEK },
2738                 { "msec", USEC_PER_MSEC },
2739                 { "ms", USEC_PER_MSEC },
2740                 { "m", USEC_PER_MINUTE },
2741                 { "usec", 1ULL },
2742                 { "us", 1ULL },
2743                 { "", USEC_PER_SEC },
2744         };
2745
2746         const char *p;
2747         usec_t r = 0;
2748
2749         assert(t);
2750         assert(usec);
2751
2752         p = t;
2753         do {
2754                 long long l;
2755                 char *e;
2756                 unsigned i;
2757
2758                 errno = 0;
2759                 l = strtoll(p, &e, 10);
2760
2761                 if (errno != 0)
2762                         return -errno;
2763
2764                 if (l < 0)
2765                         return -ERANGE;
2766
2767                 if (e == p)
2768                         return -EINVAL;
2769
2770                 e += strspn(e, WHITESPACE);
2771
2772                 for (i = 0; i < ELEMENTSOF(table); i++)
2773                         if (startswith(e, table[i].suffix)) {
2774                                 r += (usec_t) l * table[i].usec;
2775                                 p = e + strlen(table[i].suffix);
2776                                 break;
2777                         }
2778
2779                 if (i >= ELEMENTSOF(table))
2780                         return -EINVAL;
2781
2782         } while (*p != 0);
2783
2784         *usec = r;
2785
2786         return 0;
2787 }
2788
2789 int make_stdio(int fd) {
2790         int r, s, t;
2791
2792         assert(fd >= 0);
2793
2794         r = dup2(fd, STDIN_FILENO);
2795         s = dup2(fd, STDOUT_FILENO);
2796         t = dup2(fd, STDERR_FILENO);
2797
2798         if (fd >= 3)
2799                 close_nointr_nofail(fd);
2800
2801         if (r < 0 || s < 0 || t < 0)
2802                 return -errno;
2803
2804         return 0;
2805 }
2806
2807 int make_null_stdio(void) {
2808         int null_fd;
2809
2810         if ((null_fd = open("/dev/null", O_RDWR|O_NOCTTY)) < 0)
2811                 return -errno;
2812
2813         return make_stdio(null_fd);
2814 }
2815
2816 bool is_device_path(const char *path) {
2817
2818         /* Returns true on paths that refer to a device, either in
2819          * sysfs or in /dev */
2820
2821         return
2822                 path_startswith(path, "/dev/") ||
2823                 path_startswith(path, "/sys/");
2824 }
2825
2826 int dir_is_empty(const char *path) {
2827         DIR *d;
2828         int r;
2829         struct dirent buf, *de;
2830
2831         if (!(d = opendir(path)))
2832                 return -errno;
2833
2834         for (;;) {
2835                 if ((r = readdir_r(d, &buf, &de)) > 0) {
2836                         r = -r;
2837                         break;
2838                 }
2839
2840                 if (!de) {
2841                         r = 1;
2842                         break;
2843                 }
2844
2845                 if (!ignore_file(de->d_name)) {
2846                         r = 0;
2847                         break;
2848                 }
2849         }
2850
2851         closedir(d);
2852         return r;
2853 }
2854
2855 unsigned long long random_ull(void) {
2856         int fd;
2857         uint64_t ull;
2858         ssize_t r;
2859
2860         if ((fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0)
2861                 goto fallback;
2862
2863         r = loop_read(fd, &ull, sizeof(ull), true);
2864         close_nointr_nofail(fd);
2865
2866         if (r != sizeof(ull))
2867                 goto fallback;
2868
2869         return ull;
2870
2871 fallback:
2872         return random() * RAND_MAX + random();
2873 }
2874
2875 void rename_process(const char name[8]) {
2876         assert(name);
2877
2878         prctl(PR_SET_NAME, name);
2879
2880         /* This is a like a poor man's setproctitle(). The string
2881          * passed should fit in 7 chars (i.e. the length of
2882          * "systemd") */
2883
2884         if (program_invocation_name)
2885                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2886 }
2887
2888 void sigset_add_many(sigset_t *ss, ...) {
2889         va_list ap;
2890         int sig;
2891
2892         assert(ss);
2893
2894         va_start(ap, ss);
2895         while ((sig = va_arg(ap, int)) > 0)
2896                 assert_se(sigaddset(ss, sig) == 0);
2897         va_end(ap);
2898 }
2899
2900 char* gethostname_malloc(void) {
2901         struct utsname u;
2902
2903         assert_se(uname(&u) >= 0);
2904
2905         if (u.nodename[0])
2906                 return strdup(u.nodename);
2907
2908         return strdup(u.sysname);
2909 }
2910
2911 char* getlogname_malloc(void) {
2912         uid_t uid;
2913         long bufsize;
2914         char *buf, *name;
2915         struct passwd pwbuf, *pw = NULL;
2916         struct stat st;
2917
2918         if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2919                 uid = st.st_uid;
2920         else
2921                 uid = getuid();
2922
2923         /* Shortcut things to avoid NSS lookups */
2924         if (uid == 0)
2925                 return strdup("root");
2926
2927         if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) <= 0)
2928                 bufsize = 4096;
2929
2930         if (!(buf = malloc(bufsize)))
2931                 return NULL;
2932
2933         if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw) {
2934                 name = strdup(pw->pw_name);
2935                 free(buf);
2936                 return name;
2937         }
2938
2939         free(buf);
2940
2941         if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
2942                 return NULL;
2943
2944         return name;
2945 }
2946
2947 int getttyname_malloc(int fd, char **r) {
2948         char path[PATH_MAX], *c;
2949         int k;
2950
2951         assert(r);
2952
2953         if ((k = ttyname_r(fd, path, sizeof(path))) != 0)
2954                 return -k;
2955
2956         char_array_0(path);
2957
2958         if (!(c = strdup(startswith(path, "/dev/") ? path + 5 : path)))
2959                 return -ENOMEM;
2960
2961         *r = c;
2962         return 0;
2963 }
2964
2965 int getttyname_harder(int fd, char **r) {
2966         int k;
2967         char *s;
2968
2969         if ((k = getttyname_malloc(fd, &s)) < 0)
2970                 return k;
2971
2972         if (streq(s, "tty")) {
2973                 free(s);
2974                 return get_ctty(r, NULL);
2975         }
2976
2977         *r = s;
2978         return 0;
2979 }
2980
2981 int get_ctty_devnr(dev_t *d) {
2982         int k;
2983         char line[LINE_MAX], *p;
2984         unsigned long ttynr;
2985         FILE *f;
2986
2987         if (!(f = fopen("/proc/self/stat", "r")))
2988                 return -errno;
2989
2990         if (!(fgets(line, sizeof(line), f))) {
2991                 k = -errno;
2992                 fclose(f);
2993                 return k;
2994         }
2995
2996         fclose(f);
2997
2998         if (!(p = strrchr(line, ')')))
2999                 return -EIO;
3000
3001         p++;
3002
3003         if (sscanf(p, " "
3004                    "%*c "  /* state */
3005                    "%*d "  /* ppid */
3006                    "%*d "  /* pgrp */
3007                    "%*d "  /* session */
3008                    "%lu ", /* ttynr */
3009                    &ttynr) != 1)
3010                 return -EIO;
3011
3012         *d = (dev_t) ttynr;
3013         return 0;
3014 }
3015
3016 int get_ctty(char **r, dev_t *_devnr) {
3017         int k;
3018         char fn[PATH_MAX], *s, *b, *p;
3019         dev_t devnr;
3020
3021         assert(r);
3022
3023         if ((k = get_ctty_devnr(&devnr)) < 0)
3024                 return k;
3025
3026         snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
3027         char_array_0(fn);
3028
3029         if ((k = readlink_malloc(fn, &s)) < 0) {
3030
3031                 if (k != -ENOENT)
3032                         return k;
3033
3034                 /* This is an ugly hack */
3035                 if (major(devnr) == 136) {
3036                         if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
3037                                 return -ENOMEM;
3038
3039                         *r = b;
3040                         if (_devnr)
3041                                 *_devnr = devnr;
3042
3043                         return 0;
3044                 }
3045
3046                 /* Probably something like the ptys which have no
3047                  * symlink in /dev/char. Let's return something
3048                  * vaguely useful. */
3049
3050                 if (!(b = strdup(fn + 5)))
3051                         return -ENOMEM;
3052
3053                 *r = b;
3054                 if (_devnr)
3055                         *_devnr = devnr;
3056
3057                 return 0;
3058         }
3059
3060         if (startswith(s, "/dev/"))
3061                 p = s + 5;
3062         else if (startswith(s, "../"))
3063                 p = s + 3;
3064         else
3065                 p = s;
3066
3067         b = strdup(p);
3068         free(s);
3069
3070         if (!b)
3071                 return -ENOMEM;
3072
3073         *r = b;
3074         if (_devnr)
3075                 *_devnr = devnr;
3076
3077         return 0;
3078 }
3079
3080 static int rm_rf_children(int fd, bool only_dirs) {
3081         DIR *d;
3082         int ret = 0;
3083
3084         assert(fd >= 0);
3085
3086         /* This returns the first error we run into, but nevertheless
3087          * tries to go on */
3088
3089         if (!(d = fdopendir(fd))) {
3090                 close_nointr_nofail(fd);
3091
3092                 return errno == ENOENT ? 0 : -errno;
3093         }
3094
3095         for (;;) {
3096                 struct dirent buf, *de;
3097                 bool is_dir;
3098                 int r;
3099
3100                 if ((r = readdir_r(d, &buf, &de)) != 0) {
3101                         if (ret == 0)
3102                                 ret = -r;
3103                         break;
3104                 }
3105
3106                 if (!de)
3107                         break;
3108
3109                 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
3110                         continue;
3111
3112                 if (de->d_type == DT_UNKNOWN) {
3113                         struct stat st;
3114
3115                         if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
3116                                 if (ret == 0 && errno != ENOENT)
3117                                         ret = -errno;
3118                                 continue;
3119                         }
3120
3121                         is_dir = S_ISDIR(st.st_mode);
3122                 } else
3123                         is_dir = de->d_type == DT_DIR;
3124
3125                 if (is_dir) {
3126                         int subdir_fd;
3127
3128                         if ((subdir_fd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)) < 0) {
3129                                 if (ret == 0 && errno != ENOENT)
3130                                         ret = -errno;
3131                                 continue;
3132                         }
3133
3134                         if ((r = rm_rf_children(subdir_fd, only_dirs)) < 0) {
3135                                 if (ret == 0)
3136                                         ret = r;
3137                         }
3138
3139                         if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3140                                 if (ret == 0 && errno != ENOENT)
3141                                         ret = -errno;
3142                         }
3143                 } else  if (!only_dirs) {
3144
3145                         if (unlinkat(fd, de->d_name, 0) < 0) {
3146                                 if (ret == 0 && errno != ENOENT)
3147                                         ret = -errno;
3148                         }
3149                 }
3150         }
3151
3152         closedir(d);
3153
3154         return ret;
3155 }
3156
3157 int rm_rf(const char *path, bool only_dirs, bool delete_root) {
3158         int fd;
3159         int r;
3160
3161         assert(path);
3162
3163         if ((fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)) < 0) {
3164
3165                 if (errno != ENOTDIR)
3166                         return -errno;
3167
3168                 if (delete_root && !only_dirs)
3169                         if (unlink(path) < 0)
3170                                 return -errno;
3171
3172                 return 0;
3173         }
3174
3175         r = rm_rf_children(fd, only_dirs);
3176
3177         if (delete_root)
3178                 if (rmdir(path) < 0) {
3179                         if (r == 0)
3180                                 r = -errno;
3181                 }
3182
3183         return r;
3184 }
3185
3186 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3187         assert(path);
3188
3189         /* Under the assumption that we are running privileged we
3190          * first change the access mode and only then hand out
3191          * ownership to avoid a window where access is too open. */
3192
3193         if (chmod(path, mode) < 0)
3194                 return -errno;
3195
3196         if (chown(path, uid, gid) < 0)
3197                 return -errno;
3198
3199         return 0;
3200 }
3201
3202 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3203         cpu_set_t *r;
3204         unsigned n = 1024;
3205
3206         /* Allocates the cpuset in the right size */
3207
3208         for (;;) {
3209                 if (!(r = CPU_ALLOC(n)))
3210                         return NULL;
3211
3212                 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3213                         CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3214
3215                         if (ncpus)
3216                                 *ncpus = n;
3217
3218                         return r;
3219                 }
3220
3221                 CPU_FREE(r);
3222
3223                 if (errno != EINVAL)
3224                         return NULL;
3225
3226                 n *= 2;
3227         }
3228 }
3229
3230 void status_vprintf(const char *format, va_list ap) {
3231         char *s = NULL;
3232         int fd = -1;
3233
3234         assert(format);
3235
3236         /* This independent of logging, as status messages are
3237          * optional and go exclusively to the console. */
3238
3239         if (vasprintf(&s, format, ap) < 0)
3240                 goto finish;
3241
3242         if ((fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0)
3243                 goto finish;
3244
3245         write(fd, s, strlen(s));
3246
3247 finish:
3248         free(s);
3249
3250         if (fd >= 0)
3251                 close_nointr_nofail(fd);
3252 }
3253
3254 void status_printf(const char *format, ...) {
3255         va_list ap;
3256
3257         assert(format);
3258
3259         va_start(ap, format);
3260         status_vprintf(format, ap);
3261         va_end(ap);
3262 }
3263
3264 void status_welcome(void) {
3265         char *pretty_name = NULL, *ansi_color = NULL;
3266         const char *const_pretty = NULL, *const_color = NULL;
3267         int r;
3268
3269         if ((r = parse_env_file("/etc/os-release", NEWLINE,
3270                                 "PRETTY_NAME", &pretty_name,
3271                                 "ANSI_COLOR", &ansi_color,
3272                                 NULL)) < 0) {
3273
3274                 if (r != -ENOENT)
3275                         log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3276         }
3277
3278 #if defined(TARGET_FEDORA)
3279         if (!pretty_name) {
3280                 if ((r = read_one_line_file("/etc/system-release", &pretty_name)) < 0) {
3281
3282                         if (r != -ENOENT)
3283                                 log_warning("Failed to read /etc/system-release: %s", strerror(-r));
3284                 }
3285         }
3286
3287         if (!ansi_color && pretty_name) {
3288
3289                 /* This tries to mimic the color magic the old Red Hat sysinit
3290                  * script did. */
3291
3292                 if (startswith(pretty_name, "Red Hat"))
3293                         const_color = "0;31"; /* Red for RHEL */
3294                 else if (startswith(pretty_name, "Fedora"))
3295                         const_color = "0;34"; /* Blue for Fedora */
3296         }
3297
3298 #elif defined(TARGET_SUSE)
3299
3300         if (!pretty_name) {
3301                 if ((r = read_one_line_file("/etc/SuSE-release", &pretty_name)) < 0) {
3302
3303                         if (r != -ENOENT)
3304                                 log_warning("Failed to read /etc/SuSE-release: %s", strerror(-r));
3305                 }
3306         }
3307
3308         if (!ansi_color)
3309                 const_color = "0;32"; /* Green for openSUSE */
3310
3311 #elif defined(TARGET_GENTOO)
3312
3313         if (!pretty_name) {
3314                 if ((r = read_one_line_file("/etc/gentoo-release", &pretty_name)) < 0) {
3315
3316                         if (r != -ENOENT)
3317                                 log_warning("Failed to read /etc/gentoo-release: %s", strerror(-r));
3318                 }
3319         }
3320
3321         if (!ansi_color)
3322                 const_color = "1;34"; /* Light Blue for Gentoo */
3323
3324 #elif defined(TARGET_ALTLINUX)
3325
3326         if (!pretty_name) {
3327                 if ((r = read_one_line_file("/etc/altlinux-release", &pretty_name)) < 0) {
3328
3329                         if (r != -ENOENT)
3330                                 log_warning("Failed to read /etc/altlinux-release: %s", strerror(-r));
3331                 }
3332         }
3333
3334         if (!ansi_color)
3335                 const_color = "0;36"; /* Cyan for ALTLinux */
3336
3337
3338 #elif defined(TARGET_DEBIAN)
3339
3340         if (!pretty_name) {
3341                 char *version;
3342
3343                 if ((r = read_one_line_file("/etc/debian_version", &version)) < 0) {
3344
3345                         if (r != -ENOENT)
3346                                 log_warning("Failed to read /etc/debian_version: %s", strerror(-r));
3347                 } else {
3348                         pretty_name = strappend("Debian ", version);
3349                         free(version);
3350
3351                         if (!pretty_name)
3352                                 log_warning("Failed to allocate Debian version string.");
3353                 }
3354         }
3355
3356         if (!ansi_color)
3357                 const_color = "1;31"; /* Light Red for Debian */
3358
3359 #elif defined(TARGET_UBUNTU)
3360
3361         if ((r = parse_env_file("/etc/lsb-release", NEWLINE,
3362                                 "DISTRIB_DESCRIPTION", &pretty_name,
3363                                 NULL)) < 0) {
3364
3365                 if (r != -ENOENT)
3366                         log_warning("Failed to read /etc/lsb-release: %s", strerror(-r));
3367         }
3368
3369         if (!ansi_color)
3370                 const_color = "0;33"; /* Orange/Brown for Ubuntu */
3371
3372 #elif defined(TARGET_MANDRIVA)
3373
3374         if (!pretty_name) {
3375                 char *s, *p;
3376
3377                 if ((r = read_one_line_file("/etc/mandriva-release", &s) < 0)) {
3378                         if (r != -ENOENT)
3379                                 log_warning("Failed to read /etc/mandriva-release: %s", strerror(-r));
3380                 } else {
3381                         p = strstr(s, " release ");
3382                         if (p) {
3383                                 *p = '\0';
3384                                 p += 9;
3385                                 p[strcspn(p, " ")] = '\0';
3386
3387                                 /* This corresponds to standard rc.sysinit */
3388                                 if (asprintf(&pretty_name, "%s\x1B[0;39m %s", s, p) > 0)
3389                                         const_color = "1;36";
3390                                 else
3391                                         log_warning("Failed to allocate Mandriva version string.");
3392                         } else
3393                                 log_warning("Failed to parse /etc/mandriva-release");
3394                         free(s);
3395                 }
3396         }
3397
3398 #endif
3399
3400         if (!pretty_name && !const_pretty)
3401                 const_pretty = "Linux";
3402
3403         if (!ansi_color && !const_color)
3404                 const_color = "1";
3405
3406         status_printf("\nWelcome to \x1B[%sm%s\x1B[0m!\n\n",
3407                       const_color ? const_color : ansi_color,
3408                       const_pretty ? const_pretty : pretty_name);
3409
3410         free(ansi_color);
3411         free(pretty_name);
3412 }
3413
3414 char *replace_env(const char *format, char **env) {
3415         enum {
3416                 WORD,
3417                 CURLY,
3418                 VARIABLE
3419         } state = WORD;
3420
3421         const char *e, *word = format;
3422         char *r = NULL, *k;
3423
3424         assert(format);
3425
3426         for (e = format; *e; e ++) {
3427
3428                 switch (state) {
3429
3430                 case WORD:
3431                         if (*e == '$')
3432                                 state = CURLY;
3433                         break;
3434
3435                 case CURLY:
3436                         if (*e == '{') {
3437                                 if (!(k = strnappend(r, word, e-word-1)))
3438                                         goto fail;
3439
3440                                 free(r);
3441                                 r = k;
3442
3443                                 word = e-1;
3444                                 state = VARIABLE;
3445
3446                         } else if (*e == '$') {
3447                                 if (!(k = strnappend(r, word, e-word)))
3448                                         goto fail;
3449
3450                                 free(r);
3451                                 r = k;
3452
3453                                 word = e+1;
3454                                 state = WORD;
3455                         } else
3456                                 state = WORD;
3457                         break;
3458
3459                 case VARIABLE:
3460                         if (*e == '}') {
3461                                 const char *t;
3462
3463                                 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3464                                         t = "";
3465
3466                                 if (!(k = strappend(r, t)))
3467                                         goto fail;
3468
3469                                 free(r);
3470                                 r = k;
3471
3472                                 word = e+1;
3473                                 state = WORD;
3474                         }
3475                         break;
3476                 }
3477         }
3478
3479         if (!(k = strnappend(r, word, e-word)))
3480                 goto fail;
3481
3482         free(r);
3483         return k;
3484
3485 fail:
3486         free(r);
3487         return NULL;
3488 }
3489
3490 char **replace_env_argv(char **argv, char **env) {
3491         char **r, **i;
3492         unsigned k = 0, l = 0;
3493
3494         l = strv_length(argv);
3495
3496         if (!(r = new(char*, l+1)))
3497                 return NULL;
3498
3499         STRV_FOREACH(i, argv) {
3500
3501                 /* If $FOO appears as single word, replace it by the split up variable */
3502                 if ((*i)[0] == '$' && (*i)[1] != '{') {
3503                         char *e;
3504                         char **w, **m;
3505                         unsigned q;
3506
3507                         if ((e = strv_env_get(env, *i+1))) {
3508
3509                                 if (!(m = strv_split_quoted(e))) {
3510                                         r[k] = NULL;
3511                                         strv_free(r);
3512                                         return NULL;
3513                                 }
3514                         } else
3515                                 m = NULL;
3516
3517                         q = strv_length(m);
3518                         l = l + q - 1;
3519
3520                         if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3521                                 r[k] = NULL;
3522                                 strv_free(r);
3523                                 strv_free(m);
3524                                 return NULL;
3525                         }
3526
3527                         r = w;
3528                         if (m) {
3529                                 memcpy(r + k, m, q * sizeof(char*));
3530                                 free(m);
3531                         }
3532
3533                         k += q;
3534                         continue;
3535                 }
3536
3537                 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3538                 if (!(r[k++] = replace_env(*i, env))) {
3539                         strv_free(r);
3540                         return NULL;
3541                 }
3542         }
3543
3544         r[k] = NULL;
3545         return r;
3546 }
3547
3548 int columns(void) {
3549         static __thread int parsed_columns = 0;
3550         const char *e;
3551
3552         if (parsed_columns > 0)
3553                 return parsed_columns;
3554
3555         if ((e = getenv("COLUMNS")))
3556                 parsed_columns = atoi(e);
3557
3558         if (parsed_columns <= 0) {
3559                 struct winsize ws;
3560                 zero(ws);
3561
3562                 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
3563                         parsed_columns = ws.ws_col;
3564         }
3565
3566         if (parsed_columns <= 0)
3567                 parsed_columns = 80;
3568
3569         return parsed_columns;
3570 }
3571
3572 int running_in_chroot(void) {
3573         struct stat a, b;
3574
3575         zero(a);
3576         zero(b);
3577
3578         /* Only works as root */
3579
3580         if (stat("/proc/1/root", &a) < 0)
3581                 return -errno;
3582
3583         if (stat("/", &b) < 0)
3584                 return -errno;
3585
3586         return
3587                 a.st_dev != b.st_dev ||
3588                 a.st_ino != b.st_ino;
3589 }
3590
3591 char *ellipsize(const char *s, unsigned length, unsigned percent) {
3592         size_t l, x;
3593         char *r;
3594
3595         assert(s);
3596         assert(percent <= 100);
3597         assert(length >= 3);
3598
3599         l = strlen(s);
3600
3601         if (l <= 3 || l <= length)
3602                 return strdup(s);
3603
3604         if (!(r = new0(char, length+1)))
3605                 return r;
3606
3607         x = (length * percent) / 100;
3608
3609         if (x > length - 3)
3610                 x = length - 3;
3611
3612         memcpy(r, s, x);
3613         r[x] = '.';
3614         r[x+1] = '.';
3615         r[x+2] = '.';
3616         memcpy(r + x + 3,
3617                s + l - (length - x - 3),
3618                length - x - 3);
3619
3620         return r;
3621 }
3622
3623 int touch(const char *path) {
3624         int fd;
3625
3626         assert(path);
3627
3628         if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644)) < 0)
3629                 return -errno;
3630
3631         close_nointr_nofail(fd);
3632         return 0;
3633 }
3634
3635 char *unquote(const char *s, const char* quotes) {
3636         size_t l;
3637         assert(s);
3638
3639         if ((l = strlen(s)) < 2)
3640                 return strdup(s);
3641
3642         if (strchr(quotes, s[0]) && s[l-1] == s[0])
3643                 return strndup(s+1, l-2);
3644
3645         return strdup(s);
3646 }
3647
3648 char *normalize_env_assignment(const char *s) {
3649         char *name, *value, *p, *r;
3650
3651         p = strchr(s, '=');
3652
3653         if (!p) {
3654                 if (!(r = strdup(s)))
3655                         return NULL;
3656
3657                 return strstrip(r);
3658         }
3659
3660         if (!(name = strndup(s, p - s)))
3661                 return NULL;
3662
3663         if (!(p = strdup(p+1))) {
3664                 free(name);
3665                 return NULL;
3666         }
3667
3668         value = unquote(strstrip(p), QUOTES);
3669         free(p);
3670
3671         if (!value) {
3672                 free(name);
3673                 return NULL;
3674         }
3675
3676         if (asprintf(&r, "%s=%s", name, value) < 0)
3677                 r = NULL;
3678
3679         free(value);
3680         free(name);
3681
3682         return r;
3683 }
3684
3685 int wait_for_terminate(pid_t pid, siginfo_t *status) {
3686         assert(pid >= 1);
3687         assert(status);
3688
3689         for (;;) {
3690                 zero(*status);
3691
3692                 if (waitid(P_PID, pid, status, WEXITED) < 0) {
3693
3694                         if (errno == EINTR)
3695                                 continue;
3696
3697                         return -errno;
3698                 }
3699
3700                 return 0;
3701         }
3702 }
3703
3704 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
3705         int r;
3706         siginfo_t status;
3707
3708         assert(name);
3709         assert(pid > 1);
3710
3711         if ((r = wait_for_terminate(pid, &status)) < 0) {
3712                 log_warning("Failed to wait for %s: %s", name, strerror(-r));
3713                 return r;
3714         }
3715
3716         if (status.si_code == CLD_EXITED) {
3717                 if (status.si_status != 0) {
3718                         log_warning("%s failed with error code %i.", name, status.si_status);
3719                         return status.si_status;
3720                 }
3721
3722                 log_debug("%s succeeded.", name);
3723                 return 0;
3724
3725         } else if (status.si_code == CLD_KILLED ||
3726                    status.si_code == CLD_DUMPED) {
3727
3728                 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3729                 return -EPROTO;
3730         }
3731
3732         log_warning("%s failed due to unknown reason.", name);
3733         return -EPROTO;
3734
3735 }
3736
3737 void freeze(void) {
3738
3739         /* Make sure nobody waits for us on a socket anymore */
3740         close_all_fds(NULL, 0);
3741
3742         sync();
3743
3744         for (;;)
3745                 pause();
3746 }
3747
3748 bool null_or_empty(struct stat *st) {
3749         assert(st);
3750
3751         if (S_ISREG(st->st_mode) && st->st_size <= 0)
3752                 return true;
3753
3754         if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
3755                 return true;
3756
3757         return false;
3758 }
3759
3760 DIR *xopendirat(int fd, const char *name, int flags) {
3761         int nfd;
3762         DIR *d;
3763
3764         if ((nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags)) < 0)
3765                 return NULL;
3766
3767         if (!(d = fdopendir(nfd))) {
3768                 close_nointr_nofail(nfd);
3769                 return NULL;
3770         }
3771
3772         return d;
3773 }
3774
3775 int signal_from_string_try_harder(const char *s) {
3776         int signo;
3777         assert(s);
3778
3779         if ((signo = signal_from_string(s)) <= 0)
3780                 if (startswith(s, "SIG"))
3781                         return signal_from_string(s+3);
3782
3783         return signo;
3784 }
3785
3786 void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
3787
3788         assert(f);
3789         assert(name);
3790         assert(t);
3791
3792         if (!dual_timestamp_is_set(t))
3793                 return;
3794
3795         fprintf(f, "%s=%llu %llu\n",
3796                 name,
3797                 (unsigned long long) t->realtime,
3798                 (unsigned long long) t->monotonic);
3799 }
3800
3801 void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
3802         unsigned long long a, b;
3803
3804         assert(value);
3805         assert(t);
3806
3807         if (sscanf(value, "%lli %llu", &a, &b) != 2)
3808                 log_debug("Failed to parse finish timestamp value %s", value);
3809         else {
3810                 t->realtime = a;
3811                 t->monotonic = b;
3812         }
3813 }
3814
3815 char *fstab_node_to_udev_node(const char *p) {
3816         char *dn, *t, *u;
3817         int r;
3818
3819         /* FIXME: to follow udev's logic 100% we need to leave valid
3820          * UTF8 chars unescaped */
3821
3822         if (startswith(p, "LABEL=")) {
3823
3824                 if (!(u = unquote(p+6, "\"\'")))
3825                         return NULL;
3826
3827                 t = xescape(u, "/ ");
3828                 free(u);
3829
3830                 if (!t)
3831                         return NULL;
3832
3833                 r = asprintf(&dn, "/dev/disk/by-label/%s", t);
3834                 free(t);
3835
3836                 if (r < 0)
3837                         return NULL;
3838
3839                 return dn;
3840         }
3841
3842         if (startswith(p, "UUID=")) {
3843
3844                 if (!(u = unquote(p+5, "\"\'")))
3845                         return NULL;
3846
3847                 t = xescape(u, "/ ");
3848                 free(u);
3849
3850                 if (!t)
3851                         return NULL;
3852
3853                 r = asprintf(&dn, "/dev/disk/by-uuid/%s", t);
3854                 free(t);
3855
3856                 if (r < 0)
3857                         return NULL;
3858
3859                 return dn;
3860         }
3861
3862         return strdup(p);
3863 }
3864
3865 void filter_environ(const char *prefix) {
3866         int i, j;
3867         assert(prefix);
3868
3869         if (!environ)
3870                 return;
3871
3872         for (i = 0, j = 0; environ[i]; i++) {
3873
3874                 if (startswith(environ[i], prefix))
3875                         continue;
3876
3877                 environ[j++] = environ[i];
3878         }
3879
3880         environ[j] = NULL;
3881 }
3882
3883 bool tty_is_vc(const char *tty) {
3884         assert(tty);
3885
3886         if (startswith(tty, "/dev/"))
3887                 tty += 5;
3888
3889         return startswith(tty, "tty") &&
3890                 tty[3] >= '0' && tty[3] <= '9';
3891 }
3892
3893 const char *default_term_for_tty(const char *tty) {
3894         char *active = NULL;
3895         const char *term;
3896
3897         assert(tty);
3898
3899         if (startswith(tty, "/dev/"))
3900                 tty += 5;
3901
3902         /* Resolve where /dev/console is pointing when determining
3903          * TERM */
3904         if (streq(tty, "console"))
3905                 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
3906                         /* If multiple log outputs are configured the
3907                          * last one is what /dev/console points to */
3908                         if ((tty = strrchr(active, ' ')))
3909                                 tty++;
3910                         else
3911                                 tty = active;
3912                 }
3913
3914         term = tty_is_vc(tty) ? "TERM=linux" : "TERM=vt100";
3915         free(active);
3916
3917         return term;
3918 }
3919
3920 /* Returns a short identifier for the various VM implementations */
3921 int detect_vm(const char **id) {
3922
3923 #if defined(__i386__) || defined(__x86_64__)
3924
3925         /* Both CPUID and DMI are x86 specific interfaces... */
3926
3927         static const char *const dmi_vendors[] = {
3928                 "/sys/class/dmi/id/sys_vendor",
3929                 "/sys/class/dmi/id/board_vendor",
3930                 "/sys/class/dmi/id/bios_vendor"
3931         };
3932
3933         static const char dmi_vendor_table[] =
3934                 "QEMU\0"                  "qemu\0"
3935                 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3936                 "VMware\0"                "vmware\0"
3937                 "VMW\0"                   "vmware\0"
3938                 "Microsoft Corporation\0" "microsoft\0"
3939                 "innotek GmbH\0"          "oracle\0"
3940                 "Xen\0"                   "xen\0"
3941                 "Bochs\0"                 "bochs\0";
3942
3943         static const char cpuid_vendor_table[] =
3944                 "XenVMMXenVMM\0"          "xen\0"
3945                 "KVMKVMKVM\0"             "kvm\0"
3946                 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
3947                 "VMwareVMware\0"          "vmware\0"
3948                 /* http://msdn.microsoft.com/en-us/library/ff542428.aspx */
3949                 "Microsoft Hv\0"          "microsoft\0";
3950
3951         uint32_t eax, ecx;
3952         union {
3953                 uint32_t sig32[3];
3954                 char text[13];
3955         } sig;
3956         unsigned i;
3957         const char *j, *k;
3958         bool hypervisor;
3959
3960         /* http://lwn.net/Articles/301888/ */
3961         zero(sig);
3962
3963 #if defined (__i386__)
3964 #define REG_a "eax"
3965 #define REG_b "ebx"
3966 #elif defined (__amd64__)
3967 #define REG_a "rax"
3968 #define REG_b "rbx"
3969 #endif
3970
3971         /* First detect whether there is a hypervisor */
3972         eax = 1;
3973         __asm__ __volatile__ (
3974                 /* ebx/rbx is being used for PIC! */
3975                 "  push %%"REG_b"         \n\t"
3976                 "  cpuid                  \n\t"
3977                 "  pop %%"REG_b"          \n\t"
3978
3979                 : "=a" (eax), "=c" (ecx)
3980                 : "0" (eax)
3981         );
3982
3983         hypervisor = !!(ecx & ecx & 0x80000000U);
3984
3985         if (hypervisor) {
3986
3987                 /* There is a hypervisor, see what it is */
3988                 eax = 0x40000000U;
3989                 __asm__ __volatile__ (
3990                         /* ebx/rbx is being used for PIC! */
3991                         "  push %%"REG_b"         \n\t"
3992                         "  cpuid                  \n\t"
3993                         "  mov %%ebx, %1          \n\t"
3994                         "  pop %%"REG_b"          \n\t"
3995
3996                         : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2])
3997                         : "0" (eax)
3998                 );
3999
4000                 NULSTR_FOREACH_PAIR(j, k, cpuid_vendor_table)
4001                         if (streq(sig.text, j)) {
4002
4003                                 if (id)
4004                                         *id = k;
4005
4006                                 return 1;
4007                         }
4008         }
4009
4010         for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) {
4011                 char *s;
4012                 int r;
4013                 const char *found = NULL;
4014
4015                 if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) {
4016                         if (r != -ENOENT)
4017                                 return r;
4018
4019                         continue;
4020                 }
4021
4022                 NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table)
4023                         if (startswith(s, j))
4024                                 found = k;
4025                 free(s);
4026
4027                 if (found) {
4028                         if (id)
4029                                 *id = found;
4030
4031                         return 1;
4032                 }
4033         }
4034
4035         if (hypervisor) {
4036                 if (id)
4037                         *id = "other";
4038
4039                 return 1;
4040         }
4041
4042 #endif
4043         return 0;
4044 }
4045
4046 int detect_container(const char **id) {
4047         FILE *f;
4048
4049         /* Unfortunately many of these operations require root access
4050          * in one way or another */
4051
4052         if (geteuid() != 0)
4053                 return -EPERM;
4054
4055         if (running_in_chroot() > 0) {
4056
4057                 if (id)
4058                         *id = "chroot";
4059
4060                 return 1;
4061         }
4062
4063         /* /proc/vz exists in container and outside of the container,
4064          * /proc/bc only outside of the container. */
4065         if (access("/proc/vz", F_OK) >= 0 &&
4066             access("/proc/bc", F_OK) < 0) {
4067
4068                 if (id)
4069                         *id = "openvz";
4070
4071                 return 1;
4072         }
4073
4074         if ((f = fopen("/proc/self/cgroup", "r"))) {
4075
4076                 for (;;) {
4077                         char line[LINE_MAX], *p;
4078
4079                         if (!fgets(line, sizeof(line), f))
4080                                 break;
4081
4082                         if (!(p = strchr(strstrip(line), ':')))
4083                                 continue;
4084
4085                         if (strncmp(p, ":ns:", 4))
4086                                 continue;
4087
4088                         if (!streq(p, ":ns:/")) {
4089                                 fclose(f);
4090
4091                                 if (id)
4092                                         *id = "pidns";
4093
4094                                 return 1;
4095                         }
4096                 }
4097
4098                 fclose(f);
4099         }
4100
4101         return 0;
4102 }
4103
4104 /* Returns a short identifier for the various VM/container implementations */
4105 int detect_virtualization(const char **id) {
4106         static __thread const char *cached_id = NULL;
4107         const char *_id;
4108         int r;
4109
4110         if (cached_id) {
4111
4112                 if (cached_id == (const char*) -1)
4113                         return 0;
4114
4115                 if (id)
4116                         *id = cached_id;
4117
4118                 return 1;
4119         }
4120
4121         if ((r = detect_container(&_id)) != 0)
4122                 goto finish;
4123
4124         r = detect_vm(&_id);
4125
4126 finish:
4127         if (r > 0) {
4128                 cached_id = _id;
4129
4130                 if (id)
4131                         *id = _id;
4132         } else if (r == 0)
4133                 cached_id = (const char*) -1;
4134
4135         return r;
4136 }
4137
4138 void execute_directory(const char *directory, DIR *d, char *argv[]) {
4139         DIR *_d = NULL;
4140         struct dirent *de;
4141         Hashmap *pids = NULL;
4142
4143         assert(directory);
4144
4145         /* Executes all binaries in a directory in parallel and waits
4146          * until all they all finished. */
4147
4148         if (!d) {
4149                 if (!(_d = opendir(directory))) {
4150
4151                         if (errno == ENOENT)
4152                                 return;
4153
4154                         log_error("Failed to enumerate directory %s: %m", directory);
4155                         return;
4156                 }
4157
4158                 d = _d;
4159         }
4160
4161         if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
4162                 log_error("Failed to allocate set.");
4163                 goto finish;
4164         }
4165
4166         while ((de = readdir(d))) {
4167                 char *path;
4168                 pid_t pid;
4169                 int k;
4170
4171                 if (ignore_file(de->d_name))
4172                         continue;
4173
4174                 if (de->d_type != DT_REG &&
4175                     de->d_type != DT_LNK &&
4176                     de->d_type != DT_UNKNOWN)
4177                         continue;
4178
4179                 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
4180                         log_error("Out of memory");
4181                         continue;
4182                 }
4183
4184                 if ((pid = fork()) < 0) {
4185                         log_error("Failed to fork: %m");
4186                         free(path);
4187                         continue;
4188                 }
4189
4190                 if (pid == 0) {
4191                         char *_argv[2];
4192                         /* Child */
4193
4194                         if (!argv) {
4195                                 _argv[0] = path;
4196                                 _argv[1] = NULL;
4197                                 argv = _argv;
4198                         } else
4199                                 if (!argv[0])
4200                                         argv[0] = path;
4201
4202                         execv(path, argv);
4203
4204                         log_error("Failed to execute %s: %m", path);
4205                         _exit(EXIT_FAILURE);
4206                 }
4207
4208                 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
4209
4210                 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
4211                         log_error("Failed to add PID to set: %s", strerror(-k));
4212                         free(path);
4213                 }
4214         }
4215
4216         while (!hashmap_isempty(pids)) {
4217                 siginfo_t si;
4218                 char *path;
4219
4220                 zero(si);
4221                 if (waitid(P_ALL, 0, &si, WEXITED) < 0) {
4222
4223                         if (errno == EINTR)
4224                                 continue;
4225
4226                         log_error("waitid() failed: %m");
4227                         goto finish;
4228                 }
4229
4230                 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
4231                         if (!is_clean_exit(si.si_code, si.si_status)) {
4232                                 if (si.si_code == CLD_EXITED)
4233                                         log_error("%s exited with exit status %i.", path, si.si_status);
4234                                 else
4235                                         log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
4236                         } else
4237                                 log_debug("%s exited successfully.", path);
4238
4239                         free(path);
4240                 }
4241         }
4242
4243 finish:
4244         if (_d)
4245                 closedir(_d);
4246
4247         if (pids)
4248                 hashmap_free_free(pids);
4249 }
4250
4251 int kill_and_sigcont(pid_t pid, int sig) {
4252         int r;
4253
4254         r = kill(pid, sig) < 0 ? -errno : 0;
4255
4256         if (r >= 0)
4257                 kill(pid, SIGCONT);
4258
4259         return r;
4260 }
4261
4262 bool nulstr_contains(const char*nulstr, const char *needle) {
4263         const char *i;
4264
4265         if (!nulstr)
4266                 return false;
4267
4268         NULSTR_FOREACH(i, nulstr)
4269                 if (streq(i, needle))
4270                         return true;
4271
4272         return false;
4273 }
4274
4275 bool plymouth_running(void) {
4276         return access("/run/plymouth/pid", F_OK) >= 0;
4277 }
4278
4279 void parse_syslog_priority(char **p, int *priority) {
4280         int a = 0, b = 0, c = 0;
4281         int k;
4282
4283         assert(p);
4284         assert(*p);
4285         assert(priority);
4286
4287         if ((*p)[0] != '<')
4288                 return;
4289
4290         if (!strchr(*p, '>'))
4291                 return;
4292
4293         if ((*p)[2] == '>') {
4294                 c = undecchar((*p)[1]);
4295                 k = 3;
4296         } else if ((*p)[3] == '>') {
4297                 b = undecchar((*p)[1]);
4298                 c = undecchar((*p)[2]);
4299                 k = 4;
4300         } else if ((*p)[4] == '>') {
4301                 a = undecchar((*p)[1]);
4302                 b = undecchar((*p)[2]);
4303                 c = undecchar((*p)[3]);
4304                 k = 5;
4305         } else
4306                 return;
4307
4308         if (a < 0 || b < 0 || c < 0)
4309                 return;
4310
4311         *priority = a*100+b*10+c;
4312         *p += k;
4313 }
4314
4315 int have_effective_cap(int value) {
4316         cap_t cap;
4317         cap_flag_value_t fv;
4318         int r;
4319
4320         if (!(cap = cap_get_proc()))
4321                 return -errno;
4322
4323         if (cap_get_flag(cap, value, CAP_EFFECTIVE, &fv) < 0)
4324                 r = -errno;
4325         else
4326                 r = fv == CAP_SET;
4327
4328         cap_free(cap);
4329         return r;
4330 }
4331
4332 char* strshorten(char *s, size_t l) {
4333         assert(s);
4334
4335         if (l < strlen(s))
4336                 s[l] = 0;
4337
4338         return s;
4339 }
4340
4341 static bool hostname_valid_char(char c) {
4342         return
4343                 (c >= 'a' && c <= 'z') ||
4344                 (c >= 'A' && c <= 'Z') ||
4345                 (c >= '0' && c <= '9') ||
4346                 c == '-' ||
4347                 c == '_' ||
4348                 c == '.';
4349 }
4350
4351 bool hostname_is_valid(const char *s) {
4352         const char *p;
4353
4354         if (isempty(s))
4355                 return false;
4356
4357         for (p = s; *p; p++)
4358                 if (!hostname_valid_char(*p))
4359                         return false;
4360
4361         if (p-s > HOST_NAME_MAX)
4362                 return false;
4363
4364         return true;
4365 }
4366
4367 char* hostname_cleanup(char *s) {
4368         char *p, *d;
4369
4370         for (p = s, d = s; *p; p++)
4371                 if ((*p >= 'a' && *p <= 'z') ||
4372                     (*p >= 'A' && *p <= 'Z') ||
4373                     (*p >= '0' && *p <= '9') ||
4374                     *p == '-' ||
4375                     *p == '_' ||
4376                     *p == '.')
4377                         *(d++) = *p;
4378
4379         *d = 0;
4380
4381         strshorten(s, HOST_NAME_MAX);
4382         return s;
4383 }
4384
4385 static const char *const ioprio_class_table[] = {
4386         [IOPRIO_CLASS_NONE] = "none",
4387         [IOPRIO_CLASS_RT] = "realtime",
4388         [IOPRIO_CLASS_BE] = "best-effort",
4389         [IOPRIO_CLASS_IDLE] = "idle"
4390 };
4391
4392 DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
4393
4394 static const char *const sigchld_code_table[] = {
4395         [CLD_EXITED] = "exited",
4396         [CLD_KILLED] = "killed",
4397         [CLD_DUMPED] = "dumped",
4398         [CLD_TRAPPED] = "trapped",
4399         [CLD_STOPPED] = "stopped",
4400         [CLD_CONTINUED] = "continued",
4401 };
4402
4403 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
4404
4405 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
4406         [LOG_FAC(LOG_KERN)] = "kern",
4407         [LOG_FAC(LOG_USER)] = "user",
4408         [LOG_FAC(LOG_MAIL)] = "mail",
4409         [LOG_FAC(LOG_DAEMON)] = "daemon",
4410         [LOG_FAC(LOG_AUTH)] = "auth",
4411         [LOG_FAC(LOG_SYSLOG)] = "syslog",
4412         [LOG_FAC(LOG_LPR)] = "lpr",
4413         [LOG_FAC(LOG_NEWS)] = "news",
4414         [LOG_FAC(LOG_UUCP)] = "uucp",
4415         [LOG_FAC(LOG_CRON)] = "cron",
4416         [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
4417         [LOG_FAC(LOG_FTP)] = "ftp",
4418         [LOG_FAC(LOG_LOCAL0)] = "local0",
4419         [LOG_FAC(LOG_LOCAL1)] = "local1",
4420         [LOG_FAC(LOG_LOCAL2)] = "local2",
4421         [LOG_FAC(LOG_LOCAL3)] = "local3",
4422         [LOG_FAC(LOG_LOCAL4)] = "local4",
4423         [LOG_FAC(LOG_LOCAL5)] = "local5",
4424         [LOG_FAC(LOG_LOCAL6)] = "local6",
4425         [LOG_FAC(LOG_LOCAL7)] = "local7"
4426 };
4427
4428 DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int);
4429
4430 static const char *const log_level_table[] = {
4431         [LOG_EMERG] = "emerg",
4432         [LOG_ALERT] = "alert",
4433         [LOG_CRIT] = "crit",
4434         [LOG_ERR] = "err",
4435         [LOG_WARNING] = "warning",
4436         [LOG_NOTICE] = "notice",
4437         [LOG_INFO] = "info",
4438         [LOG_DEBUG] = "debug"
4439 };
4440
4441 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
4442
4443 static const char* const sched_policy_table[] = {
4444         [SCHED_OTHER] = "other",
4445         [SCHED_BATCH] = "batch",
4446         [SCHED_IDLE] = "idle",
4447         [SCHED_FIFO] = "fifo",
4448         [SCHED_RR] = "rr"
4449 };
4450
4451 DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
4452
4453 static const char* const rlimit_table[] = {
4454         [RLIMIT_CPU] = "LimitCPU",
4455         [RLIMIT_FSIZE] = "LimitFSIZE",
4456         [RLIMIT_DATA] = "LimitDATA",
4457         [RLIMIT_STACK] = "LimitSTACK",
4458         [RLIMIT_CORE] = "LimitCORE",
4459         [RLIMIT_RSS] = "LimitRSS",
4460         [RLIMIT_NOFILE] = "LimitNOFILE",
4461         [RLIMIT_AS] = "LimitAS",
4462         [RLIMIT_NPROC] = "LimitNPROC",
4463         [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
4464         [RLIMIT_LOCKS] = "LimitLOCKS",
4465         [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
4466         [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
4467         [RLIMIT_NICE] = "LimitNICE",
4468         [RLIMIT_RTPRIO] = "LimitRTPRIO",
4469         [RLIMIT_RTTIME] = "LimitRTTIME"
4470 };
4471
4472 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
4473
4474 static const char* const ip_tos_table[] = {
4475         [IPTOS_LOWDELAY] = "low-delay",
4476         [IPTOS_THROUGHPUT] = "throughput",
4477         [IPTOS_RELIABILITY] = "reliability",
4478         [IPTOS_LOWCOST] = "low-cost",
4479 };
4480
4481 DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);
4482
4483 static const char *const signal_table[] = {
4484         [SIGHUP] = "HUP",
4485         [SIGINT] = "INT",
4486         [SIGQUIT] = "QUIT",
4487         [SIGILL] = "ILL",
4488         [SIGTRAP] = "TRAP",
4489         [SIGABRT] = "ABRT",
4490         [SIGBUS] = "BUS",
4491         [SIGFPE] = "FPE",
4492         [SIGKILL] = "KILL",
4493         [SIGUSR1] = "USR1",
4494         [SIGSEGV] = "SEGV",
4495         [SIGUSR2] = "USR2",
4496         [SIGPIPE] = "PIPE",
4497         [SIGALRM] = "ALRM",
4498         [SIGTERM] = "TERM",
4499 #ifdef SIGSTKFLT
4500         [SIGSTKFLT] = "STKFLT",  /* Linux on SPARC doesn't know SIGSTKFLT */
4501 #endif
4502         [SIGCHLD] = "CHLD",
4503         [SIGCONT] = "CONT",
4504         [SIGSTOP] = "STOP",
4505         [SIGTSTP] = "TSTP",
4506         [SIGTTIN] = "TTIN",
4507         [SIGTTOU] = "TTOU",
4508         [SIGURG] = "URG",
4509         [SIGXCPU] = "XCPU",
4510         [SIGXFSZ] = "XFSZ",
4511         [SIGVTALRM] = "VTALRM",
4512         [SIGPROF] = "PROF",
4513         [SIGWINCH] = "WINCH",
4514         [SIGIO] = "IO",
4515         [SIGPWR] = "PWR",
4516         [SIGSYS] = "SYS"
4517 };
4518
4519 DEFINE_STRING_TABLE_LOOKUP(signal, int);