]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/util.c
util-lib: introduce dirent-util.[ch] for directory entry calls
[thirdparty/systemd.git] / src / basic / 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 <ctype.h>
23 #include <dirent.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <glob.h>
27 #include <grp.h>
28 #include <langinfo.h>
29 #include <libintl.h>
30 #include <limits.h>
31 #include <linux/magic.h>
32 #include <linux/oom.h>
33 #include <linux/sched.h>
34 #include <locale.h>
35 #include <poll.h>
36 #include <pwd.h>
37 #include <sched.h>
38 #include <signal.h>
39 #include <stdarg.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <sys/file.h>
44 #include <sys/ioctl.h>
45 #include <sys/mman.h>
46 #include <sys/mount.h>
47 #include <sys/personality.h>
48 #include <sys/prctl.h>
49 #include <sys/stat.h>
50 #include <sys/statvfs.h>
51 #include <sys/time.h>
52 #include <sys/types.h>
53 #include <sys/utsname.h>
54 #include <sys/vfs.h>
55 #include <sys/wait.h>
56 #include <sys/xattr.h>
57 #include <syslog.h>
58 #include <unistd.h>
59
60 /* When we include libgen.h because we need dirname() we immediately
61 * undefine basename() since libgen.h defines it as a macro to the
62 * POSIX version which is really broken. We prefer GNU basename(). */
63 #include <libgen.h>
64 #undef basename
65
66 #ifdef HAVE_SYS_AUXV_H
67 #include <sys/auxv.h>
68 #endif
69
70 /* We include linux/fs.h as last of the system headers, as it
71 * otherwise conflicts with sys/mount.h. Yay, Linux is great! */
72 #include <linux/fs.h>
73
74 #include "build.h"
75 #include "def.h"
76 #include "device-nodes.h"
77 #include "env-util.h"
78 #include "escape.h"
79 #include "exit-status.h"
80 #include "fd-util.h"
81 #include "fileio.h"
82 #include "formats-util.h"
83 #include "gunicode.h"
84 #include "hashmap.h"
85 #include "hostname-util.h"
86 #include "ioprio.h"
87 #include "log.h"
88 #include "macro.h"
89 #include "missing.h"
90 #include "mkdir.h"
91 #include "hexdecoct.h"
92 #include "parse-util.h"
93 #include "path-util.h"
94 #include "process-util.h"
95 #include "random-util.h"
96 #include "signal-util.h"
97 #include "sparse-endian.h"
98 #include "string-util.h"
99 #include "strv.h"
100 #include "terminal-util.h"
101 #include "user-util.h"
102 #include "utf8.h"
103 #include "util.h"
104 #include "virt.h"
105 #include "dirent-util.h"
106
107 /* Put this test here for a lack of better place */
108 assert_cc(EAGAIN == EWOULDBLOCK);
109
110 int saved_argc = 0;
111 char **saved_argv = NULL;
112
113 size_t page_size(void) {
114 static thread_local size_t pgsz = 0;
115 long r;
116
117 if (_likely_(pgsz > 0))
118 return pgsz;
119
120 r = sysconf(_SC_PAGESIZE);
121 assert(r > 0);
122
123 pgsz = (size_t) r;
124 return pgsz;
125 }
126
127 int unlink_noerrno(const char *path) {
128 PROTECT_ERRNO;
129 int r;
130
131 r = unlink(path);
132 if (r < 0)
133 return -errno;
134
135 return 0;
136 }
137
138 int fchmod_umask(int fd, mode_t m) {
139 mode_t u;
140 int r;
141
142 u = umask(0777);
143 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
144 umask(u);
145
146 return r;
147 }
148
149 int readlinkat_malloc(int fd, const char *p, char **ret) {
150 size_t l = 100;
151 int r;
152
153 assert(p);
154 assert(ret);
155
156 for (;;) {
157 char *c;
158 ssize_t n;
159
160 c = new(char, l);
161 if (!c)
162 return -ENOMEM;
163
164 n = readlinkat(fd, p, c, l-1);
165 if (n < 0) {
166 r = -errno;
167 free(c);
168 return r;
169 }
170
171 if ((size_t) n < l-1) {
172 c[n] = 0;
173 *ret = c;
174 return 0;
175 }
176
177 free(c);
178 l *= 2;
179 }
180 }
181
182 int readlink_malloc(const char *p, char **ret) {
183 return readlinkat_malloc(AT_FDCWD, p, ret);
184 }
185
186 int readlink_value(const char *p, char **ret) {
187 _cleanup_free_ char *link = NULL;
188 char *value;
189 int r;
190
191 r = readlink_malloc(p, &link);
192 if (r < 0)
193 return r;
194
195 value = basename(link);
196 if (!value)
197 return -ENOENT;
198
199 value = strdup(value);
200 if (!value)
201 return -ENOMEM;
202
203 *ret = value;
204
205 return 0;
206 }
207
208 int readlink_and_make_absolute(const char *p, char **r) {
209 _cleanup_free_ char *target = NULL;
210 char *k;
211 int j;
212
213 assert(p);
214 assert(r);
215
216 j = readlink_malloc(p, &target);
217 if (j < 0)
218 return j;
219
220 k = file_in_same_dir(p, target);
221 if (!k)
222 return -ENOMEM;
223
224 *r = k;
225 return 0;
226 }
227
228 int readlink_and_canonicalize(const char *p, char **r) {
229 char *t, *s;
230 int j;
231
232 assert(p);
233 assert(r);
234
235 j = readlink_and_make_absolute(p, &t);
236 if (j < 0)
237 return j;
238
239 s = canonicalize_file_name(t);
240 if (s) {
241 free(t);
242 *r = s;
243 } else
244 *r = t;
245
246 path_kill_slashes(*r);
247
248 return 0;
249 }
250
251 int rmdir_parents(const char *path, const char *stop) {
252 size_t l;
253 int r = 0;
254
255 assert(path);
256 assert(stop);
257
258 l = strlen(path);
259
260 /* Skip trailing slashes */
261 while (l > 0 && path[l-1] == '/')
262 l--;
263
264 while (l > 0) {
265 char *t;
266
267 /* Skip last component */
268 while (l > 0 && path[l-1] != '/')
269 l--;
270
271 /* Skip trailing slashes */
272 while (l > 0 && path[l-1] == '/')
273 l--;
274
275 if (l <= 0)
276 break;
277
278 if (!(t = strndup(path, l)))
279 return -ENOMEM;
280
281 if (path_startswith(stop, t)) {
282 free(t);
283 return 0;
284 }
285
286 r = rmdir(t);
287 free(t);
288
289 if (r < 0)
290 if (errno != ENOENT)
291 return -errno;
292 }
293
294 return 0;
295 }
296
297 bool fstype_is_network(const char *fstype) {
298 static const char table[] =
299 "afs\0"
300 "cifs\0"
301 "smbfs\0"
302 "sshfs\0"
303 "ncpfs\0"
304 "ncp\0"
305 "nfs\0"
306 "nfs4\0"
307 "gfs\0"
308 "gfs2\0"
309 "glusterfs\0";
310
311 const char *x;
312
313 x = startswith(fstype, "fuse.");
314 if (x)
315 fstype = x;
316
317 return nulstr_contains(table, fstype);
318 }
319
320 int dir_is_empty(const char *path) {
321 _cleanup_closedir_ DIR *d;
322 struct dirent *de;
323
324 d = opendir(path);
325 if (!d)
326 return -errno;
327
328 FOREACH_DIRENT(de, d, return -errno)
329 return 0;
330
331 return 1;
332 }
333
334 void rename_process(const char name[8]) {
335 assert(name);
336
337 /* This is a like a poor man's setproctitle(). It changes the
338 * comm field, argv[0], and also the glibc's internally used
339 * name of the process. For the first one a limit of 16 chars
340 * applies, to the second one usually one of 10 (i.e. length
341 * of "/sbin/init"), to the third one one of 7 (i.e. length of
342 * "systemd"). If you pass a longer string it will be
343 * truncated */
344
345 prctl(PR_SET_NAME, name);
346
347 if (program_invocation_name)
348 strncpy(program_invocation_name, name, strlen(program_invocation_name));
349
350 if (saved_argc > 0) {
351 int i;
352
353 if (saved_argv[0])
354 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
355
356 for (i = 1; i < saved_argc; i++) {
357 if (!saved_argv[i])
358 break;
359
360 memzero(saved_argv[i], strlen(saved_argv[i]));
361 }
362 }
363 }
364
365 bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
366 assert(s);
367 assert_cc(sizeof(statfs_f_type_t) >= sizeof(s->f_type));
368
369 return F_TYPE_EQUAL(s->f_type, magic_value);
370 }
371
372 int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
373 struct statfs s;
374
375 if (fstatfs(fd, &s) < 0)
376 return -errno;
377
378 return is_fs_type(&s, magic_value);
379 }
380
381 int path_check_fstype(const char *path, statfs_f_type_t magic_value) {
382 _cleanup_close_ int fd = -1;
383
384 fd = open(path, O_RDONLY);
385 if (fd < 0)
386 return -errno;
387
388 return fd_check_fstype(fd, magic_value);
389 }
390
391 bool is_temporary_fs(const struct statfs *s) {
392 return is_fs_type(s, TMPFS_MAGIC) ||
393 is_fs_type(s, RAMFS_MAGIC);
394 }
395
396 int fd_is_temporary_fs(int fd) {
397 struct statfs s;
398
399 if (fstatfs(fd, &s) < 0)
400 return -errno;
401
402 return is_temporary_fs(&s);
403 }
404
405 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
406 assert(path);
407
408 /* Under the assumption that we are running privileged we
409 * first change the access mode and only then hand out
410 * ownership to avoid a window where access is too open. */
411
412 if (mode != MODE_INVALID)
413 if (chmod(path, mode) < 0)
414 return -errno;
415
416 if (uid != UID_INVALID || gid != GID_INVALID)
417 if (chown(path, uid, gid) < 0)
418 return -errno;
419
420 return 0;
421 }
422
423 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
424 assert(fd >= 0);
425
426 /* Under the assumption that we are running privileged we
427 * first change the access mode and only then hand out
428 * ownership to avoid a window where access is too open. */
429
430 if (mode != MODE_INVALID)
431 if (fchmod(fd, mode) < 0)
432 return -errno;
433
434 if (uid != UID_INVALID || gid != GID_INVALID)
435 if (fchown(fd, uid, gid) < 0)
436 return -errno;
437
438 return 0;
439 }
440
441 int files_same(const char *filea, const char *fileb) {
442 struct stat a, b;
443
444 if (stat(filea, &a) < 0)
445 return -errno;
446
447 if (stat(fileb, &b) < 0)
448 return -errno;
449
450 return a.st_dev == b.st_dev &&
451 a.st_ino == b.st_ino;
452 }
453
454 int running_in_chroot(void) {
455 int ret;
456
457 ret = files_same("/proc/1/root", "/");
458 if (ret < 0)
459 return ret;
460
461 return ret == 0;
462 }
463
464 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
465 _cleanup_close_ int fd;
466 int r;
467
468 assert(path);
469
470 if (parents)
471 mkdir_parents(path, 0755);
472
473 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
474 if (fd < 0)
475 return -errno;
476
477 if (mode > 0) {
478 r = fchmod(fd, mode);
479 if (r < 0)
480 return -errno;
481 }
482
483 if (uid != UID_INVALID || gid != GID_INVALID) {
484 r = fchown(fd, uid, gid);
485 if (r < 0)
486 return -errno;
487 }
488
489 if (stamp != USEC_INFINITY) {
490 struct timespec ts[2];
491
492 timespec_store(&ts[0], stamp);
493 ts[1] = ts[0];
494 r = futimens(fd, ts);
495 } else
496 r = futimens(fd, NULL);
497 if (r < 0)
498 return -errno;
499
500 return 0;
501 }
502
503 int touch(const char *path) {
504 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
505 }
506
507 noreturn void freeze(void) {
508
509 /* Make sure nobody waits for us on a socket anymore */
510 close_all_fds(NULL, 0);
511
512 sync();
513
514 for (;;)
515 pause();
516 }
517
518 bool null_or_empty(struct stat *st) {
519 assert(st);
520
521 if (S_ISREG(st->st_mode) && st->st_size <= 0)
522 return true;
523
524 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
525 return true;
526
527 return false;
528 }
529
530 int null_or_empty_path(const char *fn) {
531 struct stat st;
532
533 assert(fn);
534
535 if (stat(fn, &st) < 0)
536 return -errno;
537
538 return null_or_empty(&st);
539 }
540
541 int null_or_empty_fd(int fd) {
542 struct stat st;
543
544 assert(fd >= 0);
545
546 if (fstat(fd, &st) < 0)
547 return -errno;
548
549 return null_or_empty(&st);
550 }
551
552 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
553 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
554 _cleanup_set_free_free_ Set *seen = NULL;
555 char **directory;
556
557 /* We fork this all off from a child process so that we can
558 * somewhat cleanly make use of SIGALRM to set a time limit */
559
560 (void) reset_all_signal_handlers();
561 (void) reset_signal_mask();
562
563 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
564
565 pids = hashmap_new(NULL);
566 if (!pids)
567 return log_oom();
568
569 seen = set_new(&string_hash_ops);
570 if (!seen)
571 return log_oom();
572
573 STRV_FOREACH(directory, directories) {
574 _cleanup_closedir_ DIR *d;
575 struct dirent *de;
576
577 d = opendir(*directory);
578 if (!d) {
579 if (errno == ENOENT)
580 continue;
581
582 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
583 }
584
585 FOREACH_DIRENT(de, d, break) {
586 _cleanup_free_ char *path = NULL;
587 pid_t pid;
588 int r;
589
590 if (!dirent_is_file(de))
591 continue;
592
593 if (set_contains(seen, de->d_name)) {
594 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
595 continue;
596 }
597
598 r = set_put_strdup(seen, de->d_name);
599 if (r < 0)
600 return log_oom();
601
602 path = strjoin(*directory, "/", de->d_name, NULL);
603 if (!path)
604 return log_oom();
605
606 if (null_or_empty_path(path)) {
607 log_debug("%s is empty (a mask).", path);
608 continue;
609 }
610
611 pid = fork();
612 if (pid < 0) {
613 log_error_errno(errno, "Failed to fork: %m");
614 continue;
615 } else if (pid == 0) {
616 char *_argv[2];
617
618 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
619
620 if (!argv) {
621 _argv[0] = path;
622 _argv[1] = NULL;
623 argv = _argv;
624 } else
625 argv[0] = path;
626
627 execv(path, argv);
628 return log_error_errno(errno, "Failed to execute %s: %m", path);
629 }
630
631 log_debug("Spawned %s as " PID_FMT ".", path, pid);
632
633 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
634 if (r < 0)
635 return log_oom();
636 path = NULL;
637 }
638 }
639
640 /* Abort execution of this process after the timout. We simply
641 * rely on SIGALRM as default action terminating the process,
642 * and turn on alarm(). */
643
644 if (timeout != USEC_INFINITY)
645 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
646
647 while (!hashmap_isempty(pids)) {
648 _cleanup_free_ char *path = NULL;
649 pid_t pid;
650
651 pid = PTR_TO_UINT(hashmap_first_key(pids));
652 assert(pid > 0);
653
654 path = hashmap_remove(pids, UINT_TO_PTR(pid));
655 assert(path);
656
657 wait_for_terminate_and_warn(path, pid, true);
658 }
659
660 return 0;
661 }
662
663 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
664 pid_t executor_pid;
665 int r;
666 char *name;
667 char **dirs = (char**) directories;
668
669 assert(!strv_isempty(dirs));
670
671 name = basename(dirs[0]);
672 assert(!isempty(name));
673
674 /* Executes all binaries in the directories in parallel and waits
675 * for them to finish. Optionally a timeout is applied. If a file
676 * with the same name exists in more than one directory, the
677 * earliest one wins. */
678
679 executor_pid = fork();
680 if (executor_pid < 0) {
681 log_error_errno(errno, "Failed to fork: %m");
682 return;
683
684 } else if (executor_pid == 0) {
685 r = do_execute(dirs, timeout, argv);
686 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
687 }
688
689 wait_for_terminate_and_warn(name, executor_pid, true);
690 }
691
692 bool plymouth_running(void) {
693 return access("/run/plymouth/pid", F_OK) >= 0;
694 }
695
696 int symlink_atomic(const char *from, const char *to) {
697 _cleanup_free_ char *t = NULL;
698 int r;
699
700 assert(from);
701 assert(to);
702
703 r = tempfn_random(to, NULL, &t);
704 if (r < 0)
705 return r;
706
707 if (symlink(from, t) < 0)
708 return -errno;
709
710 if (rename(t, to) < 0) {
711 unlink_noerrno(t);
712 return -errno;
713 }
714
715 return 0;
716 }
717
718 int symlink_idempotent(const char *from, const char *to) {
719 _cleanup_free_ char *p = NULL;
720 int r;
721
722 assert(from);
723 assert(to);
724
725 if (symlink(from, to) < 0) {
726 if (errno != EEXIST)
727 return -errno;
728
729 r = readlink_malloc(to, &p);
730 if (r < 0)
731 return r;
732
733 if (!streq(p, from))
734 return -EINVAL;
735 }
736
737 return 0;
738 }
739
740 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
741 _cleanup_free_ char *t = NULL;
742 int r;
743
744 assert(path);
745
746 r = tempfn_random(path, NULL, &t);
747 if (r < 0)
748 return r;
749
750 if (mknod(t, mode, dev) < 0)
751 return -errno;
752
753 if (rename(t, path) < 0) {
754 unlink_noerrno(t);
755 return -errno;
756 }
757
758 return 0;
759 }
760
761 int mkfifo_atomic(const char *path, mode_t mode) {
762 _cleanup_free_ char *t = NULL;
763 int r;
764
765 assert(path);
766
767 r = tempfn_random(path, NULL, &t);
768 if (r < 0)
769 return r;
770
771 if (mkfifo(t, mode) < 0)
772 return -errno;
773
774 if (rename(t, path) < 0) {
775 unlink_noerrno(t);
776 return -errno;
777 }
778
779 return 0;
780 }
781
782 bool display_is_local(const char *display) {
783 assert(display);
784
785 return
786 display[0] == ':' &&
787 display[1] >= '0' &&
788 display[1] <= '9';
789 }
790
791 int socket_from_display(const char *display, char **path) {
792 size_t k;
793 char *f, *c;
794
795 assert(display);
796 assert(path);
797
798 if (!display_is_local(display))
799 return -EINVAL;
800
801 k = strspn(display+1, "0123456789");
802
803 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
804 if (!f)
805 return -ENOMEM;
806
807 c = stpcpy(f, "/tmp/.X11-unix/X");
808 memcpy(c, display+1, k);
809 c[k] = 0;
810
811 *path = f;
812
813 return 0;
814 }
815
816 int glob_exists(const char *path) {
817 _cleanup_globfree_ glob_t g = {};
818 int k;
819
820 assert(path);
821
822 errno = 0;
823 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
824
825 if (k == GLOB_NOMATCH)
826 return 0;
827 else if (k == GLOB_NOSPACE)
828 return -ENOMEM;
829 else if (k == 0)
830 return !strv_isempty(g.gl_pathv);
831 else
832 return errno ? -errno : -EIO;
833 }
834
835 int glob_extend(char ***strv, const char *path) {
836 _cleanup_globfree_ glob_t g = {};
837 int k;
838 char **p;
839
840 errno = 0;
841 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
842
843 if (k == GLOB_NOMATCH)
844 return -ENOENT;
845 else if (k == GLOB_NOSPACE)
846 return -ENOMEM;
847 else if (k != 0 || strv_isempty(g.gl_pathv))
848 return errno ? -errno : -EIO;
849
850 STRV_FOREACH(p, g.gl_pathv) {
851 k = strv_extend(strv, *p);
852 if (k < 0)
853 break;
854 }
855
856 return k;
857 }
858
859 int get_files_in_directory(const char *path, char ***list) {
860 _cleanup_closedir_ DIR *d = NULL;
861 size_t bufsize = 0, n = 0;
862 _cleanup_strv_free_ char **l = NULL;
863
864 assert(path);
865
866 /* Returns all files in a directory in *list, and the number
867 * of files as return value. If list is NULL returns only the
868 * number. */
869
870 d = opendir(path);
871 if (!d)
872 return -errno;
873
874 for (;;) {
875 struct dirent *de;
876
877 errno = 0;
878 de = readdir(d);
879 if (!de && errno != 0)
880 return -errno;
881 if (!de)
882 break;
883
884 dirent_ensure_type(d, de);
885
886 if (!dirent_is_file(de))
887 continue;
888
889 if (list) {
890 /* one extra slot is needed for the terminating NULL */
891 if (!GREEDY_REALLOC(l, bufsize, n + 2))
892 return -ENOMEM;
893
894 l[n] = strdup(de->d_name);
895 if (!l[n])
896 return -ENOMEM;
897
898 l[++n] = NULL;
899 } else
900 n++;
901 }
902
903 if (list) {
904 *list = l;
905 l = NULL; /* avoid freeing */
906 }
907
908 return n;
909 }
910
911 bool is_main_thread(void) {
912 static thread_local int cached = 0;
913
914 if (_unlikely_(cached == 0))
915 cached = getpid() == gettid() ? 1 : -1;
916
917 return cached > 0;
918 }
919
920 int block_get_whole_disk(dev_t d, dev_t *ret) {
921 char *p, *s;
922 int r;
923 unsigned n, m;
924
925 assert(ret);
926
927 /* If it has a queue this is good enough for us */
928 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
929 return -ENOMEM;
930
931 r = access(p, F_OK);
932 free(p);
933
934 if (r >= 0) {
935 *ret = d;
936 return 0;
937 }
938
939 /* If it is a partition find the originating device */
940 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
941 return -ENOMEM;
942
943 r = access(p, F_OK);
944 free(p);
945
946 if (r < 0)
947 return -ENOENT;
948
949 /* Get parent dev_t */
950 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
951 return -ENOMEM;
952
953 r = read_one_line_file(p, &s);
954 free(p);
955
956 if (r < 0)
957 return r;
958
959 r = sscanf(s, "%u:%u", &m, &n);
960 free(s);
961
962 if (r != 2)
963 return -EINVAL;
964
965 /* Only return this if it is really good enough for us. */
966 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
967 return -ENOMEM;
968
969 r = access(p, F_OK);
970 free(p);
971
972 if (r >= 0) {
973 *ret = makedev(m, n);
974 return 0;
975 }
976
977 return -ENOENT;
978 }
979
980 static const char *const ioprio_class_table[] = {
981 [IOPRIO_CLASS_NONE] = "none",
982 [IOPRIO_CLASS_RT] = "realtime",
983 [IOPRIO_CLASS_BE] = "best-effort",
984 [IOPRIO_CLASS_IDLE] = "idle"
985 };
986
987 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
988
989 static const char *const sigchld_code_table[] = {
990 [CLD_EXITED] = "exited",
991 [CLD_KILLED] = "killed",
992 [CLD_DUMPED] = "dumped",
993 [CLD_TRAPPED] = "trapped",
994 [CLD_STOPPED] = "stopped",
995 [CLD_CONTINUED] = "continued",
996 };
997
998 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
999
1000 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
1001 [LOG_FAC(LOG_KERN)] = "kern",
1002 [LOG_FAC(LOG_USER)] = "user",
1003 [LOG_FAC(LOG_MAIL)] = "mail",
1004 [LOG_FAC(LOG_DAEMON)] = "daemon",
1005 [LOG_FAC(LOG_AUTH)] = "auth",
1006 [LOG_FAC(LOG_SYSLOG)] = "syslog",
1007 [LOG_FAC(LOG_LPR)] = "lpr",
1008 [LOG_FAC(LOG_NEWS)] = "news",
1009 [LOG_FAC(LOG_UUCP)] = "uucp",
1010 [LOG_FAC(LOG_CRON)] = "cron",
1011 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
1012 [LOG_FAC(LOG_FTP)] = "ftp",
1013 [LOG_FAC(LOG_LOCAL0)] = "local0",
1014 [LOG_FAC(LOG_LOCAL1)] = "local1",
1015 [LOG_FAC(LOG_LOCAL2)] = "local2",
1016 [LOG_FAC(LOG_LOCAL3)] = "local3",
1017 [LOG_FAC(LOG_LOCAL4)] = "local4",
1018 [LOG_FAC(LOG_LOCAL5)] = "local5",
1019 [LOG_FAC(LOG_LOCAL6)] = "local6",
1020 [LOG_FAC(LOG_LOCAL7)] = "local7"
1021 };
1022
1023 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
1024
1025 bool log_facility_unshifted_is_valid(int facility) {
1026 return facility >= 0 && facility <= LOG_FAC(~0);
1027 }
1028
1029 static const char *const log_level_table[] = {
1030 [LOG_EMERG] = "emerg",
1031 [LOG_ALERT] = "alert",
1032 [LOG_CRIT] = "crit",
1033 [LOG_ERR] = "err",
1034 [LOG_WARNING] = "warning",
1035 [LOG_NOTICE] = "notice",
1036 [LOG_INFO] = "info",
1037 [LOG_DEBUG] = "debug"
1038 };
1039
1040 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
1041
1042 bool log_level_is_valid(int level) {
1043 return level >= 0 && level <= LOG_DEBUG;
1044 }
1045
1046 static const char* const sched_policy_table[] = {
1047 [SCHED_OTHER] = "other",
1048 [SCHED_BATCH] = "batch",
1049 [SCHED_IDLE] = "idle",
1050 [SCHED_FIFO] = "fifo",
1051 [SCHED_RR] = "rr"
1052 };
1053
1054 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
1055
1056 bool kexec_loaded(void) {
1057 bool loaded = false;
1058 char *s;
1059
1060 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
1061 if (s[0] == '1')
1062 loaded = true;
1063 free(s);
1064 }
1065 return loaded;
1066 }
1067
1068 int prot_from_flags(int flags) {
1069
1070 switch (flags & O_ACCMODE) {
1071
1072 case O_RDONLY:
1073 return PROT_READ;
1074
1075 case O_WRONLY:
1076 return PROT_WRITE;
1077
1078 case O_RDWR:
1079 return PROT_READ|PROT_WRITE;
1080
1081 default:
1082 return -EINVAL;
1083 }
1084 }
1085
1086 void* memdup(const void *p, size_t l) {
1087 void *r;
1088
1089 assert(p);
1090
1091 r = malloc(l);
1092 if (!r)
1093 return NULL;
1094
1095 memcpy(r, p, l);
1096 return r;
1097 }
1098
1099 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
1100 bool stdout_is_tty, stderr_is_tty;
1101 pid_t parent_pid, agent_pid;
1102 sigset_t ss, saved_ss;
1103 unsigned n, i;
1104 va_list ap;
1105 char **l;
1106
1107 assert(pid);
1108 assert(path);
1109
1110 /* Spawns a temporary TTY agent, making sure it goes away when
1111 * we go away */
1112
1113 parent_pid = getpid();
1114
1115 /* First we temporarily block all signals, so that the new
1116 * child has them blocked initially. This way, we can be sure
1117 * that SIGTERMs are not lost we might send to the agent. */
1118 assert_se(sigfillset(&ss) >= 0);
1119 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
1120
1121 agent_pid = fork();
1122 if (agent_pid < 0) {
1123 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
1124 return -errno;
1125 }
1126
1127 if (agent_pid != 0) {
1128 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
1129 *pid = agent_pid;
1130 return 0;
1131 }
1132
1133 /* In the child:
1134 *
1135 * Make sure the agent goes away when the parent dies */
1136 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
1137 _exit(EXIT_FAILURE);
1138
1139 /* Make sure we actually can kill the agent, if we need to, in
1140 * case somebody invoked us from a shell script that trapped
1141 * SIGTERM or so... */
1142 (void) reset_all_signal_handlers();
1143 (void) reset_signal_mask();
1144
1145 /* Check whether our parent died before we were able
1146 * to set the death signal and unblock the signals */
1147 if (getppid() != parent_pid)
1148 _exit(EXIT_SUCCESS);
1149
1150 /* Don't leak fds to the agent */
1151 close_all_fds(except, n_except);
1152
1153 stdout_is_tty = isatty(STDOUT_FILENO);
1154 stderr_is_tty = isatty(STDERR_FILENO);
1155
1156 if (!stdout_is_tty || !stderr_is_tty) {
1157 int fd;
1158
1159 /* Detach from stdout/stderr. and reopen
1160 * /dev/tty for them. This is important to
1161 * ensure that when systemctl is started via
1162 * popen() or a similar call that expects to
1163 * read EOF we actually do generate EOF and
1164 * not delay this indefinitely by because we
1165 * keep an unused copy of stdin around. */
1166 fd = open("/dev/tty", O_WRONLY);
1167 if (fd < 0) {
1168 log_error_errno(errno, "Failed to open /dev/tty: %m");
1169 _exit(EXIT_FAILURE);
1170 }
1171
1172 if (!stdout_is_tty)
1173 dup2(fd, STDOUT_FILENO);
1174
1175 if (!stderr_is_tty)
1176 dup2(fd, STDERR_FILENO);
1177
1178 if (fd > 2)
1179 close(fd);
1180 }
1181
1182 /* Count arguments */
1183 va_start(ap, path);
1184 for (n = 0; va_arg(ap, char*); n++)
1185 ;
1186 va_end(ap);
1187
1188 /* Allocate strv */
1189 l = alloca(sizeof(char *) * (n + 1));
1190
1191 /* Fill in arguments */
1192 va_start(ap, path);
1193 for (i = 0; i <= n; i++)
1194 l[i] = va_arg(ap, char*);
1195 va_end(ap);
1196
1197 execv(path, l);
1198 _exit(EXIT_FAILURE);
1199 }
1200
1201 bool http_etag_is_valid(const char *etag) {
1202 if (isempty(etag))
1203 return false;
1204
1205 if (!endswith(etag, "\""))
1206 return false;
1207
1208 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
1209 return false;
1210
1211 return true;
1212 }
1213
1214 bool http_url_is_valid(const char *url) {
1215 const char *p;
1216
1217 if (isempty(url))
1218 return false;
1219
1220 p = startswith(url, "http://");
1221 if (!p)
1222 p = startswith(url, "https://");
1223 if (!p)
1224 return false;
1225
1226 if (isempty(p))
1227 return false;
1228
1229 return ascii_is_valid(p);
1230 }
1231
1232 bool documentation_url_is_valid(const char *url) {
1233 const char *p;
1234
1235 if (isempty(url))
1236 return false;
1237
1238 if (http_url_is_valid(url))
1239 return true;
1240
1241 p = startswith(url, "file:/");
1242 if (!p)
1243 p = startswith(url, "info:");
1244 if (!p)
1245 p = startswith(url, "man:");
1246
1247 if (isempty(p))
1248 return false;
1249
1250 return ascii_is_valid(p);
1251 }
1252
1253 bool in_initrd(void) {
1254 static int saved = -1;
1255 struct statfs s;
1256
1257 if (saved >= 0)
1258 return saved;
1259
1260 /* We make two checks here:
1261 *
1262 * 1. the flag file /etc/initrd-release must exist
1263 * 2. the root file system must be a memory file system
1264 *
1265 * The second check is extra paranoia, since misdetecting an
1266 * initrd can have bad bad consequences due the initrd
1267 * emptying when transititioning to the main systemd.
1268 */
1269
1270 saved = access("/etc/initrd-release", F_OK) >= 0 &&
1271 statfs("/", &s) >= 0 &&
1272 is_temporary_fs(&s);
1273
1274 return saved;
1275 }
1276
1277 bool string_is_safe(const char *p) {
1278 const char *t;
1279
1280 if (!p)
1281 return false;
1282
1283 for (t = p; *t; t++) {
1284 if (*t > 0 && *t < ' ')
1285 return false;
1286
1287 if (strchr("\\\"\'\x7f", *t))
1288 return false;
1289 }
1290
1291 return true;
1292 }
1293
1294 /* hey glibc, APIs with callbacks without a user pointer are so useless */
1295 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
1296 int (*compar) (const void *, const void *, void *), void *arg) {
1297 size_t l, u, idx;
1298 const void *p;
1299 int comparison;
1300
1301 l = 0;
1302 u = nmemb;
1303 while (l < u) {
1304 idx = (l + u) / 2;
1305 p = (void *)(((const char *) base) + (idx * size));
1306 comparison = compar(key, p, arg);
1307 if (comparison < 0)
1308 u = idx;
1309 else if (comparison > 0)
1310 l = idx + 1;
1311 else
1312 return (void *)p;
1313 }
1314 return NULL;
1315 }
1316
1317 void init_gettext(void) {
1318 setlocale(LC_ALL, "");
1319 textdomain(GETTEXT_PACKAGE);
1320 }
1321
1322 bool is_locale_utf8(void) {
1323 const char *set;
1324 static int cached_answer = -1;
1325
1326 if (cached_answer >= 0)
1327 goto out;
1328
1329 if (!setlocale(LC_ALL, "")) {
1330 cached_answer = true;
1331 goto out;
1332 }
1333
1334 set = nl_langinfo(CODESET);
1335 if (!set) {
1336 cached_answer = true;
1337 goto out;
1338 }
1339
1340 if (streq(set, "UTF-8")) {
1341 cached_answer = true;
1342 goto out;
1343 }
1344
1345 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
1346 * unset and everything can do to UTF-8 nowadays. */
1347 set = setlocale(LC_CTYPE, NULL);
1348 if (!set) {
1349 cached_answer = true;
1350 goto out;
1351 }
1352
1353 /* Check result, but ignore the result if C was set
1354 * explicitly. */
1355 cached_answer =
1356 STR_IN_SET(set, "C", "POSIX") &&
1357 !getenv("LC_ALL") &&
1358 !getenv("LC_CTYPE") &&
1359 !getenv("LANG");
1360
1361 out:
1362 return (bool) cached_answer;
1363 }
1364
1365 const char *draw_special_char(DrawSpecialChar ch) {
1366 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
1367
1368 /* UTF-8 */ {
1369 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
1370 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
1371 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
1372 [DRAW_TREE_SPACE] = " ", /* */
1373 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
1374 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
1375 [DRAW_ARROW] = "\342\206\222", /* → */
1376 [DRAW_DASH] = "\342\200\223", /* – */
1377 },
1378
1379 /* ASCII fallback */ {
1380 [DRAW_TREE_VERTICAL] = "| ",
1381 [DRAW_TREE_BRANCH] = "|-",
1382 [DRAW_TREE_RIGHT] = "`-",
1383 [DRAW_TREE_SPACE] = " ",
1384 [DRAW_TRIANGULAR_BULLET] = ">",
1385 [DRAW_BLACK_CIRCLE] = "*",
1386 [DRAW_ARROW] = "->",
1387 [DRAW_DASH] = "-",
1388 }
1389 };
1390
1391 return draw_table[!is_locale_utf8()][ch];
1392 }
1393
1394 int on_ac_power(void) {
1395 bool found_offline = false, found_online = false;
1396 _cleanup_closedir_ DIR *d = NULL;
1397
1398 d = opendir("/sys/class/power_supply");
1399 if (!d)
1400 return errno == ENOENT ? true : -errno;
1401
1402 for (;;) {
1403 struct dirent *de;
1404 _cleanup_close_ int fd = -1, device = -1;
1405 char contents[6];
1406 ssize_t n;
1407
1408 errno = 0;
1409 de = readdir(d);
1410 if (!de && errno != 0)
1411 return -errno;
1412
1413 if (!de)
1414 break;
1415
1416 if (hidden_file(de->d_name))
1417 continue;
1418
1419 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
1420 if (device < 0) {
1421 if (errno == ENOENT || errno == ENOTDIR)
1422 continue;
1423
1424 return -errno;
1425 }
1426
1427 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1428 if (fd < 0) {
1429 if (errno == ENOENT)
1430 continue;
1431
1432 return -errno;
1433 }
1434
1435 n = read(fd, contents, sizeof(contents));
1436 if (n < 0)
1437 return -errno;
1438
1439 if (n != 6 || memcmp(contents, "Mains\n", 6))
1440 continue;
1441
1442 safe_close(fd);
1443 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1444 if (fd < 0) {
1445 if (errno == ENOENT)
1446 continue;
1447
1448 return -errno;
1449 }
1450
1451 n = read(fd, contents, sizeof(contents));
1452 if (n < 0)
1453 return -errno;
1454
1455 if (n != 2 || contents[1] != '\n')
1456 return -EIO;
1457
1458 if (contents[0] == '1') {
1459 found_online = true;
1460 break;
1461 } else if (contents[0] == '0')
1462 found_offline = true;
1463 else
1464 return -EIO;
1465 }
1466
1467 return found_online || !found_offline;
1468 }
1469
1470 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
1471 size_t a, newalloc;
1472 void *q;
1473
1474 assert(p);
1475 assert(allocated);
1476
1477 if (*allocated >= need)
1478 return *p;
1479
1480 newalloc = MAX(need * 2, 64u / size);
1481 a = newalloc * size;
1482
1483 /* check for overflows */
1484 if (a < size * need)
1485 return NULL;
1486
1487 q = realloc(*p, a);
1488 if (!q)
1489 return NULL;
1490
1491 *p = q;
1492 *allocated = newalloc;
1493 return q;
1494 }
1495
1496 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
1497 size_t prev;
1498 uint8_t *q;
1499
1500 assert(p);
1501 assert(allocated);
1502
1503 prev = *allocated;
1504
1505 q = greedy_realloc(p, allocated, need, size);
1506 if (!q)
1507 return NULL;
1508
1509 if (*allocated > prev)
1510 memzero(q + prev * size, (*allocated - prev) * size);
1511
1512 return q;
1513 }
1514
1515 bool id128_is_valid(const char *s) {
1516 size_t i, l;
1517
1518 l = strlen(s);
1519 if (l == 32) {
1520
1521 /* Simple formatted 128bit hex string */
1522
1523 for (i = 0; i < l; i++) {
1524 char c = s[i];
1525
1526 if (!(c >= '0' && c <= '9') &&
1527 !(c >= 'a' && c <= 'z') &&
1528 !(c >= 'A' && c <= 'Z'))
1529 return false;
1530 }
1531
1532 } else if (l == 36) {
1533
1534 /* Formatted UUID */
1535
1536 for (i = 0; i < l; i++) {
1537 char c = s[i];
1538
1539 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
1540 if (c != '-')
1541 return false;
1542 } else {
1543 if (!(c >= '0' && c <= '9') &&
1544 !(c >= 'a' && c <= 'z') &&
1545 !(c >= 'A' && c <= 'Z'))
1546 return false;
1547 }
1548 }
1549
1550 } else
1551 return false;
1552
1553 return true;
1554 }
1555
1556 int shall_restore_state(void) {
1557 _cleanup_free_ char *value = NULL;
1558 int r;
1559
1560 r = get_proc_cmdline_key("systemd.restore_state=", &value);
1561 if (r < 0)
1562 return r;
1563 if (r == 0)
1564 return true;
1565
1566 return parse_boolean(value) != 0;
1567 }
1568
1569 int proc_cmdline(char **ret) {
1570 assert(ret);
1571
1572 if (detect_container() > 0)
1573 return get_process_cmdline(1, 0, false, ret);
1574 else
1575 return read_one_line_file("/proc/cmdline", ret);
1576 }
1577
1578 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
1579 _cleanup_free_ char *line = NULL;
1580 const char *p;
1581 int r;
1582
1583 assert(parse_item);
1584
1585 r = proc_cmdline(&line);
1586 if (r < 0)
1587 return r;
1588
1589 p = line;
1590 for (;;) {
1591 _cleanup_free_ char *word = NULL;
1592 char *value = NULL;
1593
1594 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
1595 if (r < 0)
1596 return r;
1597 if (r == 0)
1598 break;
1599
1600 /* Filter out arguments that are intended only for the
1601 * initrd */
1602 if (!in_initrd() && startswith(word, "rd."))
1603 continue;
1604
1605 value = strchr(word, '=');
1606 if (value)
1607 *(value++) = 0;
1608
1609 r = parse_item(word, value);
1610 if (r < 0)
1611 return r;
1612 }
1613
1614 return 0;
1615 }
1616
1617 int get_proc_cmdline_key(const char *key, char **value) {
1618 _cleanup_free_ char *line = NULL, *ret = NULL;
1619 bool found = false;
1620 const char *p;
1621 int r;
1622
1623 assert(key);
1624
1625 r = proc_cmdline(&line);
1626 if (r < 0)
1627 return r;
1628
1629 p = line;
1630 for (;;) {
1631 _cleanup_free_ char *word = NULL;
1632 const char *e;
1633
1634 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
1635 if (r < 0)
1636 return r;
1637 if (r == 0)
1638 break;
1639
1640 /* Filter out arguments that are intended only for the
1641 * initrd */
1642 if (!in_initrd() && startswith(word, "rd."))
1643 continue;
1644
1645 if (value) {
1646 e = startswith(word, key);
1647 if (!e)
1648 continue;
1649
1650 r = free_and_strdup(&ret, e);
1651 if (r < 0)
1652 return r;
1653
1654 found = true;
1655 } else {
1656 if (streq(word, key))
1657 found = true;
1658 }
1659 }
1660
1661 if (value) {
1662 *value = ret;
1663 ret = NULL;
1664 }
1665
1666 return found;
1667
1668 }
1669
1670 int container_get_leader(const char *machine, pid_t *pid) {
1671 _cleanup_free_ char *s = NULL, *class = NULL;
1672 const char *p;
1673 pid_t leader;
1674 int r;
1675
1676 assert(machine);
1677 assert(pid);
1678
1679 if (!machine_name_is_valid(machine))
1680 return -EINVAL;
1681
1682 p = strjoina("/run/systemd/machines/", machine);
1683 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
1684 if (r == -ENOENT)
1685 return -EHOSTDOWN;
1686 if (r < 0)
1687 return r;
1688 if (!s)
1689 return -EIO;
1690
1691 if (!streq_ptr(class, "container"))
1692 return -EIO;
1693
1694 r = parse_pid(s, &leader);
1695 if (r < 0)
1696 return r;
1697 if (leader <= 1)
1698 return -EIO;
1699
1700 *pid = leader;
1701 return 0;
1702 }
1703
1704 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
1705 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
1706 int rfd = -1;
1707
1708 assert(pid >= 0);
1709
1710 if (mntns_fd) {
1711 const char *mntns;
1712
1713 mntns = procfs_file_alloca(pid, "ns/mnt");
1714 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
1715 if (mntnsfd < 0)
1716 return -errno;
1717 }
1718
1719 if (pidns_fd) {
1720 const char *pidns;
1721
1722 pidns = procfs_file_alloca(pid, "ns/pid");
1723 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
1724 if (pidnsfd < 0)
1725 return -errno;
1726 }
1727
1728 if (netns_fd) {
1729 const char *netns;
1730
1731 netns = procfs_file_alloca(pid, "ns/net");
1732 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
1733 if (netnsfd < 0)
1734 return -errno;
1735 }
1736
1737 if (userns_fd) {
1738 const char *userns;
1739
1740 userns = procfs_file_alloca(pid, "ns/user");
1741 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
1742 if (usernsfd < 0 && errno != ENOENT)
1743 return -errno;
1744 }
1745
1746 if (root_fd) {
1747 const char *root;
1748
1749 root = procfs_file_alloca(pid, "root");
1750 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
1751 if (rfd < 0)
1752 return -errno;
1753 }
1754
1755 if (pidns_fd)
1756 *pidns_fd = pidnsfd;
1757
1758 if (mntns_fd)
1759 *mntns_fd = mntnsfd;
1760
1761 if (netns_fd)
1762 *netns_fd = netnsfd;
1763
1764 if (userns_fd)
1765 *userns_fd = usernsfd;
1766
1767 if (root_fd)
1768 *root_fd = rfd;
1769
1770 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
1771
1772 return 0;
1773 }
1774
1775 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
1776 if (userns_fd >= 0) {
1777 /* Can't setns to your own userns, since then you could
1778 * escalate from non-root to root in your own namespace, so
1779 * check if namespaces equal before attempting to enter. */
1780 _cleanup_free_ char *userns_fd_path = NULL;
1781 int r;
1782 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
1783 return -ENOMEM;
1784
1785 r = files_same(userns_fd_path, "/proc/self/ns/user");
1786 if (r < 0)
1787 return r;
1788 if (r)
1789 userns_fd = -1;
1790 }
1791
1792 if (pidns_fd >= 0)
1793 if (setns(pidns_fd, CLONE_NEWPID) < 0)
1794 return -errno;
1795
1796 if (mntns_fd >= 0)
1797 if (setns(mntns_fd, CLONE_NEWNS) < 0)
1798 return -errno;
1799
1800 if (netns_fd >= 0)
1801 if (setns(netns_fd, CLONE_NEWNET) < 0)
1802 return -errno;
1803
1804 if (userns_fd >= 0)
1805 if (setns(userns_fd, CLONE_NEWUSER) < 0)
1806 return -errno;
1807
1808 if (root_fd >= 0) {
1809 if (fchdir(root_fd) < 0)
1810 return -errno;
1811
1812 if (chroot(".") < 0)
1813 return -errno;
1814 }
1815
1816 return reset_uid_gid();
1817 }
1818
1819 int fd_warn_permissions(const char *path, int fd) {
1820 struct stat st;
1821
1822 if (fstat(fd, &st) < 0)
1823 return -errno;
1824
1825 if (st.st_mode & 0111)
1826 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
1827
1828 if (st.st_mode & 0002)
1829 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
1830
1831 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
1832 log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
1833
1834 return 0;
1835 }
1836
1837 unsigned long personality_from_string(const char *p) {
1838
1839 /* Parse a personality specifier. We introduce our own
1840 * identifiers that indicate specific ABIs, rather than just
1841 * hints regarding the register size, since we want to keep
1842 * things open for multiple locally supported ABIs for the
1843 * same register size. We try to reuse the ABI identifiers
1844 * used by libseccomp. */
1845
1846 #if defined(__x86_64__)
1847
1848 if (streq(p, "x86"))
1849 return PER_LINUX32;
1850
1851 if (streq(p, "x86-64"))
1852 return PER_LINUX;
1853
1854 #elif defined(__i386__)
1855
1856 if (streq(p, "x86"))
1857 return PER_LINUX;
1858
1859 #elif defined(__s390x__)
1860
1861 if (streq(p, "s390"))
1862 return PER_LINUX32;
1863
1864 if (streq(p, "s390x"))
1865 return PER_LINUX;
1866
1867 #elif defined(__s390__)
1868
1869 if (streq(p, "s390"))
1870 return PER_LINUX;
1871 #endif
1872
1873 return PERSONALITY_INVALID;
1874 }
1875
1876 const char* personality_to_string(unsigned long p) {
1877
1878 #if defined(__x86_64__)
1879
1880 if (p == PER_LINUX32)
1881 return "x86";
1882
1883 if (p == PER_LINUX)
1884 return "x86-64";
1885
1886 #elif defined(__i386__)
1887
1888 if (p == PER_LINUX)
1889 return "x86";
1890
1891 #elif defined(__s390x__)
1892
1893 if (p == PER_LINUX)
1894 return "s390x";
1895
1896 if (p == PER_LINUX32)
1897 return "s390";
1898
1899 #elif defined(__s390__)
1900
1901 if (p == PER_LINUX)
1902 return "s390";
1903
1904 #endif
1905
1906 return NULL;
1907 }
1908
1909 uint64_t physical_memory(void) {
1910 long mem;
1911
1912 /* We return this as uint64_t in case we are running as 32bit
1913 * process on a 64bit kernel with huge amounts of memory */
1914
1915 mem = sysconf(_SC_PHYS_PAGES);
1916 assert(mem > 0);
1917
1918 return (uint64_t) mem * (uint64_t) page_size();
1919 }
1920
1921 int update_reboot_param_file(const char *param) {
1922 int r = 0;
1923
1924 if (param) {
1925 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
1926 if (r < 0)
1927 return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m");
1928 } else
1929 (void) unlink(REBOOT_PARAM_FILE);
1930
1931 return 0;
1932 }
1933
1934 int is_symlink(const char *path) {
1935 struct stat info;
1936
1937 if (lstat(path, &info) < 0)
1938 return -errno;
1939
1940 return !!S_ISLNK(info.st_mode);
1941 }
1942
1943 int is_dir(const char* path, bool follow) {
1944 struct stat st;
1945 int r;
1946
1947 if (follow)
1948 r = stat(path, &st);
1949 else
1950 r = lstat(path, &st);
1951 if (r < 0)
1952 return -errno;
1953
1954 return !!S_ISDIR(st.st_mode);
1955 }
1956
1957 int is_device_node(const char *path) {
1958 struct stat info;
1959
1960 if (lstat(path, &info) < 0)
1961 return -errno;
1962
1963 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
1964 }
1965
1966 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
1967 char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
1968 _cleanup_close_ int fd = -1;
1969 ssize_t l;
1970
1971 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
1972
1973 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
1974 if (fd < 0)
1975 return -errno;
1976
1977 xsprintf(fn, "/proc/self/fd/%i", fd);
1978
1979 l = getxattr(fn, attribute, value, size);
1980 if (l < 0)
1981 return -errno;
1982
1983 return l;
1984 }
1985
1986 static int parse_crtime(le64_t le, usec_t *usec) {
1987 uint64_t u;
1988
1989 assert(usec);
1990
1991 u = le64toh(le);
1992 if (u == 0 || u == (uint64_t) -1)
1993 return -EIO;
1994
1995 *usec = (usec_t) u;
1996 return 0;
1997 }
1998
1999 int fd_getcrtime(int fd, usec_t *usec) {
2000 le64_t le;
2001 ssize_t n;
2002
2003 assert(fd >= 0);
2004 assert(usec);
2005
2006 /* Until Linux gets a real concept of birthtime/creation time,
2007 * let's fake one with xattrs */
2008
2009 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
2010 if (n < 0)
2011 return -errno;
2012 if (n != sizeof(le))
2013 return -EIO;
2014
2015 return parse_crtime(le, usec);
2016 }
2017
2018 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
2019 le64_t le;
2020 ssize_t n;
2021
2022 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
2023 if (n < 0)
2024 return -errno;
2025 if (n != sizeof(le))
2026 return -EIO;
2027
2028 return parse_crtime(le, usec);
2029 }
2030
2031 int path_getcrtime(const char *p, usec_t *usec) {
2032 le64_t le;
2033 ssize_t n;
2034
2035 assert(p);
2036 assert(usec);
2037
2038 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
2039 if (n < 0)
2040 return -errno;
2041 if (n != sizeof(le))
2042 return -EIO;
2043
2044 return parse_crtime(le, usec);
2045 }
2046
2047 int fd_setcrtime(int fd, usec_t usec) {
2048 le64_t le;
2049
2050 assert(fd >= 0);
2051
2052 if (usec <= 0)
2053 usec = now(CLOCK_REALTIME);
2054
2055 le = htole64((uint64_t) usec);
2056 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
2057 return -errno;
2058
2059 return 0;
2060 }
2061
2062 int chattr_fd(int fd, unsigned value, unsigned mask) {
2063 unsigned old_attr, new_attr;
2064 struct stat st;
2065
2066 assert(fd >= 0);
2067
2068 if (fstat(fd, &st) < 0)
2069 return -errno;
2070
2071 /* Explicitly check whether this is a regular file or
2072 * directory. If it is anything else (such as a device node or
2073 * fifo), then the ioctl will not hit the file systems but
2074 * possibly drivers, where the ioctl might have different
2075 * effects. Notably, DRM is using the same ioctl() number. */
2076
2077 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
2078 return -ENOTTY;
2079
2080 if (mask == 0)
2081 return 0;
2082
2083 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
2084 return -errno;
2085
2086 new_attr = (old_attr & ~mask) | (value & mask);
2087 if (new_attr == old_attr)
2088 return 0;
2089
2090 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
2091 return -errno;
2092
2093 return 1;
2094 }
2095
2096 int chattr_path(const char *p, unsigned value, unsigned mask) {
2097 _cleanup_close_ int fd = -1;
2098
2099 assert(p);
2100
2101 if (mask == 0)
2102 return 0;
2103
2104 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
2105 if (fd < 0)
2106 return -errno;
2107
2108 return chattr_fd(fd, value, mask);
2109 }
2110
2111 int read_attr_fd(int fd, unsigned *ret) {
2112 struct stat st;
2113
2114 assert(fd >= 0);
2115
2116 if (fstat(fd, &st) < 0)
2117 return -errno;
2118
2119 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
2120 return -ENOTTY;
2121
2122 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
2123 return -errno;
2124
2125 return 0;
2126 }
2127
2128 int read_attr_path(const char *p, unsigned *ret) {
2129 _cleanup_close_ int fd = -1;
2130
2131 assert(p);
2132 assert(ret);
2133
2134 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
2135 if (fd < 0)
2136 return -errno;
2137
2138 return read_attr_fd(fd, ret);
2139 }
2140
2141 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
2142 int a = 0, b = 0, c = 0;
2143 int k;
2144
2145 assert(p);
2146 assert(*p);
2147 assert(priority);
2148
2149 if ((*p)[0] != '<')
2150 return 0;
2151
2152 if (!strchr(*p, '>'))
2153 return 0;
2154
2155 if ((*p)[2] == '>') {
2156 c = undecchar((*p)[1]);
2157 k = 3;
2158 } else if ((*p)[3] == '>') {
2159 b = undecchar((*p)[1]);
2160 c = undecchar((*p)[2]);
2161 k = 4;
2162 } else if ((*p)[4] == '>') {
2163 a = undecchar((*p)[1]);
2164 b = undecchar((*p)[2]);
2165 c = undecchar((*p)[3]);
2166 k = 5;
2167 } else
2168 return 0;
2169
2170 if (a < 0 || b < 0 || c < 0 ||
2171 (!with_facility && (a || b || c > 7)))
2172 return 0;
2173
2174 if (with_facility)
2175 *priority = a*100 + b*10 + c;
2176 else
2177 *priority = (*priority & LOG_FACMASK) | c;
2178
2179 *p += k;
2180 return 1;
2181 }
2182
2183 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
2184 size_t i;
2185
2186 if (!key)
2187 return -1;
2188
2189 for (i = 0; i < len; ++i)
2190 if (streq_ptr(table[i], key))
2191 return (ssize_t) i;
2192
2193 return -1;
2194 }
2195
2196 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
2197 struct stat buf;
2198 int ret;
2199
2200 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
2201 if (ret >= 0)
2202 return 0;
2203
2204 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
2205 * If it is not implemented, fallback to another method. */
2206 if (!IN_SET(errno, EINVAL, ENOSYS))
2207 return -errno;
2208
2209 /* The link()/unlink() fallback does not work on directories. But
2210 * renameat() without RENAME_NOREPLACE gives the same semantics on
2211 * directories, except when newpath is an *empty* directory. This is
2212 * good enough. */
2213 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
2214 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
2215 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
2216 return ret >= 0 ? 0 : -errno;
2217 }
2218
2219 /* If it is not a directory, use the link()/unlink() fallback. */
2220 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
2221 if (ret < 0)
2222 return -errno;
2223
2224 ret = unlinkat(olddirfd, oldpath, 0);
2225 if (ret < 0) {
2226 /* backup errno before the following unlinkat() alters it */
2227 ret = errno;
2228 (void) unlinkat(newdirfd, newpath, 0);
2229 errno = ret;
2230 return -errno;
2231 }
2232
2233 return 0;
2234 }
2235
2236 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
2237 char *v;
2238 size_t l;
2239 ssize_t n;
2240
2241 assert(path);
2242 assert(name);
2243 assert(value);
2244
2245 for (l = 100; ; l = (size_t) n + 1) {
2246 v = new0(char, l);
2247 if (!v)
2248 return -ENOMEM;
2249
2250 if (allow_symlink)
2251 n = lgetxattr(path, name, v, l);
2252 else
2253 n = getxattr(path, name, v, l);
2254
2255 if (n >= 0 && (size_t) n < l) {
2256 *value = v;
2257 return n;
2258 }
2259
2260 free(v);
2261
2262 if (n < 0 && errno != ERANGE)
2263 return -errno;
2264
2265 if (allow_symlink)
2266 n = lgetxattr(path, name, NULL, 0);
2267 else
2268 n = getxattr(path, name, NULL, 0);
2269 if (n < 0)
2270 return -errno;
2271 }
2272 }
2273
2274 int fgetxattr_malloc(int fd, const char *name, char **value) {
2275 char *v;
2276 size_t l;
2277 ssize_t n;
2278
2279 assert(fd >= 0);
2280 assert(name);
2281 assert(value);
2282
2283 for (l = 100; ; l = (size_t) n + 1) {
2284 v = new0(char, l);
2285 if (!v)
2286 return -ENOMEM;
2287
2288 n = fgetxattr(fd, name, v, l);
2289
2290 if (n >= 0 && (size_t) n < l) {
2291 *value = v;
2292 return n;
2293 }
2294
2295 free(v);
2296
2297 if (n < 0 && errno != ERANGE)
2298 return -errno;
2299
2300 n = fgetxattr(fd, name, NULL, 0);
2301 if (n < 0)
2302 return -errno;
2303 }
2304 }
2305
2306 int version(void) {
2307 puts(PACKAGE_STRING "\n"
2308 SYSTEMD_FEATURES);
2309 return 0;
2310 }
2311
2312 bool fdname_is_valid(const char *s) {
2313 const char *p;
2314
2315 /* Validates a name for $LISTEN_FDNAMES. We basically allow
2316 * everything ASCII that's not a control character. Also, as
2317 * special exception the ":" character is not allowed, as we
2318 * use that as field separator in $LISTEN_FDNAMES.
2319 *
2320 * Note that the empty string is explicitly allowed
2321 * here. However, we limit the length of the names to 255
2322 * characters. */
2323
2324 if (!s)
2325 return false;
2326
2327 for (p = s; *p; p++) {
2328 if (*p < ' ')
2329 return false;
2330 if (*p >= 127)
2331 return false;
2332 if (*p == ':')
2333 return false;
2334 }
2335
2336 return p - s < 256;
2337 }
2338
2339 bool oom_score_adjust_is_valid(int oa) {
2340 return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
2341 }