chiark / gitweb /
manager: we are not interested in SIGPIPE/SIGTTIN
[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
41 #include "macro.h"
42 #include "util.h"
43 #include "ioprio.h"
44 #include "missing.h"
45 #include "log.h"
46 #include "strv.h"
47
48 bool streq_ptr(const char *a, const char *b) {
49
50         /* Like streq(), but tries to make sense of NULL pointers */
51
52         if (a && b)
53                 return streq(a, b);
54
55         if (!a && !b)
56                 return true;
57
58         return false;
59 }
60
61 usec_t now(clockid_t clock_id) {
62         struct timespec ts;
63
64         assert_se(clock_gettime(clock_id, &ts) == 0);
65
66         return timespec_load(&ts);
67 }
68
69 usec_t timespec_load(const struct timespec *ts) {
70         assert(ts);
71
72         return
73                 (usec_t) ts->tv_sec * USEC_PER_SEC +
74                 (usec_t) ts->tv_nsec / NSEC_PER_USEC;
75 }
76
77 struct timespec *timespec_store(struct timespec *ts, usec_t u)  {
78         assert(ts);
79
80         ts->tv_sec = (time_t) (u / USEC_PER_SEC);
81         ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
82
83         return ts;
84 }
85
86 usec_t timeval_load(const struct timeval *tv) {
87         assert(tv);
88
89         return
90                 (usec_t) tv->tv_sec * USEC_PER_SEC +
91                 (usec_t) tv->tv_usec;
92 }
93
94 struct timeval *timeval_store(struct timeval *tv, usec_t u) {
95         assert(tv);
96
97         tv->tv_sec = (time_t) (u / USEC_PER_SEC);
98         tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
99
100         return tv;
101 }
102
103 bool endswith(const char *s, const char *postfix) {
104         size_t sl, pl;
105
106         assert(s);
107         assert(postfix);
108
109         sl = strlen(s);
110         pl = strlen(postfix);
111
112         if (sl < pl)
113                 return false;
114
115         return memcmp(s + sl - pl, postfix, pl) == 0;
116 }
117
118 bool startswith(const char *s, const char *prefix) {
119         size_t sl, pl;
120
121         assert(s);
122         assert(prefix);
123
124         sl = strlen(s);
125         pl = strlen(prefix);
126
127         if (sl < pl)
128                 return false;
129
130         return memcmp(s, prefix, pl) == 0;
131 }
132
133 bool first_word(const char *s, const char *word) {
134         size_t sl, wl;
135
136         assert(s);
137         assert(word);
138
139         sl = strlen(s);
140         wl = strlen(word);
141
142         if (sl < wl)
143                 return false;
144
145         if (memcmp(s, word, wl) != 0)
146                 return false;
147
148         return (s[wl] == 0 ||
149                 strchr(WHITESPACE, s[wl]));
150 }
151
152 int close_nointr(int fd) {
153         assert(fd >= 0);
154
155         for (;;) {
156                 int r;
157
158                 if ((r = close(fd)) >= 0)
159                         return r;
160
161                 if (errno != EINTR)
162                         return r;
163         }
164 }
165
166 void close_nointr_nofail(int fd) {
167
168         /* like close_nointr() but cannot fail, and guarantees errno
169          * is unchanged */
170
171         assert_se(close_nointr(fd) == 0);
172 }
173
174 int parse_boolean(const char *v) {
175         assert(v);
176
177         if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
178                 return 1;
179         else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
180                 return 0;
181
182         return -EINVAL;
183 }
184
185 int safe_atou(const char *s, unsigned *ret_u) {
186         char *x = NULL;
187         unsigned long l;
188
189         assert(s);
190         assert(ret_u);
191
192         errno = 0;
193         l = strtoul(s, &x, 0);
194
195         if (!x || *x || errno)
196                 return errno ? -errno : -EINVAL;
197
198         if ((unsigned long) (unsigned) l != l)
199                 return -ERANGE;
200
201         *ret_u = (unsigned) l;
202         return 0;
203 }
204
205 int safe_atoi(const char *s, int *ret_i) {
206         char *x = NULL;
207         long l;
208
209         assert(s);
210         assert(ret_i);
211
212         errno = 0;
213         l = strtol(s, &x, 0);
214
215         if (!x || *x || errno)
216                 return errno ? -errno : -EINVAL;
217
218         if ((long) (int) l != l)
219                 return -ERANGE;
220
221         *ret_i = (int) l;
222         return 0;
223 }
224
225 int safe_atolu(const char *s, long unsigned *ret_lu) {
226         char *x = NULL;
227         unsigned long l;
228
229         assert(s);
230         assert(ret_lu);
231
232         errno = 0;
233         l = strtoul(s, &x, 0);
234
235         if (!x || *x || errno)
236                 return errno ? -errno : -EINVAL;
237
238         *ret_lu = l;
239         return 0;
240 }
241
242 int safe_atoli(const char *s, long int *ret_li) {
243         char *x = NULL;
244         long l;
245
246         assert(s);
247         assert(ret_li);
248
249         errno = 0;
250         l = strtol(s, &x, 0);
251
252         if (!x || *x || errno)
253                 return errno ? -errno : -EINVAL;
254
255         *ret_li = l;
256         return 0;
257 }
258
259 int safe_atollu(const char *s, long long unsigned *ret_llu) {
260         char *x = NULL;
261         unsigned long long l;
262
263         assert(s);
264         assert(ret_llu);
265
266         errno = 0;
267         l = strtoull(s, &x, 0);
268
269         if (!x || *x || errno)
270                 return errno ? -errno : -EINVAL;
271
272         *ret_llu = l;
273         return 0;
274 }
275
276 int safe_atolli(const char *s, long long int *ret_lli) {
277         char *x = NULL;
278         long long l;
279
280         assert(s);
281         assert(ret_lli);
282
283         errno = 0;
284         l = strtoll(s, &x, 0);
285
286         if (!x || *x || errno)
287                 return errno ? -errno : -EINVAL;
288
289         *ret_lli = l;
290         return 0;
291 }
292
293 /* Split a string into words. */
294 char *split(const char *c, size_t *l, const char *separator, char **state) {
295         char *current;
296
297         current = *state ? *state : (char*) c;
298
299         if (!*current || *c == 0)
300                 return NULL;
301
302         current += strspn(current, separator);
303         *l = strcspn(current, separator);
304         *state = current+*l;
305
306         return (char*) current;
307 }
308
309 /* Split a string into words, but consider strings enclosed in '' and
310  * "" as words even if they include spaces. */
311 char *split_quoted(const char *c, size_t *l, 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, WHITESPACE);
320
321         if (*current == '\'') {
322                 current ++;
323                 *l = strcspn(current, "'");
324                 *state = current+*l;
325
326                 if (**state == '\'')
327                         (*state)++;
328         } else if (*current == '\"') {
329                 current ++;
330                 *l = strcspn(current, "\"");
331                 *state = current+*l;
332
333                 if (**state == '\"')
334                         (*state)++;
335         } else {
336                 *l = strcspn(current, WHITESPACE);
337                 *state = current+*l;
338         }
339
340         /* FIXME: Cannot deal with strings that have spaces AND ticks
341          * in them */
342
343         return (char*) current;
344 }
345
346 char **split_path_and_make_absolute(const char *p) {
347         char **l;
348         assert(p);
349
350         if (!(l = strv_split(p, ":")))
351                 return NULL;
352
353         if (!strv_path_make_absolute_cwd(l)) {
354                 strv_free(l);
355                 return NULL;
356         }
357
358         return l;
359 }
360
361 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
362         int r;
363         FILE *f;
364         char fn[132], line[256], *p;
365         long long unsigned ppid;
366
367         assert(pid >= 0);
368         assert(_ppid);
369
370         assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%llu/stat", (unsigned long long) pid) < (int) (sizeof(fn)-1));
371         fn[sizeof(fn)-1] = 0;
372
373         if (!(f = fopen(fn, "r")))
374                 return -errno;
375
376         if (!(fgets(line, sizeof(line), f))) {
377                 r = -errno;
378                 fclose(f);
379                 return r;
380         }
381
382         fclose(f);
383
384         /* Let's skip the pid and comm fields. The latter is enclosed
385          * in () but does not escape any () in its value, so let's
386          * skip over it manually */
387
388         if (!(p = strrchr(line, ')')))
389                 return -EIO;
390
391         p++;
392
393         if (sscanf(p, " "
394                    "%*c "  /* state */
395                    "%llu ", /* ppid */
396                    &ppid) != 1)
397                 return -EIO;
398
399         if ((long long unsigned) (pid_t) ppid != ppid)
400                 return -ERANGE;
401
402         *_ppid = (pid_t) ppid;
403
404         return 0;
405 }
406
407 int write_one_line_file(const char *fn, const char *line) {
408         FILE *f;
409         int r;
410
411         assert(fn);
412         assert(line);
413
414         if (!(f = fopen(fn, "we")))
415                 return -errno;
416
417         if (fputs(line, f) < 0) {
418                 r = -errno;
419                 goto finish;
420         }
421
422         r = 0;
423 finish:
424         fclose(f);
425         return r;
426 }
427
428 int read_one_line_file(const char *fn, char **line) {
429         FILE *f;
430         int r;
431         char t[2048], *c;
432
433         assert(fn);
434         assert(line);
435
436         if (!(f = fopen(fn, "re")))
437                 return -errno;
438
439         if (!(fgets(t, sizeof(t), f))) {
440                 r = -errno;
441                 goto finish;
442         }
443
444         if (!(c = strdup(t))) {
445                 r = -ENOMEM;
446                 goto finish;
447         }
448
449         *line = c;
450         r = 0;
451
452 finish:
453         fclose(f);
454         return r;
455 }
456
457 char *truncate_nl(char *s) {
458         assert(s);
459
460         s[strcspn(s, NEWLINE)] = 0;
461         return s;
462 }
463
464 int get_process_name(pid_t pid, char **name) {
465         char *p;
466         int r;
467
468         assert(pid >= 1);
469         assert(name);
470
471         if (asprintf(&p, "/proc/%llu/comm", (unsigned long long) pid) < 0)
472                 return -ENOMEM;
473
474         r = read_one_line_file(p, name);
475         free(p);
476
477         if (r < 0)
478                 return r;
479
480         truncate_nl(*name);
481         return 0;
482 }
483
484 char *strappend(const char *s, const char *suffix) {
485         size_t a, b;
486         char *r;
487
488         assert(s);
489         assert(suffix);
490
491         a = strlen(s);
492         b = strlen(suffix);
493
494         if (!(r = new(char, a+b+1)))
495                 return NULL;
496
497         memcpy(r, s, a);
498         memcpy(r+a, suffix, b);
499         r[a+b] = 0;
500
501         return r;
502 }
503
504 int readlink_malloc(const char *p, char **r) {
505         size_t l = 100;
506
507         assert(p);
508         assert(r);
509
510         for (;;) {
511                 char *c;
512                 ssize_t n;
513
514                 if (!(c = new(char, l)))
515                         return -ENOMEM;
516
517                 if ((n = readlink(p, c, l-1)) < 0) {
518                         int ret = -errno;
519                         free(c);
520                         return ret;
521                 }
522
523                 if ((size_t) n < l-1) {
524                         c[n] = 0;
525                         *r = c;
526                         return 0;
527                 }
528
529                 free(c);
530                 l *= 2;
531         }
532 }
533
534 char *file_name_from_path(const char *p) {
535         char *r;
536
537         assert(p);
538
539         if ((r = strrchr(p, '/')))
540                 return r + 1;
541
542         return (char*) p;
543 }
544
545 bool path_is_absolute(const char *p) {
546         assert(p);
547
548         return p[0] == '/';
549 }
550
551 bool is_path(const char *p) {
552
553         return !!strchr(p, '/');
554 }
555
556 char *path_make_absolute(const char *p, const char *prefix) {
557         char *r;
558
559         assert(p);
560
561         /* Makes every item in the list an absolute path by prepending
562          * the prefix, if specified and necessary */
563
564         if (path_is_absolute(p) || !prefix)
565                 return strdup(p);
566
567         if (asprintf(&r, "%s/%s", prefix, p) < 0)
568                 return NULL;
569
570         return r;
571 }
572
573 char *path_make_absolute_cwd(const char *p) {
574         char *cwd, *r;
575
576         assert(p);
577
578         /* Similar to path_make_absolute(), but prefixes with the
579          * current working directory. */
580
581         if (path_is_absolute(p))
582                 return strdup(p);
583
584         if (!(cwd = get_current_dir_name()))
585                 return NULL;
586
587         r = path_make_absolute(p, cwd);
588         free(cwd);
589
590         return r;
591 }
592
593 char **strv_path_make_absolute_cwd(char **l) {
594         char **s;
595
596         /* Goes through every item in the string list and makes it
597          * absolute. This works in place and won't rollback any
598          * changes on failure. */
599
600         STRV_FOREACH(s, l) {
601                 char *t;
602
603                 if (!(t = path_make_absolute_cwd(*s)))
604                         return NULL;
605
606                 free(*s);
607                 *s = t;
608         }
609
610         return l;
611 }
612
613 int reset_all_signal_handlers(void) {
614         int sig;
615
616         for (sig = 1; sig < _NSIG; sig++) {
617                 struct sigaction sa;
618
619                 if (sig == SIGKILL || sig == SIGSTOP)
620                         continue;
621
622                 zero(sa);
623                 sa.sa_handler = SIG_DFL;
624                 sa.sa_flags = SA_RESTART;
625
626                 /* On Linux the first two RT signals are reserved by
627                  * glibc, and sigaction() will return EINVAL for them. */
628                 if ((sigaction(sig, &sa, NULL) < 0))
629                         if (errno != EINVAL)
630                                 return -errno;
631         }
632
633         return 0;
634 }
635
636 char *strstrip(char *s) {
637         char *e, *l = NULL;
638
639         /* Drops trailing whitespace. Modifies the string in
640          * place. Returns pointer to first non-space character */
641
642         s += strspn(s, WHITESPACE);
643
644         for (e = s; *e; e++)
645                 if (!strchr(WHITESPACE, *e))
646                         l = e;
647
648         if (l)
649                 *(l+1) = 0;
650         else
651                 *s = 0;
652
653         return s;
654
655 }
656
657 char *delete_chars(char *s, const char *bad) {
658         char *f, *t;
659
660         /* Drops all whitespace, regardless where in the string */
661
662         for (f = s, t = s; *f; f++) {
663                 if (strchr(bad, *f))
664                         continue;
665
666                 *(t++) = *f;
667         }
668
669         *t = 0;
670
671         return s;
672 }
673
674 char *file_in_same_dir(const char *path, const char *filename) {
675         char *e, *r;
676         size_t k;
677
678         assert(path);
679         assert(filename);
680
681         /* This removes the last component of path and appends
682          * filename, unless the latter is absolute anyway or the
683          * former isn't */
684
685         if (path_is_absolute(filename))
686                 return strdup(filename);
687
688         if (!(e = strrchr(path, '/')))
689                 return strdup(filename);
690
691         k = strlen(filename);
692         if (!(r = new(char, e-path+1+k+1)))
693                 return NULL;
694
695         memcpy(r, path, e-path+1);
696         memcpy(r+(e-path)+1, filename, k+1);
697
698         return r;
699 }
700
701 int mkdir_parents(const char *path, mode_t mode) {
702         const char *p, *e;
703
704         assert(path);
705
706         /* Creates every parent directory in the path except the last
707          * component. */
708
709         p = path + strspn(path, "/");
710         for (;;) {
711                 int r;
712                 char *t;
713
714                 e = p + strcspn(p, "/");
715                 p = e + strspn(e, "/");
716
717                 /* Is this the last component? If so, then we're
718                  * done */
719                 if (*p == 0)
720                         return 0;
721
722                 if (!(t = strndup(path, e - path)))
723                         return -ENOMEM;
724
725                 r = mkdir(t, mode);
726
727                 free(t);
728
729                 if (r < 0 && errno != EEXIST)
730                         return -errno;
731         }
732 }
733
734 int mkdir_p(const char *path, mode_t mode) {
735         int r;
736
737         /* Like mkdir -p */
738
739         if ((r = mkdir_parents(path, mode)) < 0)
740                 return r;
741
742         if (mkdir(path, mode) < 0)
743                 return -errno;
744
745         return 0;
746 }
747
748 char hexchar(int x) {
749         static const char table[16] = "0123456789abcdef";
750
751         return table[x & 15];
752 }
753
754 int unhexchar(char c) {
755
756         if (c >= '0' && c <= '9')
757                 return c - '0';
758
759         if (c >= 'a' && c <= 'f')
760                 return c - 'a' + 10;
761
762         if (c >= 'A' && c <= 'F')
763                 return c - 'A' + 10;
764
765         return -1;
766 }
767
768 char octchar(int x) {
769         return '0' + (x & 7);
770 }
771
772 int unoctchar(char c) {
773
774         if (c >= '0' && c <= '7')
775                 return c - '0';
776
777         return -1;
778 }
779
780 char decchar(int x) {
781         return '0' + (x % 10);
782 }
783
784 int undecchar(char c) {
785
786         if (c >= '0' && c <= '9')
787                 return c - '0';
788
789         return -1;
790 }
791
792 char *cescape(const char *s) {
793         char *r, *t;
794         const char *f;
795
796         assert(s);
797
798         /* Does C style string escaping. */
799
800         if (!(r = new(char, strlen(s)*4 + 1)))
801                 return NULL;
802
803         for (f = s, t = r; *f; f++)
804
805                 switch (*f) {
806
807                 case '\a':
808                         *(t++) = '\\';
809                         *(t++) = 'a';
810                         break;
811                 case '\b':
812                         *(t++) = '\\';
813                         *(t++) = 'b';
814                         break;
815                 case '\f':
816                         *(t++) = '\\';
817                         *(t++) = 'f';
818                         break;
819                 case '\n':
820                         *(t++) = '\\';
821                         *(t++) = 'n';
822                         break;
823                 case '\r':
824                         *(t++) = '\\';
825                         *(t++) = 'r';
826                         break;
827                 case '\t':
828                         *(t++) = '\\';
829                         *(t++) = 't';
830                         break;
831                 case '\v':
832                         *(t++) = '\\';
833                         *(t++) = 'v';
834                         break;
835                 case '\\':
836                         *(t++) = '\\';
837                         *(t++) = '\\';
838                         break;
839                 case '"':
840                         *(t++) = '\\';
841                         *(t++) = '"';
842                         break;
843                 case '\'':
844                         *(t++) = '\\';
845                         *(t++) = '\'';
846                         break;
847
848                 default:
849                         /* For special chars we prefer octal over
850                          * hexadecimal encoding, simply because glib's
851                          * g_strescape() does the same */
852                         if ((*f < ' ') || (*f >= 127)) {
853                                 *(t++) = '\\';
854                                 *(t++) = octchar((unsigned char) *f >> 6);
855                                 *(t++) = octchar((unsigned char) *f >> 3);
856                                 *(t++) = octchar((unsigned char) *f);
857                         } else
858                                 *(t++) = *f;
859                         break;
860                 }
861
862         *t = 0;
863
864         return r;
865 }
866
867 char *cunescape(const char *s) {
868         char *r, *t;
869         const char *f;
870
871         assert(s);
872
873         /* Undoes C style string escaping */
874
875         if (!(r = new(char, strlen(s)+1)))
876                 return r;
877
878         for (f = s, t = r; *f; f++) {
879
880                 if (*f != '\\') {
881                         *(t++) = *f;
882                         continue;
883                 }
884
885                 f++;
886
887                 switch (*f) {
888
889                 case 'a':
890                         *(t++) = '\a';
891                         break;
892                 case 'b':
893                         *(t++) = '\b';
894                         break;
895                 case 'f':
896                         *(t++) = '\f';
897                         break;
898                 case 'n':
899                         *(t++) = '\n';
900                         break;
901                 case 'r':
902                         *(t++) = '\r';
903                         break;
904                 case 't':
905                         *(t++) = '\t';
906                         break;
907                 case 'v':
908                         *(t++) = '\v';
909                         break;
910                 case '\\':
911                         *(t++) = '\\';
912                         break;
913                 case '"':
914                         *(t++) = '"';
915                         break;
916                 case '\'':
917                         *(t++) = '\'';
918                         break;
919
920                 case 'x': {
921                         /* hexadecimal encoding */
922                         int a, b;
923
924                         if ((a = unhexchar(f[1])) < 0 ||
925                             (b = unhexchar(f[2])) < 0) {
926                                 /* Invalid escape code, let's take it literal then */
927                                 *(t++) = '\\';
928                                 *(t++) = 'x';
929                         } else {
930                                 *(t++) = (char) ((a << 4) | b);
931                                 f += 2;
932                         }
933
934                         break;
935                 }
936
937                 case '0':
938                 case '1':
939                 case '2':
940                 case '3':
941                 case '4':
942                 case '5':
943                 case '6':
944                 case '7': {
945                         /* octal encoding */
946                         int a, b, c;
947
948                         if ((a = unoctchar(f[0])) < 0 ||
949                             (b = unoctchar(f[1])) < 0 ||
950                             (c = unoctchar(f[2])) < 0) {
951                                 /* Invalid escape code, let's take it literal then */
952                                 *(t++) = '\\';
953                                 *(t++) = f[0];
954                         } else {
955                                 *(t++) = (char) ((a << 6) | (b << 3) | c);
956                                 f += 2;
957                         }
958
959                         break;
960                 }
961
962                 case 0:
963                         /* premature end of string.*/
964                         *(t++) = '\\';
965                         goto finish;
966
967                 default:
968                         /* Invalid escape code, let's take it literal then */
969                         *(t++) = '\\';
970                         *(t++) = 'f';
971                         break;
972                 }
973         }
974
975 finish:
976         *t = 0;
977         return r;
978 }
979
980
981 char *xescape(const char *s, const char *bad) {
982         char *r, *t;
983         const char *f;
984
985         /* Escapes all chars in bad, in addition to \ and all special
986          * chars, in \xFF style escaping. May be reversed with
987          * cunescape. */
988
989         if (!(r = new(char, strlen(s)*4+1)))
990                 return NULL;
991
992         for (f = s, t = r; *f; f++) {
993
994                 if ((*f < ' ') || (*f >= 127) ||
995                     (*f == '\\') || strchr(bad, *f)) {
996                         *(t++) = '\\';
997                         *(t++) = 'x';
998                         *(t++) = hexchar(*f >> 4);
999                         *(t++) = hexchar(*f);
1000                 } else
1001                         *(t++) = *f;
1002         }
1003
1004         *t = 0;
1005
1006         return r;
1007 }
1008
1009 char *bus_path_escape(const char *s) {
1010         char *r, *t;
1011         const char *f;
1012
1013         assert(s);
1014
1015         /* Escapes all chars that D-Bus' object path cannot deal
1016          * with. Can be reverse with bus_path_unescape() */
1017
1018         if (!(r = new(char, strlen(s)*3+1)))
1019                 return NULL;
1020
1021         for (f = s, t = r; *f; f++) {
1022
1023                 if (!(*f >= 'A' && *f <= 'Z') &&
1024                     !(*f >= 'a' && *f <= 'z') &&
1025                     !(*f >= '0' && *f <= '9')) {
1026                         *(t++) = '_';
1027                         *(t++) = hexchar(*f >> 4);
1028                         *(t++) = hexchar(*f);
1029                 } else
1030                         *(t++) = *f;
1031         }
1032
1033         *t = 0;
1034
1035         return r;
1036 }
1037
1038 char *bus_path_unescape(const char *s) {
1039         char *r, *t;
1040         const char *f;
1041
1042         assert(s);
1043
1044         if (!(r = new(char, strlen(s)+1)))
1045                 return NULL;
1046
1047         for (f = s, t = r; *f; f++) {
1048
1049                 if (*f == '_') {
1050                         int a, b;
1051
1052                         if ((a = unhexchar(f[1])) < 0 ||
1053                             (b = unhexchar(f[2])) < 0) {
1054                                 /* Invalid escape code, let's take it literal then */
1055                                 *(t++) = '_';
1056                         } else {
1057                                 *(t++) = (char) ((a << 4) | b);
1058                                 f += 2;
1059                         }
1060                 } else
1061                         *(t++) = *f;
1062         }
1063
1064         *t = 0;
1065
1066         return r;
1067 }
1068
1069 char *path_kill_slashes(char *path) {
1070         char *f, *t;
1071         bool slash = false;
1072
1073         /* Removes redundant inner and trailing slashes. Modifies the
1074          * passed string in-place.
1075          *
1076          * ///foo///bar/ becomes /foo/bar
1077          */
1078
1079         for (f = path, t = path; *f; f++) {
1080
1081                 if (*f == '/') {
1082                         slash = true;
1083                         continue;
1084                 }
1085
1086                 if (slash) {
1087                         slash = false;
1088                         *(t++) = '/';
1089                 }
1090
1091                 *(t++) = *f;
1092         }
1093
1094         /* Special rule, if we are talking of the root directory, a
1095         trailing slash is good */
1096
1097         if (t == path && slash)
1098                 *(t++) = '/';
1099
1100         *t = 0;
1101         return path;
1102 }
1103
1104 bool path_startswith(const char *path, const char *prefix) {
1105         assert(path);
1106         assert(prefix);
1107
1108         if ((path[0] == '/') != (prefix[0] == '/'))
1109                 return false;
1110
1111         for (;;) {
1112                 size_t a, b;
1113
1114                 path += strspn(path, "/");
1115                 prefix += strspn(prefix, "/");
1116
1117                 if (*prefix == 0)
1118                         return true;
1119
1120                 if (*path == 0)
1121                         return false;
1122
1123                 a = strcspn(path, "/");
1124                 b = strcspn(prefix, "/");
1125
1126                 if (a != b)
1127                         return false;
1128
1129                 if (memcmp(path, prefix, a) != 0)
1130                         return false;
1131
1132                 path += a;
1133                 prefix += b;
1134         }
1135 }
1136
1137 char *ascii_strlower(char *t) {
1138         char *p;
1139
1140         assert(t);
1141
1142         for (p = t; *p; p++)
1143                 if (*p >= 'A' && *p <= 'Z')
1144                         *p = *p - 'A' + 'a';
1145
1146         return t;
1147 }
1148
1149 bool ignore_file(const char *filename) {
1150         assert(filename);
1151
1152         return
1153                 filename[0] == '.' ||
1154                 endswith(filename, "~") ||
1155                 endswith(filename, ".rpmnew") ||
1156                 endswith(filename, ".rpmsave") ||
1157                 endswith(filename, ".rpmorig") ||
1158                 endswith(filename, ".dpkg-old") ||
1159                 endswith(filename, ".dpkg-new") ||
1160                 endswith(filename, ".swp");
1161 }
1162
1163 int fd_nonblock(int fd, bool nonblock) {
1164         int flags;
1165
1166         assert(fd >= 0);
1167
1168         if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1169                 return -errno;
1170
1171         if (nonblock)
1172                 flags |= O_NONBLOCK;
1173         else
1174                 flags &= ~O_NONBLOCK;
1175
1176         if (fcntl(fd, F_SETFL, flags) < 0)
1177                 return -errno;
1178
1179         return 0;
1180 }
1181
1182 int fd_cloexec(int fd, bool cloexec) {
1183         int flags;
1184
1185         assert(fd >= 0);
1186
1187         if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1188                 return -errno;
1189
1190         if (cloexec)
1191                 flags |= FD_CLOEXEC;
1192         else
1193                 flags &= ~FD_CLOEXEC;
1194
1195         if (fcntl(fd, F_SETFD, flags) < 0)
1196                 return -errno;
1197
1198         return 0;
1199 }
1200
1201 int close_all_fds(const int except[], unsigned n_except) {
1202         DIR *d;
1203         struct dirent *de;
1204         int r = 0;
1205
1206         if (!(d = opendir("/proc/self/fd")))
1207                 return -errno;
1208
1209         while ((de = readdir(d))) {
1210                 int fd = -1;
1211
1212                 if (de->d_name[0] == '.')
1213                         continue;
1214
1215                 if ((r = safe_atoi(de->d_name, &fd)) < 0)
1216                         goto finish;
1217
1218                 if (fd < 3)
1219                         continue;
1220
1221                 if (fd == dirfd(d))
1222                         continue;
1223
1224                 if (except) {
1225                         bool found;
1226                         unsigned i;
1227
1228                         found = false;
1229                         for (i = 0; i < n_except; i++)
1230                                 if (except[i] == fd) {
1231                                         found = true;
1232                                         break;
1233                                 }
1234
1235                         if (found)
1236                                 continue;
1237                 }
1238
1239                 if ((r = close_nointr(fd)) < 0) {
1240                         /* Valgrind has its own FD and doesn't want to have it closed */
1241                         if (errno != EBADF)
1242                                 goto finish;
1243                 }
1244         }
1245
1246         r = 0;
1247
1248 finish:
1249         closedir(d);
1250         return r;
1251 }
1252
1253 bool chars_intersect(const char *a, const char *b) {
1254         const char *p;
1255
1256         /* Returns true if any of the chars in a are in b. */
1257         for (p = a; *p; p++)
1258                 if (strchr(b, *p))
1259                         return true;
1260
1261         return false;
1262 }
1263
1264 char *format_timestamp(char *buf, size_t l, usec_t t) {
1265         struct tm tm;
1266         time_t sec;
1267
1268         assert(buf);
1269         assert(l > 0);
1270
1271         if (t <= 0)
1272                 return NULL;
1273
1274         sec = (time_t) t / USEC_PER_SEC;
1275
1276         if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0)
1277                 return NULL;
1278
1279         return buf;
1280 }
1281
1282 bool fstype_is_network(const char *fstype) {
1283         static const char * const table[] = {
1284                 "cifs",
1285                 "smbfs",
1286                 "ncpfs",
1287                 "nfs",
1288                 "nfs4"
1289         };
1290
1291         unsigned i;
1292
1293         for (i = 0; i < ELEMENTSOF(table); i++)
1294                 if (streq(table[i], fstype))
1295                         return true;
1296
1297         return false;
1298 }
1299
1300 int chvt(int vt) {
1301         int fd, r = 0;
1302
1303         if ((fd = open("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0)
1304                 return -errno;
1305
1306         if (vt < 0) {
1307                 int tiocl[2] = {
1308                         TIOCL_GETKMSGREDIRECT,
1309                         0
1310                 };
1311
1312                 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1313                         return -errno;
1314
1315                 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1316         }
1317
1318         if (ioctl(fd, VT_ACTIVATE, vt) < 0)
1319                 r = -errno;
1320
1321         close_nointr(r);
1322         return r;
1323 }
1324
1325 static const char *const ioprio_class_table[] = {
1326         [IOPRIO_CLASS_NONE] = "none",
1327         [IOPRIO_CLASS_RT] = "realtime",
1328         [IOPRIO_CLASS_BE] = "best-effort",
1329         [IOPRIO_CLASS_IDLE] = "idle"
1330 };
1331
1332 DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
1333
1334 static const char *const sigchld_code_table[] = {
1335         [CLD_EXITED] = "exited",
1336         [CLD_KILLED] = "killed",
1337         [CLD_DUMPED] = "dumped",
1338         [CLD_TRAPPED] = "trapped",
1339         [CLD_STOPPED] = "stopped",
1340         [CLD_CONTINUED] = "continued",
1341 };
1342
1343 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
1344
1345 static const char *const log_facility_table[LOG_NFACILITIES] = {
1346         [LOG_FAC(LOG_KERN)] = "kern",
1347         [LOG_FAC(LOG_USER)] = "user",
1348         [LOG_FAC(LOG_MAIL)] = "mail",
1349         [LOG_FAC(LOG_DAEMON)] = "daemon",
1350         [LOG_FAC(LOG_AUTH)] = "auth",
1351         [LOG_FAC(LOG_SYSLOG)] = "syslog",
1352         [LOG_FAC(LOG_LPR)] = "lpr",
1353         [LOG_FAC(LOG_NEWS)] = "news",
1354         [LOG_FAC(LOG_UUCP)] = "uucp",
1355         [LOG_FAC(LOG_CRON)] = "cron",
1356         [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
1357         [LOG_FAC(LOG_FTP)] = "ftp",
1358         [LOG_FAC(LOG_LOCAL0)] = "local0",
1359         [LOG_FAC(LOG_LOCAL1)] = "local1",
1360         [LOG_FAC(LOG_LOCAL2)] = "local2",
1361         [LOG_FAC(LOG_LOCAL3)] = "local3",
1362         [LOG_FAC(LOG_LOCAL4)] = "local4",
1363         [LOG_FAC(LOG_LOCAL5)] = "local5",
1364         [LOG_FAC(LOG_LOCAL6)] = "local6",
1365         [LOG_FAC(LOG_LOCAL7)] = "local7"
1366 };
1367
1368 DEFINE_STRING_TABLE_LOOKUP(log_facility, int);
1369
1370 static const char *const log_level_table[] = {
1371         [LOG_EMERG] = "emerg",
1372         [LOG_ALERT] = "alert",
1373         [LOG_CRIT] = "crit",
1374         [LOG_ERR] = "err",
1375         [LOG_WARNING] = "warning",
1376         [LOG_NOTICE] = "notice",
1377         [LOG_INFO] = "info",
1378         [LOG_DEBUG] = "debug"
1379 };
1380
1381 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
1382
1383 static const char* const sched_policy_table[] = {
1384         [SCHED_OTHER] = "other",
1385         [SCHED_BATCH] = "batch",
1386         [SCHED_IDLE] = "idle",
1387         [SCHED_FIFO] = "fifo",
1388         [SCHED_RR] = "rr"
1389 };
1390
1391 DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
1392
1393 static const char* const rlimit_table[] = {
1394         [RLIMIT_CPU] = "LimitCPU",
1395         [RLIMIT_FSIZE] = "LimitFSIZE",
1396         [RLIMIT_DATA] = "LimitDATA",
1397         [RLIMIT_STACK] = "LimitSTACK",
1398         [RLIMIT_CORE] = "LimitCORE",
1399         [RLIMIT_RSS] = "LimitRSS",
1400         [RLIMIT_NOFILE] = "LimitNOFILE",
1401         [RLIMIT_AS] = "LimitAS",
1402         [RLIMIT_NPROC] = "LimitNPROC",
1403         [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
1404         [RLIMIT_LOCKS] = "LimitLOCKS",
1405         [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
1406         [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
1407         [RLIMIT_NICE] = "LimitNICE",
1408         [RLIMIT_RTPRIO] = "LimitRTPRIO",
1409         [RLIMIT_RTTIME] = "LimitRTTIME"
1410 };
1411
1412 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);