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