chiark / gitweb /
8556ea12cd153d6899f3b98a8cc803e80b61f401
[elogind.git] / util.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
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
46 #include "macro.h"
47 #include "util.h"
48 #include "ioprio.h"
49 #include "missing.h"
50 #include "log.h"
51 #include "strv.h"
52
53 bool streq_ptr(const char *a, const char *b) {
54
55         /* Like streq(), but tries to make sense of NULL pointers */
56
57         if (a && b)
58                 return streq(a, b);
59
60         if (!a && !b)
61                 return true;
62
63         return false;
64 }
65
66 usec_t now(clockid_t clock_id) {
67         struct timespec ts;
68
69         assert_se(clock_gettime(clock_id, &ts) == 0);
70
71         return timespec_load(&ts);
72 }
73
74 usec_t timespec_load(const struct timespec *ts) {
75         assert(ts);
76
77         return
78                 (usec_t) ts->tv_sec * USEC_PER_SEC +
79                 (usec_t) ts->tv_nsec / NSEC_PER_USEC;
80 }
81
82 struct timespec *timespec_store(struct timespec *ts, usec_t u)  {
83         assert(ts);
84
85         ts->tv_sec = (time_t) (u / USEC_PER_SEC);
86         ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
87
88         return ts;
89 }
90
91 usec_t timeval_load(const struct timeval *tv) {
92         assert(tv);
93
94         return
95                 (usec_t) tv->tv_sec * USEC_PER_SEC +
96                 (usec_t) tv->tv_usec;
97 }
98
99 struct timeval *timeval_store(struct timeval *tv, usec_t u) {
100         assert(tv);
101
102         tv->tv_sec = (time_t) (u / USEC_PER_SEC);
103         tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
104
105         return tv;
106 }
107
108 bool endswith(const char *s, const char *postfix) {
109         size_t sl, pl;
110
111         assert(s);
112         assert(postfix);
113
114         sl = strlen(s);
115         pl = strlen(postfix);
116
117         if (pl == 0)
118                 return true;
119
120         if (sl < pl)
121                 return false;
122
123         return memcmp(s + sl - pl, postfix, pl) == 0;
124 }
125
126 bool startswith(const char *s, const char *prefix) {
127         size_t sl, pl;
128
129         assert(s);
130         assert(prefix);
131
132         sl = strlen(s);
133         pl = strlen(prefix);
134
135         if (pl == 0)
136                 return true;
137
138         if (sl < pl)
139                 return false;
140
141         return memcmp(s, prefix, pl) == 0;
142 }
143
144 bool first_word(const char *s, const char *word) {
145         size_t sl, wl;
146
147         assert(s);
148         assert(word);
149
150         sl = strlen(s);
151         wl = strlen(word);
152
153         if (sl < wl)
154                 return false;
155
156         if (wl == 0)
157                 return true;
158
159         if (memcmp(s, word, wl) != 0)
160                 return false;
161
162         return s[wl] == 0 ||
163                 strchr(WHITESPACE, s[wl]);
164 }
165
166 int close_nointr(int fd) {
167         assert(fd >= 0);
168
169         for (;;) {
170                 int r;
171
172                 if ((r = close(fd)) >= 0)
173                         return r;
174
175                 if (errno != EINTR)
176                         return r;
177         }
178 }
179
180 void close_nointr_nofail(int fd) {
181         int saved_errno = errno;
182
183         /* like close_nointr() but cannot fail, and guarantees errno
184          * is unchanged */
185
186         assert_se(close_nointr(fd) == 0);
187
188         errno = saved_errno;
189 }
190
191 int parse_boolean(const char *v) {
192         assert(v);
193
194         if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
195                 return 1;
196         else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
197                 return 0;
198
199         return -EINVAL;
200 }
201
202 int safe_atou(const char *s, unsigned *ret_u) {
203         char *x = NULL;
204         unsigned long l;
205
206         assert(s);
207         assert(ret_u);
208
209         errno = 0;
210         l = strtoul(s, &x, 0);
211
212         if (!x || *x || errno)
213                 return errno ? -errno : -EINVAL;
214
215         if ((unsigned long) (unsigned) l != l)
216                 return -ERANGE;
217
218         *ret_u = (unsigned) l;
219         return 0;
220 }
221
222 int safe_atoi(const char *s, int *ret_i) {
223         char *x = NULL;
224         long l;
225
226         assert(s);
227         assert(ret_i);
228
229         errno = 0;
230         l = strtol(s, &x, 0);
231
232         if (!x || *x || errno)
233                 return errno ? -errno : -EINVAL;
234
235         if ((long) (int) l != l)
236                 return -ERANGE;
237
238         *ret_i = (int) l;
239         return 0;
240 }
241
242 int safe_atolu(const char *s, long unsigned *ret_lu) {
243         char *x = NULL;
244         unsigned long l;
245
246         assert(s);
247         assert(ret_lu);
248
249         errno = 0;
250         l = strtoul(s, &x, 0);
251
252         if (!x || *x || errno)
253                 return errno ? -errno : -EINVAL;
254
255         *ret_lu = l;
256         return 0;
257 }
258
259 int safe_atoli(const char *s, long int *ret_li) {
260         char *x = NULL;
261         long l;
262
263         assert(s);
264         assert(ret_li);
265
266         errno = 0;
267         l = strtol(s, &x, 0);
268
269         if (!x || *x || errno)
270                 return errno ? -errno : -EINVAL;
271
272         *ret_li = l;
273         return 0;
274 }
275
276 int safe_atollu(const char *s, long long unsigned *ret_llu) {
277         char *x = NULL;
278         unsigned long long l;
279
280         assert(s);
281         assert(ret_llu);
282
283         errno = 0;
284         l = strtoull(s, &x, 0);
285
286         if (!x || *x || errno)
287                 return errno ? -errno : -EINVAL;
288
289         *ret_llu = l;
290         return 0;
291 }
292
293 int safe_atolli(const char *s, long long int *ret_lli) {
294         char *x = NULL;
295         long long l;
296
297         assert(s);
298         assert(ret_lli);
299
300         errno = 0;
301         l = strtoll(s, &x, 0);
302
303         if (!x || *x || errno)
304                 return errno ? -errno : -EINVAL;
305
306         *ret_lli = l;
307         return 0;
308 }
309
310 /* Split a string into words. */
311 char *split(const char *c, size_t *l, const char *separator, char **state) {
312         char *current;
313
314         current = *state ? *state : (char*) c;
315
316         if (!*current || *c == 0)
317                 return NULL;
318
319         current += strspn(current, separator);
320         *l = strcspn(current, separator);
321         *state = current+*l;
322
323         return (char*) current;
324 }
325
326 /* Split a string into words, but consider strings enclosed in '' and
327  * "" as words even if they include spaces. */
328 char *split_quoted(const char *c, size_t *l, char **state) {
329         char *current;
330
331         current = *state ? *state : (char*) c;
332
333         if (!*current || *c == 0)
334                 return NULL;
335
336         current += strspn(current, WHITESPACE);
337
338         if (*current == '\'') {
339                 current ++;
340                 *l = strcspn(current, "'");
341                 *state = current+*l;
342
343                 if (**state == '\'')
344                         (*state)++;
345         } else if (*current == '\"') {
346                 current ++;
347                 *l = strcspn(current, "\"");
348                 *state = current+*l;
349
350                 if (**state == '\"')
351                         (*state)++;
352         } else {
353                 *l = strcspn(current, WHITESPACE);
354                 *state = current+*l;
355         }
356
357         /* FIXME: Cannot deal with strings that have spaces AND ticks
358          * in them */
359
360         return (char*) current;
361 }
362
363 char **split_path_and_make_absolute(const char *p) {
364         char **l;
365         assert(p);
366
367         if (!(l = strv_split(p, ":")))
368                 return NULL;
369
370         if (!strv_path_make_absolute_cwd(l)) {
371                 strv_free(l);
372                 return NULL;
373         }
374
375         return l;
376 }
377
378 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
379         int r;
380         FILE *f;
381         char fn[132], line[256], *p;
382         long long unsigned ppid;
383
384         assert(pid >= 0);
385         assert(_ppid);
386
387         assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%llu/stat", (unsigned long long) pid) < (int) (sizeof(fn)-1));
388         fn[sizeof(fn)-1] = 0;
389
390         if (!(f = fopen(fn, "r")))
391                 return -errno;
392
393         if (!(fgets(line, sizeof(line), f))) {
394                 r = -errno;
395                 fclose(f);
396                 return r;
397         }
398
399         fclose(f);
400
401         /* Let's skip the pid and comm fields. The latter is enclosed
402          * in () but does not escape any () in its value, so let's
403          * skip over it manually */
404
405         if (!(p = strrchr(line, ')')))
406                 return -EIO;
407
408         p++;
409
410         if (sscanf(p, " "
411                    "%*c "  /* state */
412                    "%llu ", /* ppid */
413                    &ppid) != 1)
414                 return -EIO;
415
416         if ((long long unsigned) (pid_t) ppid != ppid)
417                 return -ERANGE;
418
419         *_ppid = (pid_t) ppid;
420
421         return 0;
422 }
423
424 int write_one_line_file(const char *fn, const char *line) {
425         FILE *f;
426         int r;
427
428         assert(fn);
429         assert(line);
430
431         if (!(f = fopen(fn, "we")))
432                 return -errno;
433
434         if (fputs(line, f) < 0) {
435                 r = -errno;
436                 goto finish;
437         }
438
439         r = 0;
440 finish:
441         fclose(f);
442         return r;
443 }
444
445 int read_one_line_file(const char *fn, char **line) {
446         FILE *f;
447         int r;
448         char t[2048], *c;
449
450         assert(fn);
451         assert(line);
452
453         if (!(f = fopen(fn, "re")))
454                 return -errno;
455
456         if (!(fgets(t, sizeof(t), f))) {
457                 r = -errno;
458                 goto finish;
459         }
460
461         if (!(c = strdup(t))) {
462                 r = -ENOMEM;
463                 goto finish;
464         }
465
466         *line = c;
467         r = 0;
468
469 finish:
470         fclose(f);
471         return r;
472 }
473
474 char *truncate_nl(char *s) {
475         assert(s);
476
477         s[strcspn(s, NEWLINE)] = 0;
478         return s;
479 }
480
481 int get_process_name(pid_t pid, char **name) {
482         char *p;
483         int r;
484
485         assert(pid >= 1);
486         assert(name);
487
488         if (asprintf(&p, "/proc/%llu/comm", (unsigned long long) pid) < 0)
489                 return -ENOMEM;
490
491         r = read_one_line_file(p, name);
492         free(p);
493
494         if (r < 0)
495                 return r;
496
497         truncate_nl(*name);
498         return 0;
499 }
500
501 char *strappend(const char *s, const char *suffix) {
502         size_t a, b;
503         char *r;
504
505         assert(s);
506         assert(suffix);
507
508         a = strlen(s);
509         b = strlen(suffix);
510
511         if (!(r = new(char, a+b+1)))
512                 return NULL;
513
514         memcpy(r, s, a);
515         memcpy(r+a, suffix, b);
516         r[a+b] = 0;
517
518         return r;
519 }
520
521 int readlink_malloc(const char *p, char **r) {
522         size_t l = 100;
523
524         assert(p);
525         assert(r);
526
527         for (;;) {
528                 char *c;
529                 ssize_t n;
530
531                 if (!(c = new(char, l)))
532                         return -ENOMEM;
533
534                 if ((n = readlink(p, c, l-1)) < 0) {
535                         int ret = -errno;
536                         free(c);
537                         return ret;
538                 }
539
540                 if ((size_t) n < l-1) {
541                         c[n] = 0;
542                         *r = c;
543                         return 0;
544                 }
545
546                 free(c);
547                 l *= 2;
548         }
549 }
550
551 char *file_name_from_path(const char *p) {
552         char *r;
553
554         assert(p);
555
556         if ((r = strrchr(p, '/')))
557                 return r + 1;
558
559         return (char*) p;
560 }
561
562 bool path_is_absolute(const char *p) {
563         assert(p);
564
565         return p[0] == '/';
566 }
567
568 bool is_path(const char *p) {
569
570         return !!strchr(p, '/');
571 }
572
573 char *path_make_absolute(const char *p, const char *prefix) {
574         char *r;
575
576         assert(p);
577
578         /* Makes every item in the list an absolute path by prepending
579          * the prefix, if specified and necessary */
580
581         if (path_is_absolute(p) || !prefix)
582                 return strdup(p);
583
584         if (asprintf(&r, "%s/%s", prefix, p) < 0)
585                 return NULL;
586
587         return r;
588 }
589
590 char *path_make_absolute_cwd(const char *p) {
591         char *cwd, *r;
592
593         assert(p);
594
595         /* Similar to path_make_absolute(), but prefixes with the
596          * current working directory. */
597
598         if (path_is_absolute(p))
599                 return strdup(p);
600
601         if (!(cwd = get_current_dir_name()))
602                 return NULL;
603
604         r = path_make_absolute(p, cwd);
605         free(cwd);
606
607         return r;
608 }
609
610 char **strv_path_make_absolute_cwd(char **l) {
611         char **s;
612
613         /* Goes through every item in the string list and makes it
614          * absolute. This works in place and won't rollback any
615          * changes on failure. */
616
617         STRV_FOREACH(s, l) {
618                 char *t;
619
620                 if (!(t = path_make_absolute_cwd(*s)))
621                         return NULL;
622
623                 free(*s);
624                 *s = t;
625         }
626
627         return l;
628 }
629
630 int reset_all_signal_handlers(void) {
631         int sig;
632
633         for (sig = 1; sig < _NSIG; sig++) {
634                 struct sigaction sa;
635
636                 if (sig == SIGKILL || sig == SIGSTOP)
637                         continue;
638
639                 zero(sa);
640                 sa.sa_handler = SIG_DFL;
641                 sa.sa_flags = SA_RESTART;
642
643                 /* On Linux the first two RT signals are reserved by
644                  * glibc, and sigaction() will return EINVAL for them. */
645                 if ((sigaction(sig, &sa, NULL) < 0))
646                         if (errno != EINVAL)
647                                 return -errno;
648         }
649
650         return 0;
651 }
652
653 char *strstrip(char *s) {
654         char *e, *l = NULL;
655
656         /* Drops trailing whitespace. Modifies the string in
657          * place. Returns pointer to first non-space character */
658
659         s += strspn(s, WHITESPACE);
660
661         for (e = s; *e; e++)
662                 if (!strchr(WHITESPACE, *e))
663                         l = e;
664
665         if (l)
666                 *(l+1) = 0;
667         else
668                 *s = 0;
669
670         return s;
671 }
672
673 char *delete_chars(char *s, const char *bad) {
674         char *f, *t;
675
676         /* Drops all whitespace, regardless where in the string */
677
678         for (f = s, t = s; *f; f++) {
679                 if (strchr(bad, *f))
680                         continue;
681
682                 *(t++) = *f;
683         }
684
685         *t = 0;
686
687         return s;
688 }
689
690 char *file_in_same_dir(const char *path, const char *filename) {
691         char *e, *r;
692         size_t k;
693
694         assert(path);
695         assert(filename);
696
697         /* This removes the last component of path and appends
698          * filename, unless the latter is absolute anyway or the
699          * former isn't */
700
701         if (path_is_absolute(filename))
702                 return strdup(filename);
703
704         if (!(e = strrchr(path, '/')))
705                 return strdup(filename);
706
707         k = strlen(filename);
708         if (!(r = new(char, e-path+1+k+1)))
709                 return NULL;
710
711         memcpy(r, path, e-path+1);
712         memcpy(r+(e-path)+1, filename, k+1);
713
714         return r;
715 }
716
717 int mkdir_parents(const char *path, mode_t mode) {
718         const char *p, *e;
719
720         assert(path);
721
722         /* Creates every parent directory in the path except the last
723          * component. */
724
725         p = path + strspn(path, "/");
726         for (;;) {
727                 int r;
728                 char *t;
729
730                 e = p + strcspn(p, "/");
731                 p = e + strspn(e, "/");
732
733                 /* Is this the last component? If so, then we're
734                  * done */
735                 if (*p == 0)
736                         return 0;
737
738                 if (!(t = strndup(path, e - path)))
739                         return -ENOMEM;
740
741                 r = mkdir(t, mode);
742
743                 free(t);
744
745                 if (r < 0 && errno != EEXIST)
746                         return -errno;
747         }
748 }
749
750 int mkdir_p(const char *path, mode_t mode) {
751         int r;
752
753         /* Like mkdir -p */
754
755         if ((r = mkdir_parents(path, mode)) < 0)
756                 return r;
757
758         if (mkdir(path, mode) < 0)
759                 return -errno;
760
761         return 0;
762 }
763
764 char hexchar(int x) {
765         static const char table[16] = "0123456789abcdef";
766
767         return table[x & 15];
768 }
769
770 int unhexchar(char c) {
771
772         if (c >= '0' && c <= '9')
773                 return c - '0';
774
775         if (c >= 'a' && c <= 'f')
776                 return c - 'a' + 10;
777
778         if (c >= 'A' && c <= 'F')
779                 return c - 'A' + 10;
780
781         return -1;
782 }
783
784 char octchar(int x) {
785         return '0' + (x & 7);
786 }
787
788 int unoctchar(char c) {
789
790         if (c >= '0' && c <= '7')
791                 return c - '0';
792
793         return -1;
794 }
795
796 char decchar(int x) {
797         return '0' + (x % 10);
798 }
799
800 int undecchar(char c) {
801
802         if (c >= '0' && c <= '9')
803                 return c - '0';
804
805         return -1;
806 }
807
808 char *cescape(const char *s) {
809         char *r, *t;
810         const char *f;
811
812         assert(s);
813
814         /* Does C style string escaping. */
815
816         if (!(r = new(char, strlen(s)*4 + 1)))
817                 return NULL;
818
819         for (f = s, t = r; *f; f++)
820
821                 switch (*f) {
822
823                 case '\a':
824                         *(t++) = '\\';
825                         *(t++) = 'a';
826                         break;
827                 case '\b':
828                         *(t++) = '\\';
829                         *(t++) = 'b';
830                         break;
831                 case '\f':
832                         *(t++) = '\\';
833                         *(t++) = 'f';
834                         break;
835                 case '\n':
836                         *(t++) = '\\';
837                         *(t++) = 'n';
838                         break;
839                 case '\r':
840                         *(t++) = '\\';
841                         *(t++) = 'r';
842                         break;
843                 case '\t':
844                         *(t++) = '\\';
845                         *(t++) = 't';
846                         break;
847                 case '\v':
848                         *(t++) = '\\';
849                         *(t++) = 'v';
850                         break;
851                 case '\\':
852                         *(t++) = '\\';
853                         *(t++) = '\\';
854                         break;
855                 case '"':
856                         *(t++) = '\\';
857                         *(t++) = '"';
858                         break;
859                 case '\'':
860                         *(t++) = '\\';
861                         *(t++) = '\'';
862                         break;
863
864                 default:
865                         /* For special chars we prefer octal over
866                          * hexadecimal encoding, simply because glib's
867                          * g_strescape() does the same */
868                         if ((*f < ' ') || (*f >= 127)) {
869                                 *(t++) = '\\';
870                                 *(t++) = octchar((unsigned char) *f >> 6);
871                                 *(t++) = octchar((unsigned char) *f >> 3);
872                                 *(t++) = octchar((unsigned char) *f);
873                         } else
874                                 *(t++) = *f;
875                         break;
876                 }
877
878         *t = 0;
879
880         return r;
881 }
882
883 char *cunescape(const char *s) {
884         char *r, *t;
885         const char *f;
886
887         assert(s);
888
889         /* Undoes C style string escaping */
890
891         if (!(r = new(char, strlen(s)+1)))
892                 return r;
893
894         for (f = s, t = r; *f; f++) {
895
896                 if (*f != '\\') {
897                         *(t++) = *f;
898                         continue;
899                 }
900
901                 f++;
902
903                 switch (*f) {
904
905                 case 'a':
906                         *(t++) = '\a';
907                         break;
908                 case 'b':
909                         *(t++) = '\b';
910                         break;
911                 case 'f':
912                         *(t++) = '\f';
913                         break;
914                 case 'n':
915                         *(t++) = '\n';
916                         break;
917                 case 'r':
918                         *(t++) = '\r';
919                         break;
920                 case 't':
921                         *(t++) = '\t';
922                         break;
923                 case 'v':
924                         *(t++) = '\v';
925                         break;
926                 case '\\':
927                         *(t++) = '\\';
928                         break;
929                 case '"':
930                         *(t++) = '"';
931                         break;
932                 case '\'':
933                         *(t++) = '\'';
934                         break;
935
936                 case 'x': {
937                         /* hexadecimal encoding */
938                         int a, b;
939
940                         if ((a = unhexchar(f[1])) < 0 ||
941                             (b = unhexchar(f[2])) < 0) {
942                                 /* Invalid escape code, let's take it literal then */
943                                 *(t++) = '\\';
944                                 *(t++) = 'x';
945                         } else {
946                                 *(t++) = (char) ((a << 4) | b);
947                                 f += 2;
948                         }
949
950                         break;
951                 }
952
953                 case '0':
954                 case '1':
955                 case '2':
956                 case '3':
957                 case '4':
958                 case '5':
959                 case '6':
960                 case '7': {
961                         /* octal encoding */
962                         int a, b, c;
963
964                         if ((a = unoctchar(f[0])) < 0 ||
965                             (b = unoctchar(f[1])) < 0 ||
966                             (c = unoctchar(f[2])) < 0) {
967                                 /* Invalid escape code, let's take it literal then */
968                                 *(t++) = '\\';
969                                 *(t++) = f[0];
970                         } else {
971                                 *(t++) = (char) ((a << 6) | (b << 3) | c);
972                                 f += 2;
973                         }
974
975                         break;
976                 }
977
978                 case 0:
979                         /* premature end of string.*/
980                         *(t++) = '\\';
981                         goto finish;
982
983                 default:
984                         /* Invalid escape code, let's take it literal then */
985                         *(t++) = '\\';
986                         *(t++) = 'f';
987                         break;
988                 }
989         }
990
991 finish:
992         *t = 0;
993         return r;
994 }
995
996
997 char *xescape(const char *s, const char *bad) {
998         char *r, *t;
999         const char *f;
1000
1001         /* Escapes all chars in bad, in addition to \ and all special
1002          * chars, in \xFF style escaping. May be reversed with
1003          * cunescape. */
1004
1005         if (!(r = new(char, strlen(s)*4+1)))
1006                 return NULL;
1007
1008         for (f = s, t = r; *f; f++) {
1009
1010                 if ((*f < ' ') || (*f >= 127) ||
1011                     (*f == '\\') || strchr(bad, *f)) {
1012                         *(t++) = '\\';
1013                         *(t++) = 'x';
1014                         *(t++) = hexchar(*f >> 4);
1015                         *(t++) = hexchar(*f);
1016                 } else
1017                         *(t++) = *f;
1018         }
1019
1020         *t = 0;
1021
1022         return r;
1023 }
1024
1025 char *bus_path_escape(const char *s) {
1026         char *r, *t;
1027         const char *f;
1028
1029         assert(s);
1030
1031         /* Escapes all chars that D-Bus' object path cannot deal
1032          * with. Can be reverse with bus_path_unescape() */
1033
1034         if (!(r = new(char, strlen(s)*3+1)))
1035                 return NULL;
1036
1037         for (f = s, t = r; *f; f++) {
1038
1039                 if (!(*f >= 'A' && *f <= 'Z') &&
1040                     !(*f >= 'a' && *f <= 'z') &&
1041                     !(*f >= '0' && *f <= '9')) {
1042                         *(t++) = '_';
1043                         *(t++) = hexchar(*f >> 4);
1044                         *(t++) = hexchar(*f);
1045                 } else
1046                         *(t++) = *f;
1047         }
1048
1049         *t = 0;
1050
1051         return r;
1052 }
1053
1054 char *bus_path_unescape(const char *f) {
1055         char *r, *t;
1056
1057         assert(f);
1058
1059         if (!(r = strdup(f)))
1060                 return NULL;
1061
1062         for (t = r; *f; f++) {
1063
1064                 if (*f == '_') {
1065                         int a, b;
1066
1067                         if ((a = unhexchar(f[1])) < 0 ||
1068                             (b = unhexchar(f[2])) < 0) {
1069                                 /* Invalid escape code, let's take it literal then */
1070                                 *(t++) = '_';
1071                         } else {
1072                                 *(t++) = (char) ((a << 4) | b);
1073                                 f += 2;
1074                         }
1075                 } else
1076                         *(t++) = *f;
1077         }
1078
1079         *t = 0;
1080
1081         return r;
1082 }
1083
1084 char *path_kill_slashes(char *path) {
1085         char *f, *t;
1086         bool slash = false;
1087
1088         /* Removes redundant inner and trailing slashes. Modifies the
1089          * passed string in-place.
1090          *
1091          * ///foo///bar/ becomes /foo/bar
1092          */
1093
1094         for (f = path, t = path; *f; f++) {
1095
1096                 if (*f == '/') {
1097                         slash = true;
1098                         continue;
1099                 }
1100
1101                 if (slash) {
1102                         slash = false;
1103                         *(t++) = '/';
1104                 }
1105
1106                 *(t++) = *f;
1107         }
1108
1109         /* Special rule, if we are talking of the root directory, a
1110         trailing slash is good */
1111
1112         if (t == path && slash)
1113                 *(t++) = '/';
1114
1115         *t = 0;
1116         return path;
1117 }
1118
1119 bool path_startswith(const char *path, const char *prefix) {
1120         assert(path);
1121         assert(prefix);
1122
1123         if ((path[0] == '/') != (prefix[0] == '/'))
1124                 return false;
1125
1126         for (;;) {
1127                 size_t a, b;
1128
1129                 path += strspn(path, "/");
1130                 prefix += strspn(prefix, "/");
1131
1132                 if (*prefix == 0)
1133                         return true;
1134
1135                 if (*path == 0)
1136                         return false;
1137
1138                 a = strcspn(path, "/");
1139                 b = strcspn(prefix, "/");
1140
1141                 if (a != b)
1142                         return false;
1143
1144                 if (memcmp(path, prefix, a) != 0)
1145                         return false;
1146
1147                 path += a;
1148                 prefix += b;
1149         }
1150 }
1151
1152 bool path_equal(const char *a, const char *b) {
1153         assert(a);
1154         assert(b);
1155
1156         if ((a[0] == '/') != (b[0] == '/'))
1157                 return false;
1158
1159         for (;;) {
1160                 size_t j, k;
1161
1162                 a += strspn(a, "/");
1163                 b += strspn(b, "/");
1164
1165                 if (*a == 0 && *b == 0)
1166                         return true;
1167
1168                 if (*a == 0 || *b == 0)
1169                         return false;
1170
1171                 j = strcspn(a, "/");
1172                 k = strcspn(b, "/");
1173
1174                 if (j != k)
1175                         return false;
1176
1177                 if (memcmp(a, b, j) != 0)
1178                         return false;
1179
1180                 a += j;
1181                 b += k;
1182         }
1183 }
1184
1185 char *ascii_strlower(char *t) {
1186         char *p;
1187
1188         assert(t);
1189
1190         for (p = t; *p; p++)
1191                 if (*p >= 'A' && *p <= 'Z')
1192                         *p = *p - 'A' + 'a';
1193
1194         return t;
1195 }
1196
1197 bool ignore_file(const char *filename) {
1198         assert(filename);
1199
1200         return
1201                 filename[0] == '.' ||
1202                 endswith(filename, "~") ||
1203                 endswith(filename, ".rpmnew") ||
1204                 endswith(filename, ".rpmsave") ||
1205                 endswith(filename, ".rpmorig") ||
1206                 endswith(filename, ".dpkg-old") ||
1207                 endswith(filename, ".dpkg-new") ||
1208                 endswith(filename, ".swp");
1209 }
1210
1211 int fd_nonblock(int fd, bool nonblock) {
1212         int flags;
1213
1214         assert(fd >= 0);
1215
1216         if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1217                 return -errno;
1218
1219         if (nonblock)
1220                 flags |= O_NONBLOCK;
1221         else
1222                 flags &= ~O_NONBLOCK;
1223
1224         if (fcntl(fd, F_SETFL, flags) < 0)
1225                 return -errno;
1226
1227         return 0;
1228 }
1229
1230 int fd_cloexec(int fd, bool cloexec) {
1231         int flags;
1232
1233         assert(fd >= 0);
1234
1235         if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1236                 return -errno;
1237
1238         if (cloexec)
1239                 flags |= FD_CLOEXEC;
1240         else
1241                 flags &= ~FD_CLOEXEC;
1242
1243         if (fcntl(fd, F_SETFD, flags) < 0)
1244                 return -errno;
1245
1246         return 0;
1247 }
1248
1249 int close_all_fds(const int except[], unsigned n_except) {
1250         DIR *d;
1251         struct dirent *de;
1252         int r = 0;
1253
1254         if (!(d = opendir("/proc/self/fd")))
1255                 return -errno;
1256
1257         while ((de = readdir(d))) {
1258                 int fd = -1;
1259
1260                 if (ignore_file(de->d_name))
1261                         continue;
1262
1263                 if ((r = safe_atoi(de->d_name, &fd)) < 0)
1264                         goto finish;
1265
1266                 if (fd < 3)
1267                         continue;
1268
1269                 if (fd == dirfd(d))
1270                         continue;
1271
1272                 if (except) {
1273                         bool found;
1274                         unsigned i;
1275
1276                         found = false;
1277                         for (i = 0; i < n_except; i++)
1278                                 if (except[i] == fd) {
1279                                         found = true;
1280                                         break;
1281                                 }
1282
1283                         if (found)
1284                                 continue;
1285                 }
1286
1287                 if ((r = close_nointr(fd)) < 0) {
1288                         /* Valgrind has its own FD and doesn't want to have it closed */
1289                         if (errno != EBADF)
1290                                 goto finish;
1291                 }
1292         }
1293
1294         r = 0;
1295
1296 finish:
1297         closedir(d);
1298         return r;
1299 }
1300
1301 bool chars_intersect(const char *a, const char *b) {
1302         const char *p;
1303
1304         /* Returns true if any of the chars in a are in b. */
1305         for (p = a; *p; p++)
1306                 if (strchr(b, *p))
1307                         return true;
1308
1309         return false;
1310 }
1311
1312 char *format_timestamp(char *buf, size_t l, usec_t t) {
1313         struct tm tm;
1314         time_t sec;
1315
1316         assert(buf);
1317         assert(l > 0);
1318
1319         if (t <= 0)
1320                 return NULL;
1321
1322         sec = (time_t) t / USEC_PER_SEC;
1323
1324         if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0)
1325                 return NULL;
1326
1327         return buf;
1328 }
1329
1330 bool fstype_is_network(const char *fstype) {
1331         static const char * const table[] = {
1332                 "cifs",
1333                 "smbfs",
1334                 "ncpfs",
1335                 "nfs",
1336                 "nfs4"
1337         };
1338
1339         unsigned i;
1340
1341         for (i = 0; i < ELEMENTSOF(table); i++)
1342                 if (streq(table[i], fstype))
1343                         return true;
1344
1345         return false;
1346 }
1347
1348 int chvt(int vt) {
1349         int fd, r = 0;
1350
1351         if ((fd = open("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
1352                 return -errno;
1353
1354         if (vt < 0) {
1355                 int tiocl[2] = {
1356                         TIOCL_GETKMSGREDIRECT,
1357                         0
1358                 };
1359
1360                 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1361                         return -errno;
1362
1363                 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1364         }
1365
1366         if (ioctl(fd, VT_ACTIVATE, vt) < 0)
1367                 r = -errno;
1368
1369         close_nointr_nofail(r);
1370         return r;
1371 }
1372
1373 int read_one_char(FILE *f, char *ret, bool *need_nl) {
1374         struct termios old_termios, new_termios;
1375         char c;
1376         char line[1024];
1377
1378         assert(f);
1379         assert(ret);
1380
1381         if (tcgetattr(fileno(f), &old_termios) >= 0) {
1382                 new_termios = old_termios;
1383
1384                 new_termios.c_lflag &= ~ICANON;
1385                 new_termios.c_cc[VMIN] = 1;
1386                 new_termios.c_cc[VTIME] = 0;
1387
1388                 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
1389                         size_t k;
1390
1391                         k = fread(&c, 1, 1, f);
1392
1393                         tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1394
1395                         if (k <= 0)
1396                                 return -EIO;
1397
1398                         if (need_nl)
1399                                 *need_nl = c != '\n';
1400
1401                         *ret = c;
1402                         return 0;
1403                 }
1404         }
1405
1406         if (!(fgets(line, sizeof(line), f)))
1407                 return -EIO;
1408
1409         truncate_nl(line);
1410
1411         if (strlen(line) != 1)
1412                 return -EBADMSG;
1413
1414         if (need_nl)
1415                 *need_nl = false;
1416
1417         *ret = line[0];
1418         return 0;
1419 }
1420
1421 int ask(char *ret, const char *replies, const char *text, ...) {
1422         assert(ret);
1423         assert(replies);
1424         assert(text);
1425
1426         for (;;) {
1427                 va_list ap;
1428                 char c;
1429                 int r;
1430                 bool need_nl = true;
1431
1432                 fputs("\x1B[1m", stdout);
1433
1434                 va_start(ap, text);
1435                 vprintf(text, ap);
1436                 va_end(ap);
1437
1438                 fputs("\x1B[0m", stdout);
1439
1440                 fflush(stdout);
1441
1442                 if ((r = read_one_char(stdin, &c, &need_nl)) < 0) {
1443
1444                         if (r == -EBADMSG) {
1445                                 puts("Bad input, please try again.");
1446                                 continue;
1447                         }
1448
1449                         putchar('\n');
1450                         return r;
1451                 }
1452
1453                 if (need_nl)
1454                         putchar('\n');
1455
1456                 if (strchr(replies, c)) {
1457                         *ret = c;
1458                         return 0;
1459                 }
1460
1461                 puts("Read unexpected character, please try again.");
1462         }
1463 }
1464
1465 int reset_terminal(int fd) {
1466         struct termios termios;
1467         int r = 0;
1468
1469         assert(fd >= 0);
1470
1471         /* Set terminal to some sane defaults */
1472
1473         if (tcgetattr(fd, &termios) < 0) {
1474                 r = -errno;
1475                 goto finish;
1476         }
1477
1478         /* We only reset the stuff that matters to the software. How
1479          * hardware is set up we don't touch assuming that somebody
1480          * else will do that for us */
1481
1482         termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
1483         termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
1484         termios.c_oflag |= ONLCR;
1485         termios.c_cflag |= CREAD;
1486         termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
1487
1488         termios.c_cc[VINTR]    =   03;  /* ^C */
1489         termios.c_cc[VQUIT]    =  034;  /* ^\ */
1490         termios.c_cc[VERASE]   = 0177;
1491         termios.c_cc[VKILL]    =  025;  /* ^X */
1492         termios.c_cc[VEOF]     =   04;  /* ^D */
1493         termios.c_cc[VSTART]   =  021;  /* ^Q */
1494         termios.c_cc[VSTOP]    =  023;  /* ^S */
1495         termios.c_cc[VSUSP]    =  032;  /* ^Z */
1496         termios.c_cc[VLNEXT]   =  026;  /* ^V */
1497         termios.c_cc[VWERASE]  =  027;  /* ^W */
1498         termios.c_cc[VREPRINT] =  022;  /* ^R */
1499         termios.c_cc[VEOL]     =    0;
1500         termios.c_cc[VEOL2]    =    0;
1501
1502         termios.c_cc[VTIME]  = 0;
1503         termios.c_cc[VMIN]   = 1;
1504
1505         if (tcsetattr(fd, TCSANOW, &termios) < 0)
1506                 r = -errno;
1507
1508 finish:
1509         /* Just in case, flush all crap out */
1510         tcflush(fd, TCIOFLUSH);
1511
1512         return r;
1513 }
1514
1515 int open_terminal(const char *name, int mode) {
1516         int fd, r;
1517
1518         if ((fd = open(name, mode)) < 0)
1519                 return -errno;
1520
1521         if ((r = isatty(fd)) < 0) {
1522                 close_nointr_nofail(fd);
1523                 return -errno;
1524         }
1525
1526         if (!r) {
1527                 close_nointr_nofail(fd);
1528                 return -ENOTTY;
1529         }
1530
1531         return fd;
1532 }
1533
1534 int flush_fd(int fd) {
1535         struct pollfd pollfd;
1536
1537         zero(pollfd);
1538         pollfd.fd = fd;
1539         pollfd.events = POLLIN;
1540
1541         for (;;) {
1542                 char buf[1024];
1543                 ssize_t l;
1544                 int r;
1545
1546                 if ((r = poll(&pollfd, 1, 0)) < 0) {
1547
1548                         if (errno == EINTR)
1549                                 continue;
1550
1551                         return -errno;
1552                 }
1553
1554                 if (r == 0)
1555                         return 0;
1556
1557                 if ((l = read(fd, buf, sizeof(buf))) < 0) {
1558
1559                         if (errno == EINTR)
1560                                 continue;
1561
1562                         if (errno == EAGAIN)
1563                                 return 0;
1564
1565                         return -errno;
1566                 }
1567
1568                 if (l <= 0)
1569                         return 0;
1570         }
1571 }
1572
1573 int acquire_terminal(const char *name, bool fail, bool force) {
1574         int fd = -1, notify = -1, r, wd;
1575
1576         assert(name);
1577
1578         /* We use inotify to be notified when the tty is closed. We
1579          * create the watch before checking if we can actually acquire
1580          * it, so that we don't lose any event.
1581          *
1582          * Note: strictly speaking this actually watches for the
1583          * device being closed, it does *not* really watch whether a
1584          * tty loses its controlling process. However, unless some
1585          * rogue process uses TIOCNOTTY on /dev/tty *after* closing
1586          * its tty otherwise this will not become a problem. As long
1587          * as the administrator makes sure not configure any service
1588          * on the same tty as an untrusted user this should not be a
1589          * problem. (Which he probably should not do anyway.) */
1590
1591         if (!fail && !force) {
1592                 if ((notify = inotify_init1(IN_CLOEXEC)) < 0) {
1593                         r = -errno;
1594                         goto fail;
1595                 }
1596
1597                 if ((wd = inotify_add_watch(notify, name, IN_CLOSE)) < 0) {
1598                         r = -errno;
1599                         goto fail;
1600                 }
1601         }
1602
1603         for (;;) {
1604                 if ((r = flush_fd(notify)) < 0)
1605                         goto fail;
1606
1607                 /* We pass here O_NOCTTY only so that we can check the return
1608                  * value TIOCSCTTY and have a reliable way to figure out if we
1609                  * successfully became the controlling process of the tty */
1610                 if ((fd = open_terminal(name, O_RDWR|O_NOCTTY)) < 0)
1611                         return -errno;
1612
1613                 /* First, try to get the tty */
1614                 if ((r = ioctl(fd, TIOCSCTTY, force)) < 0 &&
1615                     (force || fail || errno != EPERM)) {
1616                         r = -errno;
1617                         goto fail;
1618                 }
1619
1620                 if (r >= 0)
1621                         break;
1622
1623                 assert(!fail);
1624                 assert(!force);
1625                 assert(notify >= 0);
1626
1627                 for (;;) {
1628                         struct inotify_event e;
1629                         ssize_t l;
1630
1631                         if ((l = read(notify, &e, sizeof(e))) != sizeof(e)) {
1632
1633                                 if (l < 0) {
1634
1635                                         if (errno == EINTR)
1636                                                 continue;
1637
1638                                         r = -errno;
1639                                 } else
1640                                         r = -EIO;
1641
1642                                 goto fail;
1643                         }
1644
1645                         if (e.wd != wd || !(e.mask & IN_CLOSE)) {
1646                                 r = -errno;
1647                                 goto fail;
1648                         }
1649
1650                         break;
1651                 }
1652
1653                 /* We close the tty fd here since if the old session
1654                  * ended our handle will be dead. It's important that
1655                  * we do this after sleeping, so that we don't enter
1656                  * an endless loop. */
1657                 close_nointr_nofail(fd);
1658         }
1659
1660         if (notify >= 0)
1661                 close_nointr_nofail(notify);
1662
1663         if ((r = reset_terminal(fd)) < 0)
1664                 log_warning("Failed to reset terminal: %s", strerror(-r));
1665
1666         return fd;
1667
1668 fail:
1669         if (fd >= 0)
1670                 close_nointr_nofail(fd);
1671
1672         if (notify >= 0)
1673                 close_nointr_nofail(notify);
1674
1675         return r;
1676 }
1677
1678 int release_terminal(void) {
1679         int r = 0, fd;
1680         struct sigaction sa_old, sa_new;
1681
1682         if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY)) < 0)
1683                 return -errno;
1684
1685         /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
1686          * by our own TIOCNOTTY */
1687
1688         zero(sa_new);
1689         sa_new.sa_handler = SIG_IGN;
1690         sa_new.sa_flags = SA_RESTART;
1691         assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
1692
1693         if (ioctl(fd, TIOCNOTTY) < 0)
1694                 r = -errno;
1695
1696         assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
1697
1698         close_nointr_nofail(fd);
1699         return r;
1700 }
1701
1702 int ignore_signal(int sig) {
1703         struct sigaction sa;
1704
1705         zero(sa);
1706         sa.sa_handler = SIG_IGN;
1707         sa.sa_flags = SA_RESTART;
1708
1709         return sigaction(sig, &sa, NULL);
1710 }
1711
1712 int close_pipe(int p[]) {
1713         int a = 0, b = 0;
1714
1715         assert(p);
1716
1717         if (p[0] >= 0) {
1718                 a = close_nointr(p[0]);
1719                 p[0] = -1;
1720         }
1721
1722         if (p[1] >= 0) {
1723                 b = close_nointr(p[1]);
1724                 p[1] = -1;
1725         }
1726
1727         return a < 0 ? a : b;
1728 }
1729
1730 ssize_t loop_read(int fd, void *buf, size_t nbytes) {
1731         uint8_t *p;
1732         ssize_t n = 0;
1733
1734         assert(fd >= 0);
1735         assert(buf);
1736
1737         p = buf;
1738
1739         while (nbytes > 0) {
1740                 ssize_t k;
1741
1742                 if ((k = read(fd, p, nbytes)) <= 0) {
1743
1744                         if (errno == EINTR)
1745                                 continue;
1746
1747                         if (errno == EAGAIN) {
1748                                 struct pollfd pollfd;
1749
1750                                 zero(pollfd);
1751                                 pollfd.fd = fd;
1752                                 pollfd.events = POLLIN;
1753
1754                                 if (poll(&pollfd, 1, -1) < 0) {
1755                                         if (errno == EINTR)
1756                                                 continue;
1757
1758                                         return n > 0 ? n : -errno;
1759                                 }
1760
1761                                 if (pollfd.revents != POLLIN)
1762                                         return n > 0 ? n : -EIO;
1763
1764                                 continue;
1765                         }
1766
1767                         return n > 0 ? n : (k < 0 ? -errno : 0);
1768                 }
1769
1770                 p += k;
1771                 nbytes -= k;
1772                 n += k;
1773         }
1774
1775         return n;
1776 }
1777
1778 int path_is_mount_point(const char *t) {
1779         struct stat a, b;
1780         char *copy;
1781
1782         if (lstat(t, &a) < 0) {
1783
1784                 if (errno == ENOENT)
1785                         return 0;
1786
1787                 return -errno;
1788         }
1789
1790         if (!(copy = strdup(t)))
1791                 return -ENOMEM;
1792
1793         if (lstat(dirname(copy), &b) < 0) {
1794                 free(copy);
1795                 return -errno;
1796         }
1797
1798         free(copy);
1799
1800         return a.st_dev != b.st_dev;
1801 }
1802
1803 int parse_usec(const char *t, usec_t *usec) {
1804         static const struct {
1805                 const char *suffix;
1806                 usec_t usec;
1807         } table[] = {
1808                 { "sec", USEC_PER_SEC },
1809                 { "s", USEC_PER_SEC },
1810                 { "min", USEC_PER_MINUTE },
1811                 { "hr", USEC_PER_HOUR },
1812                 { "h", USEC_PER_HOUR },
1813                 { "d", USEC_PER_DAY },
1814                 { "w", USEC_PER_WEEK },
1815                 { "msec", USEC_PER_MSEC },
1816                 { "ms", USEC_PER_MSEC },
1817                 { "m", USEC_PER_MINUTE },
1818                 { "usec", 1ULL },
1819                 { "us", 1ULL },
1820                 { "", USEC_PER_SEC },
1821         };
1822
1823         const char *p;
1824         usec_t r = 0;
1825
1826         assert(t);
1827         assert(usec);
1828
1829         p = t;
1830         do {
1831                 long long l;
1832                 char *e;
1833                 unsigned i;
1834
1835                 errno = 0;
1836                 l = strtoll(p, &e, 10);
1837
1838                 if (errno != 0)
1839                         return -errno;
1840
1841                 if (l < 0)
1842                         return -ERANGE;
1843
1844                 if (e == p)
1845                         return -EINVAL;
1846
1847                 e += strspn(e, WHITESPACE);
1848
1849                 for (i = 0; i < ELEMENTSOF(table); i++)
1850                         if (startswith(e, table[i].suffix)) {
1851                                 r += (usec_t) l * table[i].usec;
1852                                 p = e + strlen(table[i].suffix);
1853                                 break;
1854                         }
1855
1856                 if (i >= ELEMENTSOF(table))
1857                         return -EINVAL;
1858
1859         } while (*p != 0);
1860
1861         *usec = r;
1862
1863         return 0;
1864 }
1865
1866 static const char *const ioprio_class_table[] = {
1867         [IOPRIO_CLASS_NONE] = "none",
1868         [IOPRIO_CLASS_RT] = "realtime",
1869         [IOPRIO_CLASS_BE] = "best-effort",
1870         [IOPRIO_CLASS_IDLE] = "idle"
1871 };
1872
1873 DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
1874
1875 static const char *const sigchld_code_table[] = {
1876         [CLD_EXITED] = "exited",
1877         [CLD_KILLED] = "killed",
1878         [CLD_DUMPED] = "dumped",
1879         [CLD_TRAPPED] = "trapped",
1880         [CLD_STOPPED] = "stopped",
1881         [CLD_CONTINUED] = "continued",
1882 };
1883
1884 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
1885
1886 static const char *const log_facility_table[LOG_NFACILITIES] = {
1887         [LOG_FAC(LOG_KERN)] = "kern",
1888         [LOG_FAC(LOG_USER)] = "user",
1889         [LOG_FAC(LOG_MAIL)] = "mail",
1890         [LOG_FAC(LOG_DAEMON)] = "daemon",
1891         [LOG_FAC(LOG_AUTH)] = "auth",
1892         [LOG_FAC(LOG_SYSLOG)] = "syslog",
1893         [LOG_FAC(LOG_LPR)] = "lpr",
1894         [LOG_FAC(LOG_NEWS)] = "news",
1895         [LOG_FAC(LOG_UUCP)] = "uucp",
1896         [LOG_FAC(LOG_CRON)] = "cron",
1897         [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
1898         [LOG_FAC(LOG_FTP)] = "ftp",
1899         [LOG_FAC(LOG_LOCAL0)] = "local0",
1900         [LOG_FAC(LOG_LOCAL1)] = "local1",
1901         [LOG_FAC(LOG_LOCAL2)] = "local2",
1902         [LOG_FAC(LOG_LOCAL3)] = "local3",
1903         [LOG_FAC(LOG_LOCAL4)] = "local4",
1904         [LOG_FAC(LOG_LOCAL5)] = "local5",
1905         [LOG_FAC(LOG_LOCAL6)] = "local6",
1906         [LOG_FAC(LOG_LOCAL7)] = "local7"
1907 };
1908
1909 DEFINE_STRING_TABLE_LOOKUP(log_facility, int);
1910
1911 static const char *const log_level_table[] = {
1912         [LOG_EMERG] = "emerg",
1913         [LOG_ALERT] = "alert",
1914         [LOG_CRIT] = "crit",
1915         [LOG_ERR] = "err",
1916         [LOG_WARNING] = "warning",
1917         [LOG_NOTICE] = "notice",
1918         [LOG_INFO] = "info",
1919         [LOG_DEBUG] = "debug"
1920 };
1921
1922 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
1923
1924 static const char* const sched_policy_table[] = {
1925         [SCHED_OTHER] = "other",
1926         [SCHED_BATCH] = "batch",
1927         [SCHED_IDLE] = "idle",
1928         [SCHED_FIFO] = "fifo",
1929         [SCHED_RR] = "rr"
1930 };
1931
1932 DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
1933
1934 static const char* const rlimit_table[] = {
1935         [RLIMIT_CPU] = "LimitCPU",
1936         [RLIMIT_FSIZE] = "LimitFSIZE",
1937         [RLIMIT_DATA] = "LimitDATA",
1938         [RLIMIT_STACK] = "LimitSTACK",
1939         [RLIMIT_CORE] = "LimitCORE",
1940         [RLIMIT_RSS] = "LimitRSS",
1941         [RLIMIT_NOFILE] = "LimitNOFILE",
1942         [RLIMIT_AS] = "LimitAS",
1943         [RLIMIT_NPROC] = "LimitNPROC",
1944         [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
1945         [RLIMIT_LOCKS] = "LimitLOCKS",
1946         [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
1947         [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
1948         [RLIMIT_NICE] = "LimitNICE",
1949         [RLIMIT_RTPRIO] = "LimitRTPRIO",
1950         [RLIMIT_RTTIME] = "LimitRTTIME"
1951 };
1952
1953 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);