summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
l---------src/shared/Makefile1
-rw-r--r--src/shared/acl-util.c429
-rw-r--r--src/shared/acl-util.h48
-rw-r--r--src/shared/acpi-fpdt.c164
-rw-r--r--src/shared/acpi-fpdt.h24
-rw-r--r--src/shared/apparmor-util.c39
-rw-r--r--src/shared/apparmor-util.h24
-rw-r--r--src/shared/ask-password-api.c734
-rw-r--r--src/shared/ask-password-api.h38
-rw-r--r--src/shared/base-filesystem.c129
-rw-r--r--src/shared/base-filesystem.h24
-rw-r--r--src/shared/boot-timestamps.c64
-rw-r--r--src/shared/boot-timestamps.h25
-rw-r--r--src/shared/bus-unit-util.c1350
-rw-r--r--src/shared/bus-unit-util.h58
-rw-r--r--src/shared/bus-util.c1567
-rw-r--r--src/shared/bus-util.h161
-rw-r--r--src/shared/cgroup-show.c312
-rw-r--r--src/shared/cgroup-show.h32
-rw-r--r--src/shared/clean-ipc.c389
-rw-r--r--src/shared/clean-ipc.h26
-rw-r--r--src/shared/condition.c578
-rw-r--r--src/shared/condition.h94
-rw-r--r--src/shared/conf-parser.c961
-rw-r--r--src/shared/conf-parser.h242
-rw-r--r--src/shared/dev-setup.c73
-rw-r--r--src/shared/dev-setup.h24
-rw-r--r--src/shared/dns-domain.c1326
-rw-r--r--src/shared/dns-domain.h109
-rw-r--r--src/shared/dropin.c251
-rw-r--r--src/shared/dropin.h61
-rw-r--r--src/shared/efivars.c715
-rw-r--r--src/shared/efivars.h131
-rw-r--r--src/shared/fdset.c273
-rw-r--r--src/shared/fdset.h58
-rw-r--r--src/shared/firewall-util.c357
-rw-r--r--src/shared/firewall-util.h83
-rw-r--r--src/shared/fstab-util.c263
-rw-r--r--src/shared/fstab-util.h52
-rw-r--r--src/shared/gcrypt-util.c71
-rw-r--r--src/shared/gcrypt-util.h47
-rw-r--r--src/shared/generator.c207
-rw-r--r--src/shared/generator.h40
-rw-r--r--src/shared/gpt.h66
-rw-r--r--src/shared/ima-util.c32
-rw-r--r--src/shared/ima-util.h24
-rw-r--r--src/shared/import-util.c185
-rw-r--r--src/shared/import-util.h43
-rw-r--r--src/shared/initreq.h77
-rw-r--r--src/shared/install-printf.c172
-rw-r--r--src/shared/install-printf.h24
-rw-r--r--src/shared/install.c3041
-rw-r--r--src/shared/install.h256
-rw-r--r--src/shared/linux/auto_dev-ioctl.h228
-rw-r--r--src/shared/logs-show.c1351
-rw-r--r--src/shared/logs-show.h70
-rw-r--r--src/shared/machine-image.c817
-rw-r--r--src/shared/machine-image.h103
-rw-r--r--src/shared/machine-pool.c426
-rw-r--r--src/shared/machine-pool.h30
-rw-r--r--src/shared/output-mode.c38
-rw-r--r--src/shared/output-mode.h58
-rw-r--r--src/shared/pager.c227
-rw-r--r--src/shared/pager.h30
-rw-r--r--src/shared/path-lookup.c822
-rw-r--r--src/shared/path-lookup.h76
-rw-r--r--src/shared/ptyfwd.c521
-rw-r--r--src/shared/ptyfwd.h54
-rw-r--r--src/shared/resolve-util.c39
-rw-r--r--src/shared/resolve-util.h60
-rw-r--r--src/shared/seccomp-util.c578
-rw-r--r--src/shared/seccomp-util.h66
-rw-r--r--src/shared/sleep-config.c278
-rw-r--r--src/shared/sleep-config.h26
-rw-r--r--src/shared/spawn-ask-password-agent.c62
-rw-r--r--src/shared/spawn-ask-password-agent.h23
-rw-r--r--src/shared/spawn-polkit-agent.c102
-rw-r--r--src/shared/spawn-polkit-agent.h23
-rw-r--r--src/shared/specifier.c188
-rw-r--r--src/shared/specifier.h37
-rw-r--r--src/shared/switch-root.c167
-rw-r--r--src/shared/switch-root.h23
-rw-r--r--src/shared/sysctl-util.c73
-rw-r--r--src/shared/sysctl-util.h25
-rw-r--r--src/shared/test-tables.h60
-rw-r--r--src/shared/tests.c33
-rw-r--r--src/shared/tests.h22
-rw-r--r--src/shared/udev-util.h44
-rw-r--r--src/shared/uid-range.c208
-rw-r--r--src/shared/uid-range.h33
-rw-r--r--src/shared/utmp-wtmp.c445
-rw-r--r--src/shared/utmp-wtmp.h74
-rw-r--r--src/shared/vlan-util.c69
-rw-r--r--src/shared/vlan-util.h35
-rw-r--r--src/shared/watchdog.c164
-rw-r--r--src/shared/watchdog.h29
96 files changed, 0 insertions, 23411 deletions
diff --git a/src/shared/Makefile b/src/shared/Makefile
deleted file mode 120000
index d0b0e8e008..0000000000
--- a/src/shared/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile \ No newline at end of file
diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c
deleted file mode 100644
index 2aa951fce9..0000000000
--- a/src/shared/acl-util.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2011,2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdbool.h>
-
-#include "acl-util.h"
-#include "alloc-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "user-util.h"
-#include "util.h"
-
-int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
- acl_entry_t i;
- int r;
-
- assert(acl);
- assert(entry);
-
- for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
- r > 0;
- r = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
-
- acl_tag_t tag;
- uid_t *u;
- bool b;
-
- if (acl_get_tag_type(i, &tag) < 0)
- return -errno;
-
- if (tag != ACL_USER)
- continue;
-
- u = acl_get_qualifier(i);
- if (!u)
- return -errno;
-
- b = *u == uid;
- acl_free(u);
-
- if (b) {
- *entry = i;
- return 1;
- }
- }
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-int calc_acl_mask_if_needed(acl_t *acl_p) {
- acl_entry_t i;
- int r;
- bool need = false;
-
- assert(acl_p);
-
- for (r = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i);
- r > 0;
- r = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) {
- acl_tag_t tag;
-
- if (acl_get_tag_type(i, &tag) < 0)
- return -errno;
-
- if (tag == ACL_MASK)
- return 0;
-
- if (IN_SET(tag, ACL_USER, ACL_GROUP))
- need = true;
- }
- if (r < 0)
- return -errno;
-
- if (need && acl_calc_mask(acl_p) < 0)
- return -errno;
-
- return need;
-}
-
-int add_base_acls_if_needed(acl_t *acl_p, const char *path) {
- acl_entry_t i;
- int r;
- bool have_user_obj = false, have_group_obj = false, have_other = false;
- struct stat st;
- _cleanup_(acl_freep) acl_t basic = NULL;
-
- assert(acl_p);
-
- for (r = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i);
- r > 0;
- r = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) {
- acl_tag_t tag;
-
- if (acl_get_tag_type(i, &tag) < 0)
- return -errno;
-
- if (tag == ACL_USER_OBJ)
- have_user_obj = true;
- else if (tag == ACL_GROUP_OBJ)
- have_group_obj = true;
- else if (tag == ACL_OTHER)
- have_other = true;
- if (have_user_obj && have_group_obj && have_other)
- return 0;
- }
- if (r < 0)
- return -errno;
-
- r = stat(path, &st);
- if (r < 0)
- return -errno;
-
- basic = acl_from_mode(st.st_mode);
- if (!basic)
- return -errno;
-
- for (r = acl_get_entry(basic, ACL_FIRST_ENTRY, &i);
- r > 0;
- r = acl_get_entry(basic, ACL_NEXT_ENTRY, &i)) {
- acl_tag_t tag;
- acl_entry_t dst;
-
- if (acl_get_tag_type(i, &tag) < 0)
- return -errno;
-
- if ((tag == ACL_USER_OBJ && have_user_obj) ||
- (tag == ACL_GROUP_OBJ && have_group_obj) ||
- (tag == ACL_OTHER && have_other))
- continue;
-
- r = acl_create_entry(acl_p, &dst);
- if (r < 0)
- return -errno;
-
- r = acl_copy_entry(dst, i);
- if (r < 0)
- return -errno;
- }
- if (r < 0)
- return -errno;
- return 0;
-}
-
-int acl_search_groups(const char *path, char ***ret_groups) {
- _cleanup_strv_free_ char **g = NULL;
- _cleanup_(acl_free) acl_t acl = NULL;
- bool ret = false;
- acl_entry_t entry;
- int r;
-
- assert(path);
-
- acl = acl_get_file(path, ACL_TYPE_DEFAULT);
- if (!acl)
- return -errno;
-
- r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
- for (;;) {
- _cleanup_(acl_free_gid_tpp) gid_t *gid = NULL;
- acl_tag_t tag;
-
- if (r < 0)
- return -errno;
- if (r == 0)
- break;
-
- if (acl_get_tag_type(entry, &tag) < 0)
- return -errno;
-
- if (tag != ACL_GROUP)
- goto next;
-
- gid = acl_get_qualifier(entry);
- if (!gid)
- return -errno;
-
- if (in_gid(*gid) > 0) {
- if (!ret_groups)
- return true;
-
- ret = true;
- }
-
- if (ret_groups) {
- char *name;
-
- name = gid_to_name(*gid);
- if (!name)
- return -ENOMEM;
-
- r = strv_consume(&g, name);
- if (r < 0)
- return r;
- }
-
- next:
- r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
- }
-
- if (ret_groups) {
- *ret_groups = g;
- g = NULL;
- }
-
- return ret;
-}
-
-int parse_acl(const char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask) {
- _cleanup_free_ char **a = NULL, **d = NULL; /* strings are not be freed */
- _cleanup_strv_free_ char **split;
- char **entry;
- int r = -EINVAL;
- _cleanup_(acl_freep) acl_t a_acl = NULL, d_acl = NULL;
-
- split = strv_split(text, ",");
- if (!split)
- return -ENOMEM;
-
- STRV_FOREACH(entry, split) {
- char *p;
-
- p = startswith(*entry, "default:");
- if (!p)
- p = startswith(*entry, "d:");
-
- if (p)
- r = strv_push(&d, p);
- else
- r = strv_push(&a, *entry);
- if (r < 0)
- return r;
- }
-
- if (!strv_isempty(a)) {
- _cleanup_free_ char *join;
-
- join = strv_join(a, ",");
- if (!join)
- return -ENOMEM;
-
- a_acl = acl_from_text(join);
- if (!a_acl)
- return -errno;
-
- if (want_mask) {
- r = calc_acl_mask_if_needed(&a_acl);
- if (r < 0)
- return r;
- }
- }
-
- if (!strv_isempty(d)) {
- _cleanup_free_ char *join;
-
- join = strv_join(d, ",");
- if (!join)
- return -ENOMEM;
-
- d_acl = acl_from_text(join);
- if (!d_acl)
- return -errno;
-
- if (want_mask) {
- r = calc_acl_mask_if_needed(&d_acl);
- if (r < 0)
- return r;
- }
- }
-
- *acl_access = a_acl;
- *acl_default = d_acl;
- a_acl = d_acl = NULL;
-
- return 0;
-}
-
-static int acl_entry_equal(acl_entry_t a, acl_entry_t b) {
- acl_tag_t tag_a, tag_b;
-
- if (acl_get_tag_type(a, &tag_a) < 0)
- return -errno;
-
- if (acl_get_tag_type(b, &tag_b) < 0)
- return -errno;
-
- if (tag_a != tag_b)
- return false;
-
- switch (tag_a) {
- case ACL_USER_OBJ:
- case ACL_GROUP_OBJ:
- case ACL_MASK:
- case ACL_OTHER:
- /* can have only one of those */
- return true;
- case ACL_USER: {
- _cleanup_(acl_free_uid_tpp) uid_t *uid_a = NULL, *uid_b = NULL;
-
- uid_a = acl_get_qualifier(a);
- if (!uid_a)
- return -errno;
-
- uid_b = acl_get_qualifier(b);
- if (!uid_b)
- return -errno;
-
- return *uid_a == *uid_b;
- }
- case ACL_GROUP: {
- _cleanup_(acl_free_gid_tpp) gid_t *gid_a = NULL, *gid_b = NULL;
-
- gid_a = acl_get_qualifier(a);
- if (!gid_a)
- return -errno;
-
- gid_b = acl_get_qualifier(b);
- if (!gid_b)
- return -errno;
-
- return *gid_a == *gid_b;
- }
- default:
- assert_not_reached("Unknown acl tag type");
- }
-}
-
-static int find_acl_entry(acl_t acl, acl_entry_t entry, acl_entry_t *out) {
- acl_entry_t i;
- int r;
-
- for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
- r > 0;
- r = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
-
- r = acl_entry_equal(i, entry);
- if (r < 0)
- return r;
- if (r > 0) {
- *out = i;
- return 1;
- }
- }
- if (r < 0)
- return -errno;
- return 0;
-}
-
-int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl) {
- _cleanup_(acl_freep) acl_t old;
- acl_entry_t i;
- int r;
-
- old = acl_get_file(path, type);
- if (!old)
- return -errno;
-
- for (r = acl_get_entry(new, ACL_FIRST_ENTRY, &i);
- r > 0;
- r = acl_get_entry(new, ACL_NEXT_ENTRY, &i)) {
-
- acl_entry_t j;
-
- r = find_acl_entry(old, i, &j);
- if (r < 0)
- return r;
- if (r == 0)
- if (acl_create_entry(&old, &j) < 0)
- return -errno;
-
- if (acl_copy_entry(j, i) < 0)
- return -errno;
- }
- if (r < 0)
- return -errno;
-
- *acl = old;
- old = NULL;
- return 0;
-}
-
-int add_acls_for_user(int fd, uid_t uid) {
- _cleanup_(acl_freep) acl_t acl = NULL;
- acl_entry_t entry;
- acl_permset_t permset;
- int r;
-
- acl = acl_get_fd(fd);
- if (!acl)
- return -errno;
-
- r = acl_find_uid(acl, uid, &entry);
- if (r <= 0) {
- if (acl_create_entry(&acl, &entry) < 0 ||
- acl_set_tag_type(entry, ACL_USER) < 0 ||
- acl_set_qualifier(entry, &uid) < 0)
- return -errno;
- }
-
- /* We do not recalculate the mask unconditionally here,
- * so that the fchmod() mask above stays intact. */
- if (acl_get_permset(entry, &permset) < 0 ||
- acl_add_perm(permset, ACL_READ) < 0)
- return -errno;
-
- r = calc_acl_mask_if_needed(&acl);
- if (r < 0)
- return r;
-
- return acl_set_fd(fd, acl);
-}
diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h
deleted file mode 100644
index 396e9e067e..0000000000
--- a/src/shared/acl-util.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#ifdef HAVE_ACL
-
-#include <acl/libacl.h>
-#include <stdbool.h>
-#include <sys/acl.h>
-
-#include "macro.h"
-
-int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry);
-int calc_acl_mask_if_needed(acl_t *acl_p);
-int add_base_acls_if_needed(acl_t *acl_p, const char *path);
-int acl_search_groups(const char* path, char ***ret_groups);
-int parse_acl(const char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask);
-int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl);
-int add_acls_for_user(int fd, uid_t uid);
-
-/* acl_free takes multiple argument types.
- * Multiple cleanup functions are necessary. */
-DEFINE_TRIVIAL_CLEANUP_FUNC(acl_t, acl_free);
-#define acl_free_charp acl_free
-DEFINE_TRIVIAL_CLEANUP_FUNC(char*, acl_free_charp);
-#define acl_free_uid_tp acl_free
-DEFINE_TRIVIAL_CLEANUP_FUNC(uid_t*, acl_free_uid_tp);
-#define acl_free_gid_tp acl_free
-DEFINE_TRIVIAL_CLEANUP_FUNC(gid_t*, acl_free_gid_tp);
-
-#endif
diff --git a/src/shared/acpi-fpdt.c b/src/shared/acpi-fpdt.c
deleted file mode 100644
index 6779691c28..0000000000
--- a/src/shared/acpi-fpdt.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Kay Sievers
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "acpi-fpdt.h"
-#include "alloc-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "time-util.h"
-
-struct acpi_table_header {
- char signature[4];
- uint32_t length;
- uint8_t revision;
- uint8_t checksum;
- char oem_id[6];
- char oem_table_id[8];
- uint32_t oem_revision;
- char asl_compiler_id[4];
- uint32_t asl_compiler_revision;
-};
-
-enum {
- ACPI_FPDT_TYPE_BOOT = 0,
- ACPI_FPDT_TYPE_S3PERF = 1,
-};
-
-struct acpi_fpdt_header {
- uint16_t type;
- uint8_t length;
- uint8_t revision;
- uint8_t reserved[4];
- uint64_t ptr;
-};
-
-struct acpi_fpdt_boot_header {
- char signature[4];
- uint32_t length;
-};
-
-enum {
- ACPI_FPDT_S3PERF_RESUME_REC = 0,
- ACPI_FPDT_S3PERF_SUSPEND_REC = 1,
- ACPI_FPDT_BOOT_REC = 2,
-};
-
-struct acpi_fpdt_boot {
- uint16_t type;
- uint8_t length;
- uint8_t revision;
- uint8_t reserved[4];
- uint64_t reset_end;
- uint64_t load_start;
- uint64_t startup_start;
- uint64_t exit_services_entry;
- uint64_t exit_services_exit;
-};
-
-int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit) {
- _cleanup_free_ char *buf = NULL;
- struct acpi_table_header *tbl;
- size_t l = 0;
- struct acpi_fpdt_header *rec;
- int r;
- uint64_t ptr = 0;
- _cleanup_close_ int fd = -1;
- struct acpi_fpdt_boot_header hbrec;
- struct acpi_fpdt_boot brec;
-
- r = read_full_file("/sys/firmware/acpi/tables/FPDT", &buf, &l);
- if (r < 0)
- return r;
-
- if (l < sizeof(struct acpi_table_header) + sizeof(struct acpi_fpdt_header))
- return -EINVAL;
-
- tbl = (struct acpi_table_header *)buf;
- if (l != tbl->length)
- return -EINVAL;
-
- if (memcmp(tbl->signature, "FPDT", 4) != 0)
- return -EINVAL;
-
- /* find Firmware Basic Boot Performance Pointer Record */
- for (rec = (struct acpi_fpdt_header *)(buf + sizeof(struct acpi_table_header));
- (char *)rec < buf + l;
- rec = (struct acpi_fpdt_header *)((char *)rec + rec->length)) {
- if (rec->length <= 0)
- break;
- if (rec->type != ACPI_FPDT_TYPE_BOOT)
- continue;
- if (rec->length != sizeof(struct acpi_fpdt_header))
- continue;
-
- ptr = rec->ptr;
- break;
- }
-
- if (ptr == 0)
- return -ENODATA;
-
- /* read Firmware Basic Boot Performance Data Record */
- fd = open("/dev/mem", O_CLOEXEC|O_RDONLY);
- if (fd < 0)
- return -errno;
-
- l = pread(fd, &hbrec, sizeof(struct acpi_fpdt_boot_header), ptr);
- if (l != sizeof(struct acpi_fpdt_boot_header))
- return -EINVAL;
-
- if (memcmp(hbrec.signature, "FBPT", 4) != 0)
- return -EINVAL;
-
- if (hbrec.length < sizeof(struct acpi_fpdt_boot_header) + sizeof(struct acpi_fpdt_boot))
- return -EINVAL;
-
- l = pread(fd, &brec, sizeof(struct acpi_fpdt_boot), ptr + sizeof(struct acpi_fpdt_boot_header));
- if (l != sizeof(struct acpi_fpdt_boot))
- return -EINVAL;
-
- if (brec.length != sizeof(struct acpi_fpdt_boot))
- return -EINVAL;
-
- if (brec.type != ACPI_FPDT_BOOT_REC)
- return -EINVAL;
-
- if (brec.exit_services_exit == 0)
- /* Non-UEFI compatible boot. */
- return -ENODATA;
-
- if (brec.startup_start == 0 || brec.exit_services_exit < brec.startup_start)
- return -EINVAL;
- if (brec.exit_services_exit > NSEC_PER_HOUR)
- return -EINVAL;
-
- if (loader_start)
- *loader_start = brec.startup_start / 1000;
- if (loader_exit)
- *loader_exit = brec.exit_services_exit / 1000;
-
- return 0;
-}
diff --git a/src/shared/acpi-fpdt.h b/src/shared/acpi-fpdt.h
deleted file mode 100644
index fc28175d0a..0000000000
--- a/src/shared/acpi-fpdt.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Kay Sievers
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <time-util.h>
-
-int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit);
diff --git a/src/shared/apparmor-util.c b/src/shared/apparmor-util.c
deleted file mode 100644
index edd695fd23..0000000000
--- a/src/shared/apparmor-util.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stddef.h>
-
-#include "alloc-util.h"
-#include "apparmor-util.h"
-#include "fileio.h"
-#include "parse-util.h"
-
-bool mac_apparmor_use(void) {
- static int cached_use = -1;
-
- if (cached_use < 0) {
- _cleanup_free_ char *p = NULL;
-
- cached_use =
- read_one_line_file("/sys/module/apparmor/parameters/enabled", &p) >= 0 &&
- parse_boolean(p) > 0;
- }
-
- return cached_use;
-}
diff --git a/src/shared/apparmor-util.h b/src/shared/apparmor-util.h
deleted file mode 100644
index 524f740152..0000000000
--- a/src/shared/apparmor-util.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-bool mac_apparmor_use(void);
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
deleted file mode 100644
index 2597cfc648..0000000000
--- a/src/shared/ask-password-api.c
+++ /dev/null
@@ -1,734 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/inotify.h>
-#include <sys/signalfd.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "ask-password-api.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "formats-util.h"
-#include "io-util.h"
-#include "log.h"
-#include "macro.h"
-#include "missing.h"
-#include "mkdir.h"
-#include "random-util.h"
-#include "signal-util.h"
-#include "socket-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "terminal-util.h"
-#include "time-util.h"
-#include "umask-util.h"
-#include "utf8.h"
-#include "util.h"
-
-#define KEYRING_TIMEOUT_USEC ((5 * USEC_PER_MINUTE) / 2)
-
-static int lookup_key(const char *keyname, key_serial_t *ret) {
- key_serial_t serial;
-
- assert(keyname);
- assert(ret);
-
- serial = request_key("user", keyname, NULL, 0);
- if (serial == -1)
- return negative_errno();
-
- *ret = serial;
- return 0;
-}
-
-static int retrieve_key(key_serial_t serial, char ***ret) {
- _cleanup_free_ char *p = NULL;
- long m = 100, n;
- char **l;
-
- assert(ret);
-
- for (;;) {
- p = new(char, m);
- if (!p)
- return -ENOMEM;
-
- n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) p, (unsigned long) m, 0);
- if (n < 0)
- return -errno;
-
- if (n < m)
- break;
-
- memory_erase(p, n);
- free(p);
- m *= 2;
- }
-
- l = strv_parse_nulstr(p, n);
- if (!l)
- return -ENOMEM;
-
- memory_erase(p, n);
-
- *ret = l;
- return 0;
-}
-
-static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **passwords) {
- _cleanup_strv_free_erase_ char **l = NULL;
- _cleanup_free_ char *p = NULL;
- key_serial_t serial;
- size_t n;
- int r;
-
- assert(keyname);
- assert(passwords);
-
- if (!(flags & ASK_PASSWORD_PUSH_CACHE))
- return 0;
-
- r = lookup_key(keyname, &serial);
- if (r >= 0) {
- r = retrieve_key(serial, &l);
- if (r < 0)
- return r;
- } else if (r != -ENOKEY)
- return r;
-
- r = strv_extend_strv(&l, passwords, true);
- if (r <= 0)
- return r;
-
- r = strv_make_nulstr(l, &p, &n);
- if (r < 0)
- return r;
-
- serial = add_key("user", keyname, p, n, KEY_SPEC_USER_KEYRING);
- memory_erase(p, n);
- if (serial == -1)
- return -errno;
-
- if (keyctl(KEYCTL_SET_TIMEOUT,
- (unsigned long) serial,
- (unsigned long) DIV_ROUND_UP(KEYRING_TIMEOUT_USEC, USEC_PER_SEC), 0, 0) < 0)
- log_debug_errno(errno, "Failed to adjust timeout: %m");
-
- log_debug("Added key to keyring as %" PRIi32 ".", serial);
-
- return 1;
-}
-
-static int add_to_keyring_and_log(const char *keyname, AskPasswordFlags flags, char **passwords) {
- int r;
-
- assert(keyname);
- assert(passwords);
-
- r = add_to_keyring(keyname, flags, passwords);
- if (r < 0)
- return log_debug_errno(r, "Failed to add password to keyring: %m");
-
- return 0;
-}
-
-int ask_password_keyring(const char *keyname, AskPasswordFlags flags, char ***ret) {
-
- key_serial_t serial;
- int r;
-
- assert(keyname);
- assert(ret);
-
- if (!(flags & ASK_PASSWORD_ACCEPT_CACHED))
- return -EUNATCH;
-
- r = lookup_key(keyname, &serial);
- if (r == -ENOSYS) /* when retrieving the distinction doesn't matter */
- return -ENOKEY;
- if (r < 0)
- return r;
-
- return retrieve_key(serial, ret);
-}
-
-static void backspace_chars(int ttyfd, size_t p) {
-
- if (ttyfd < 0)
- return;
-
- while (p > 0) {
- p--;
-
- loop_write(ttyfd, "\b \b", 3, false);
- }
-}
-
-int ask_password_tty(
- const char *message,
- const char *keyname,
- usec_t until,
- AskPasswordFlags flags,
- const char *flag_file,
- char **ret) {
-
- struct termios old_termios, new_termios;
- char passphrase[LINE_MAX + 1] = {}, *x;
- size_t p = 0, codepoint = 0;
- int r;
- _cleanup_close_ int ttyfd = -1, notify = -1;
- struct pollfd pollfd[2];
- bool reset_tty = false;
- bool dirty = false;
- enum {
- POLL_TTY,
- POLL_INOTIFY
- };
-
- assert(ret);
-
- if (flags & ASK_PASSWORD_NO_TTY)
- return -EUNATCH;
-
- if (!message)
- message = "Password:";
-
- if (flag_file) {
- notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
- if (notify < 0) {
- r = -errno;
- goto finish;
- }
-
- if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) {
- r = -errno;
- goto finish;
- }
- }
-
- ttyfd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (ttyfd >= 0) {
-
- if (tcgetattr(ttyfd, &old_termios) < 0) {
- r = -errno;
- goto finish;
- }
-
- if (colors_enabled())
- loop_write(ttyfd, ANSI_HIGHLIGHT, strlen(ANSI_HIGHLIGHT), false);
- loop_write(ttyfd, message, strlen(message), false);
- loop_write(ttyfd, " ", 1, false);
- if (colors_enabled())
- loop_write(ttyfd, ANSI_NORMAL, strlen(ANSI_NORMAL), false);
-
- new_termios = old_termios;
- new_termios.c_lflag &= ~(ICANON|ECHO);
- new_termios.c_cc[VMIN] = 1;
- new_termios.c_cc[VTIME] = 0;
-
- if (tcsetattr(ttyfd, TCSADRAIN, &new_termios) < 0) {
- r = -errno;
- goto finish;
- }
-
- reset_tty = true;
- }
-
- zero(pollfd);
- pollfd[POLL_TTY].fd = ttyfd >= 0 ? ttyfd : STDIN_FILENO;
- pollfd[POLL_TTY].events = POLLIN;
- pollfd[POLL_INOTIFY].fd = notify;
- pollfd[POLL_INOTIFY].events = POLLIN;
-
- for (;;) {
- char c;
- int sleep_for = -1, k;
- ssize_t n;
-
- if (until > 0) {
- usec_t y;
-
- y = now(CLOCK_MONOTONIC);
-
- if (y > until) {
- r = -ETIME;
- goto finish;
- }
-
- sleep_for = (int) ((until - y) / USEC_PER_MSEC);
- }
-
- if (flag_file)
- if (access(flag_file, F_OK) < 0) {
- r = -errno;
- goto finish;
- }
-
- k = poll(pollfd, notify >= 0 ? 2 : 1, sleep_for);
- if (k < 0) {
- if (errno == EINTR)
- continue;
-
- r = -errno;
- goto finish;
- } else if (k == 0) {
- r = -ETIME;
- goto finish;
- }
-
- if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
- flush_fd(notify);
-
- if (pollfd[POLL_TTY].revents == 0)
- continue;
-
- n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1);
- if (n < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
-
- r = -errno;
- goto finish;
-
- } else if (n == 0)
- break;
-
- if (c == '\n')
- break;
- else if (c == 21) { /* C-u */
-
- if (!(flags & ASK_PASSWORD_SILENT))
- backspace_chars(ttyfd, p);
- p = 0;
-
- } else if (c == '\b' || c == 127) {
-
- if (p > 0) {
-
- if (!(flags & ASK_PASSWORD_SILENT))
- backspace_chars(ttyfd, 1);
-
- p--;
- } else if (!dirty && !(flags & ASK_PASSWORD_SILENT)) {
-
- flags |= ASK_PASSWORD_SILENT;
-
- /* There are two ways to enter silent
- * mode. Either by pressing backspace
- * as first key (and only as first
- * key), or ... */
- if (ttyfd >= 0)
- loop_write(ttyfd, "(no echo) ", 10, false);
-
- } else if (ttyfd >= 0)
- loop_write(ttyfd, "\a", 1, false);
-
- } else if (c == '\t' && !(flags & ASK_PASSWORD_SILENT)) {
-
- backspace_chars(ttyfd, p);
- flags |= ASK_PASSWORD_SILENT;
-
- /* ... or by pressing TAB at any time. */
-
- if (ttyfd >= 0)
- loop_write(ttyfd, "(no echo) ", 10, false);
- } else {
- if (p >= sizeof(passphrase)-1) {
- loop_write(ttyfd, "\a", 1, false);
- continue;
- }
-
- passphrase[p++] = c;
-
- if (!(flags & ASK_PASSWORD_SILENT) && ttyfd >= 0) {
- n = utf8_encoded_valid_unichar(passphrase + codepoint);
- if (n >= 0) {
- codepoint = p;
- loop_write(ttyfd, (flags & ASK_PASSWORD_ECHO) ? &c : "*", 1, false);
- }
- }
-
- dirty = true;
- }
-
- c = 'x';
- }
-
- x = strndup(passphrase, p);
- memory_erase(passphrase, p);
- if (!x) {
- r = -ENOMEM;
- goto finish;
- }
-
- if (keyname)
- (void) add_to_keyring_and_log(keyname, flags, STRV_MAKE(x));
-
- *ret = x;
- r = 0;
-
-finish:
- if (ttyfd >= 0 && reset_tty) {
- loop_write(ttyfd, "\n", 1, false);
- tcsetattr(ttyfd, TCSADRAIN, &old_termios);
- }
-
- return r;
-}
-
-static int create_socket(char **name) {
- union sockaddr_union sa = {
- .un.sun_family = AF_UNIX,
- };
- _cleanup_close_ int fd = -1;
- static const int one = 1;
- char *c;
- int r;
-
- assert(name);
-
- fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
- if (fd < 0)
- return -errno;
-
- snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%" PRIx64, random_u64());
-
- RUN_WITH_UMASK(0177) {
- if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
- return -errno;
- }
-
- if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
- return -errno;
-
- c = strdup(sa.un.sun_path);
- if (!c)
- return -ENOMEM;
-
- *name = c;
-
- r = fd;
- fd = -1;
-
- return r;
-}
-
-int ask_password_agent(
- const char *message,
- const char *icon,
- const char *id,
- const char *keyname,
- usec_t until,
- AskPasswordFlags flags,
- char ***ret) {
-
- enum {
- FD_SOCKET,
- FD_SIGNAL,
- _FD_MAX
- };
-
- _cleanup_close_ int socket_fd = -1, signal_fd = -1, fd = -1;
- char temp[] = "/run/systemd/ask-password/tmp.XXXXXX";
- char final[sizeof(temp)] = "";
- _cleanup_free_ char *socket_name = NULL;
- _cleanup_strv_free_ char **l = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- struct pollfd pollfd[_FD_MAX];
- sigset_t mask, oldmask;
- int r;
-
- assert(ret);
-
- if (flags & ASK_PASSWORD_NO_AGENT)
- return -EUNATCH;
-
- assert_se(sigemptyset(&mask) >= 0);
- assert_se(sigset_add_many(&mask, SIGINT, SIGTERM, -1) >= 0);
- assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) >= 0);
-
- (void) mkdir_p_label("/run/systemd/ask-password", 0755);
-
- fd = mkostemp_safe(temp);
- if (fd < 0) {
- r = fd;
- goto finish;
- }
-
- (void) fchmod(fd, 0644);
-
- f = fdopen(fd, "w");
- if (!f) {
- r = -errno;
- goto finish;
- }
-
- fd = -1;
-
- signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
- if (signal_fd < 0) {
- r = -errno;
- goto finish;
- }
-
- socket_fd = create_socket(&socket_name);
- if (socket_fd < 0) {
- r = socket_fd;
- goto finish;
- }
-
- fprintf(f,
- "[Ask]\n"
- "PID="PID_FMT"\n"
- "Socket=%s\n"
- "AcceptCached=%i\n"
- "Echo=%i\n"
- "NotAfter="USEC_FMT"\n",
- getpid(),
- socket_name,
- (flags & ASK_PASSWORD_ACCEPT_CACHED) ? 1 : 0,
- (flags & ASK_PASSWORD_ECHO) ? 1 : 0,
- until);
-
- if (message)
- fprintf(f, "Message=%s\n", message);
-
- if (icon)
- fprintf(f, "Icon=%s\n", icon);
-
- if (id)
- fprintf(f, "Id=%s\n", id);
-
- r = fflush_and_check(f);
- if (r < 0)
- goto finish;
-
- memcpy(final, temp, sizeof(temp));
-
- final[sizeof(final)-11] = 'a';
- final[sizeof(final)-10] = 's';
- final[sizeof(final)-9] = 'k';
-
- if (rename(temp, final) < 0) {
- r = -errno;
- goto finish;
- }
-
- zero(pollfd);
- pollfd[FD_SOCKET].fd = socket_fd;
- pollfd[FD_SOCKET].events = POLLIN;
- pollfd[FD_SIGNAL].fd = signal_fd;
- pollfd[FD_SIGNAL].events = POLLIN;
-
- for (;;) {
- char passphrase[LINE_MAX+1];
- struct msghdr msghdr;
- struct iovec iovec;
- struct ucred *ucred;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
- } control;
- ssize_t n;
- int k;
- usec_t t;
-
- t = now(CLOCK_MONOTONIC);
-
- if (until > 0 && until <= t) {
- r = -ETIME;
- goto finish;
- }
-
- k = poll(pollfd, _FD_MAX, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1);
- if (k < 0) {
- if (errno == EINTR)
- continue;
-
- r = -errno;
- goto finish;
- }
-
- if (k <= 0) {
- r = -ETIME;
- goto finish;
- }
-
- if (pollfd[FD_SIGNAL].revents & POLLIN) {
- r = -EINTR;
- goto finish;
- }
-
- if (pollfd[FD_SOCKET].revents != POLLIN) {
- r = -EIO;
- goto finish;
- }
-
- zero(iovec);
- iovec.iov_base = passphrase;
- iovec.iov_len = sizeof(passphrase);
-
- zero(control);
- zero(msghdr);
- msghdr.msg_iov = &iovec;
- msghdr.msg_iovlen = 1;
- msghdr.msg_control = &control;
- msghdr.msg_controllen = sizeof(control);
-
- n = recvmsg(socket_fd, &msghdr, 0);
- if (n < 0) {
- if (errno == EAGAIN ||
- errno == EINTR)
- continue;
-
- r = -errno;
- goto finish;
- }
-
- cmsg_close_all(&msghdr);
-
- if (n <= 0) {
- log_debug("Message too short");
- continue;
- }
-
- if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
- control.cmsghdr.cmsg_level != SOL_SOCKET ||
- control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
- control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
- log_debug("Received message without credentials. Ignoring.");
- continue;
- }
-
- ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
- if (ucred->uid != 0) {
- log_debug("Got request from unprivileged user. Ignoring.");
- continue;
- }
-
- if (passphrase[0] == '+') {
- /* An empty message refers to the empty password */
- if (n == 1)
- l = strv_new("", NULL);
- else
- l = strv_parse_nulstr(passphrase+1, n-1);
- memory_erase(passphrase, n);
- if (!l) {
- r = -ENOMEM;
- goto finish;
- }
-
- if (strv_length(l) <= 0) {
- l = strv_free(l);
- log_debug("Invalid packet");
- continue;
- }
-
- break;
- }
-
- if (passphrase[0] == '-') {
- r = -ECANCELED;
- goto finish;
- }
-
- log_debug("Invalid packet");
- }
-
- if (keyname)
- (void) add_to_keyring_and_log(keyname, flags, l);
-
- *ret = l;
- l = NULL;
- r = 0;
-
-finish:
- if (socket_name)
- (void) unlink(socket_name);
-
- (void) unlink(temp);
-
- if (final[0])
- (void) unlink(final);
-
- assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
- return r;
-}
-
-int ask_password_auto(
- const char *message,
- const char *icon,
- const char *id,
- const char *keyname,
- usec_t until,
- AskPasswordFlags flags,
- char ***ret) {
-
- int r;
-
- assert(ret);
-
- if ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname) {
- r = ask_password_keyring(keyname, flags, ret);
- if (r != -ENOKEY)
- return r;
- }
-
- if (!(flags & ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO)) {
- char *s = NULL, **l = NULL;
-
- r = ask_password_tty(message, keyname, until, flags, NULL, &s);
- if (r < 0)
- return r;
-
- r = strv_push(&l, s);
- if (r < 0) {
- string_erase(s);
- free(s);
- return -ENOMEM;
- }
-
- *ret = l;
- return 0;
- }
-
- if (!(flags & ASK_PASSWORD_NO_AGENT))
- return ask_password_agent(message, icon, id, keyname, until, flags, ret);
-
- return -EUNATCH;
-}
diff --git a/src/shared/ask-password-api.h b/src/shared/ask-password-api.h
deleted file mode 100644
index 9d7f65130c..0000000000
--- a/src/shared/ask-password-api.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include "time-util.h"
-
-typedef enum AskPasswordFlags {
- ASK_PASSWORD_ACCEPT_CACHED = 1,
- ASK_PASSWORD_PUSH_CACHE = 2,
- ASK_PASSWORD_ECHO = 4, /* show the password literally while reading, instead of "*" */
- ASK_PASSWORD_SILENT = 8, /* do no show any password at all while reading */
- ASK_PASSWORD_NO_TTY = 16,
- ASK_PASSWORD_NO_AGENT = 32,
-} AskPasswordFlags;
-
-int ask_password_tty(const char *message, const char *keyname, usec_t until, AskPasswordFlags flags, const char *flag_file, char **ret);
-int ask_password_agent(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, char ***ret);
-int ask_password_keyring(const char *keyname, AskPasswordFlags flags, char ***ret);
-int ask_password_auto(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, char ***ret);
diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c
deleted file mode 100644
index 59a34a9d11..0000000000
--- a/src/shared/base-filesystem.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Kay Sievers
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "base-filesystem.h"
-#include "fd-util.h"
-#include "log.h"
-#include "macro.h"
-#include "string-util.h"
-#include "umask-util.h"
-#include "user-util.h"
-#include "util.h"
-
-typedef struct BaseFilesystem {
- const char *dir;
- mode_t mode;
- const char *target;
- const char *exists;
- bool ignore_failure;
-} BaseFilesystem;
-
-static const BaseFilesystem table[] = {
- { "bin", 0, "usr/bin\0", NULL },
- { "lib", 0, "usr/lib\0", NULL },
- { "root", 0755, NULL, NULL, true },
- { "sbin", 0, "usr/sbin\0", NULL },
- { "usr", 0755, NULL, NULL },
- { "var", 0755, NULL, NULL },
- { "etc", 0755, NULL, NULL },
-#if defined(__i386__) || defined(__x86_64__)
- { "lib64", 0, "usr/lib/x86_64-linux-gnu\0"
- "usr/lib64\0", "ld-linux-x86-64.so.2" },
-#endif
-};
-
-int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
- _cleanup_close_ int fd = -1;
- unsigned i;
- int r = 0;
-
- fd = open(root, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
- if (fd < 0)
- return log_error_errno(errno, "Failed to open root file system: %m");
-
- for (i = 0; i < ELEMENTSOF(table); i ++) {
- if (faccessat(fd, table[i].dir, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
- continue;
-
- if (table[i].target) {
- const char *target = NULL, *s;
-
- /* check if one of the targets exists */
- NULSTR_FOREACH(s, table[i].target) {
- if (faccessat(fd, s, F_OK, AT_SYMLINK_NOFOLLOW) < 0)
- continue;
-
- /* check if a specific file exists at the target path */
- if (table[i].exists) {
- _cleanup_free_ char *p = NULL;
-
- p = strjoin(s, "/", table[i].exists, NULL);
- if (!p)
- return log_oom();
-
- if (faccessat(fd, p, F_OK, AT_SYMLINK_NOFOLLOW) < 0)
- continue;
- }
-
- target = s;
- break;
- }
-
- if (!target)
- continue;
-
- r = symlinkat(target, fd, table[i].dir);
- if (r < 0 && errno != EEXIST)
- return log_error_errno(errno, "Failed to create symlink at %s/%s: %m", root, table[i].dir);
-
- if (uid != UID_INVALID || gid != UID_INVALID) {
- if (fchownat(fd, table[i].dir, uid, gid, AT_SYMLINK_NOFOLLOW) < 0)
- return log_error_errno(errno, "Failed to chown symlink at %s/%s: %m", root, table[i].dir);
- }
-
- continue;
- }
-
- RUN_WITH_UMASK(0000)
- r = mkdirat(fd, table[i].dir, table[i].mode);
- if (r < 0 && errno != EEXIST) {
- log_full_errno(table[i].ignore_failure ? LOG_DEBUG : LOG_ERR, errno,
- "Failed to create directory at %s/%s: %m", root, table[i].dir);
-
- if (!table[i].ignore_failure)
- return -errno;
- }
-
- if (uid != UID_INVALID || gid != UID_INVALID) {
- if (fchownat(fd, table[i].dir, uid, gid, AT_SYMLINK_NOFOLLOW) < 0)
- return log_error_errno(errno, "Failed to chown directory at %s/%s: %m", root, table[i].dir);
- }
- }
-
- return 0;
-}
diff --git a/src/shared/base-filesystem.h b/src/shared/base-filesystem.h
deleted file mode 100644
index 49599f0a60..0000000000
--- a/src/shared/base-filesystem.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Kay Sievers
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/types.h>
-
-int base_filesystem_create(const char *root, uid_t uid, gid_t gid);
diff --git a/src/shared/boot-timestamps.c b/src/shared/boot-timestamps.c
deleted file mode 100644
index 7e0152761c..0000000000
--- a/src/shared/boot-timestamps.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
- Copyright 2013 Kay Sievers
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "acpi-fpdt.h"
-#include "boot-timestamps.h"
-#include "efivars.h"
-#include "macro.h"
-#include "time-util.h"
-
-int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader) {
- usec_t x = 0, y = 0, a;
- int r;
- dual_timestamp _n;
-
- assert(firmware);
- assert(loader);
-
- if (!n) {
- dual_timestamp_get(&_n);
- n = &_n;
- }
-
- r = acpi_get_boot_usec(&x, &y);
- if (r < 0) {
- r = efi_loader_get_boot_usec(&x, &y);
- if (r < 0)
- return r;
- }
-
- /* Let's convert this to timestamps where the firmware
- * began/loader began working. To make this more confusing:
- * since usec_t is unsigned and the kernel's monotonic clock
- * begins at kernel initialization we'll actually initialize
- * the monotonic timestamps here as negative of the actual
- * value. */
-
- firmware->monotonic = y;
- loader->monotonic = y - x;
-
- a = n->monotonic + firmware->monotonic;
- firmware->realtime = n->realtime > a ? n->realtime - a : 0;
-
- a = n->monotonic + loader->monotonic;
- loader->realtime = n->realtime > a ? n->realtime - a : 0;
-
- return 0;
-}
diff --git a/src/shared/boot-timestamps.h b/src/shared/boot-timestamps.h
deleted file mode 100644
index 6f691026be..0000000000
--- a/src/shared/boot-timestamps.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
- Copyright 2013 Kay Sievers
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <time-util.h>
-
-int boot_timestamps(const dual_timestamp *n, dual_timestamp *firmware, dual_timestamp *loader);
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
deleted file mode 100644
index f639e0e832..0000000000
--- a/src/shared/bus-unit-util.c
+++ /dev/null
@@ -1,1350 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "alloc-util.h"
-#include "bus-internal.h"
-#include "bus-unit-util.h"
-#include "bus-util.h"
-#include "cgroup-util.h"
-#include "env-util.h"
-#include "escape.h"
-#include "hashmap.h"
-#include "list.h"
-#include "locale-util.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "rlimit-util.h"
-#include "signal-util.h"
-#include "string-util.h"
-#include "syslog-util.h"
-#include "terminal-util.h"
-#include "utf8.h"
-#include "util.h"
-
-int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
- assert(message);
- assert(u);
-
- u->machine = NULL;
-
- return sd_bus_message_read(
- message,
- "(ssssssouso)",
- &u->id,
- &u->description,
- &u->load_state,
- &u->active_state,
- &u->sub_state,
- &u->following,
- &u->unit_path,
- &u->job_id,
- &u->job_type,
- &u->job_path);
-}
-
-int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
- const char *eq, *field;
- int r, rl;
-
- assert(m);
- assert(assignment);
-
- eq = strchr(assignment, '=');
- if (!eq) {
- log_error("Not an assignment: %s", assignment);
- return -EINVAL;
- }
-
- r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
- if (r < 0)
- return bus_log_create_error(r);
-
- field = strndupa(assignment, eq - assignment);
- eq++;
-
- if (streq(field, "CPUQuota")) {
-
- if (isempty(eq))
- r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
- else {
- r = parse_percent_unbounded(eq);
- if (r <= 0) {
- log_error_errno(r, "CPU quota '%s' invalid.", eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U);
- }
-
- goto finish;
-
- } else if (streq(field, "EnvironmentFile")) {
-
- r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1,
- eq[0] == '-' ? eq + 1 : eq,
- eq[0] == '-');
- goto finish;
-
- } else if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec", "RuntimeMaxSec")) {
- char *n;
- usec_t t;
- size_t l;
-
- r = parse_sec(eq, &t);
- if (r < 0)
- return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq);
-
- l = strlen(field);
- n = newa(char, l + 2);
- if (!n)
- return log_oom();
-
- /* Change suffix Sec → USec */
- strcpy(mempcpy(n, field, l - 3), "USec");
- r = sd_bus_message_append(m, "sv", n, "t", t);
- goto finish;
-
- } else if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemoryLimit")) {
- uint64_t bytes;
-
- if (isempty(eq) || streq(eq, "infinity"))
- bytes = CGROUP_LIMIT_MAX;
- else {
- r = parse_percent(eq);
- if (r >= 0) {
- char *n;
-
- /* When this is a percentage we'll convert this into a relative value in the range
- * 0…UINT32_MAX and pass it in the MemoryLowScale property (and related
- * ones). This way the physical memory size can be determined server-side */
-
- n = strjoina(field, "Scale");
- r = sd_bus_message_append(m, "sv", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U));
- goto finish;
-
- } else {
- r = parse_size(eq, 1024, &bytes);
- if (r < 0)
- return log_error_errno(r, "Failed to parse bytes specification %s", assignment);
- }
- }
-
- r = sd_bus_message_append(m, "sv", field, "t", bytes);
- goto finish;
- } else if (streq(field, "TasksMax")) {
- uint64_t t;
-
- if (isempty(eq) || streq(eq, "infinity"))
- t = (uint64_t) -1;
- else {
- r = parse_percent(eq);
- if (r >= 0) {
- r = sd_bus_message_append(m, "sv", "TasksMaxScale", "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U));
- goto finish;
- } else {
- r = safe_atou64(eq, &t);
- if (r < 0)
- return log_error_errno(r, "Failed to parse maximum tasks specification %s", assignment);
- }
-
- }
-
- r = sd_bus_message_append(m, "sv", "TasksMax", "t", t);
- goto finish;
- }
-
- r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
- if (r < 0)
- return bus_log_create_error(r);
-
- rl = rlimit_from_string(field);
- if (rl >= 0) {
- const char *sn;
- struct rlimit l;
-
- r = rlimit_parse(rl, eq, &l);
- if (r < 0)
- return log_error_errno(r, "Failed to parse resource limit: %s", eq);
-
- r = sd_bus_message_append(m, "v", "t", l.rlim_max);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
- if (r < 0)
- return bus_log_create_error(r);
-
- sn = strjoina(field, "Soft");
- r = sd_bus_message_append(m, "sv", sn, "t", l.rlim_cur);
-
- } else if (STR_IN_SET(field,
- "CPUAccounting", "MemoryAccounting", "IOAccounting", "BlockIOAccounting", "TasksAccounting",
- "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
- "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
- "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers", "NoNewPrivileges",
- "SyslogLevelPrefix", "Delegate", "RemainAfterElapse", "MemoryDenyWriteExecute",
- "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
- "ProtectKernelModules", "ProtectControlGroups")) {
-
- r = parse_boolean(eq);
- if (r < 0)
- return log_error_errno(r, "Failed to parse boolean assignment %s.", assignment);
-
- r = sd_bus_message_append(m, "v", "b", r);
-
- } else if (STR_IN_SET(field, "CPUWeight", "StartupCPUWeight")) {
- uint64_t u;
-
- r = cg_weight_parse(eq, &u);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "t", u);
-
- } else if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) {
- uint64_t u;
-
- r = cg_cpu_shares_parse(eq, &u);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "t", u);
-
- } else if (STR_IN_SET(field, "IOWeight", "StartupIOWeight")) {
- uint64_t u;
-
- r = cg_weight_parse(eq, &u);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "t", u);
-
- } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) {
- uint64_t u;
-
- r = cg_blkio_weight_parse(eq, &u);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "t", u);
-
- } else if (STR_IN_SET(field,
- "User", "Group", "DevicePolicy", "KillMode",
- "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
- "StandardInput", "StandardOutput", "StandardError",
- "Description", "Slice", "Type", "WorkingDirectory",
- "RootDirectory", "SyslogIdentifier", "ProtectSystem",
- "ProtectHome", "SELinuxContext"))
- r = sd_bus_message_append(m, "v", "s", eq);
-
- else if (streq(field, "SyslogLevel")) {
- int level;
-
- level = log_level_from_string(eq);
- if (level < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", level);
-
- } else if (streq(field, "SyslogFacility")) {
- int facility;
-
- facility = log_facility_unshifted_from_string(eq);
- if (facility < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", facility);
-
- } else if (streq(field, "DeviceAllow")) {
-
- if (isempty(eq))
- r = sd_bus_message_append(m, "v", "a(ss)", 0);
- else {
- const char *path, *rwm, *e;
-
- e = strchr(eq, ' ');
- if (e) {
- path = strndupa(eq, e - eq);
- rwm = e+1;
- } else {
- path = eq;
- rwm = "";
- }
-
- if (!is_deviceallow_pattern(path)) {
- log_error("%s is not a device file in /dev.", path);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
- }
-
- } else if (cgroup_io_limit_type_from_string(field) >= 0 || STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
-
- if (isempty(eq))
- r = sd_bus_message_append(m, "v", "a(st)", 0);
- else {
- const char *path, *bandwidth, *e;
- uint64_t bytes;
-
- e = strchr(eq, ' ');
- if (e) {
- path = strndupa(eq, e - eq);
- bandwidth = e+1;
- } else {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- if (!path_startswith(path, "/dev")) {
- log_error("%s is not a device file in /dev.", path);
- return -EINVAL;
- }
-
- if (streq(bandwidth, "infinity")) {
- bytes = CGROUP_LIMIT_MAX;
- } else {
- r = parse_size(bandwidth, 1000, &bytes);
- if (r < 0) {
- log_error("Failed to parse byte value %s.", bandwidth);
- return -EINVAL;
- }
- }
-
- r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
- }
-
- } else if (STR_IN_SET(field, "IODeviceWeight", "BlockIODeviceWeight")) {
-
- if (isempty(eq))
- r = sd_bus_message_append(m, "v", "a(st)", 0);
- else {
- const char *path, *weight, *e;
- uint64_t u;
-
- e = strchr(eq, ' ');
- if (e) {
- path = strndupa(eq, e - eq);
- weight = e+1;
- } else {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- if (!path_startswith(path, "/dev")) {
- log_error("%s is not a device file in /dev.", path);
- return -EINVAL;
- }
-
- r = safe_atou64(weight, &u);
- if (r < 0) {
- log_error("Failed to parse %s value %s.", field, weight);
- return -EINVAL;
- }
- r = sd_bus_message_append(m, "v", "a(st)", 1, path, u);
- }
-
- } else if (streq(field, "Nice")) {
- int n;
-
- r = parse_nice(eq, &n);
- if (r < 0)
- return log_error_errno(r, "Failed to parse nice value: %s", eq);
-
- r = sd_bus_message_append(m, "v", "i", (int32_t) n);
-
- } else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
- const char *p;
-
- r = sd_bus_message_open_container(m, 'v', "as");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, 'a', "s");
- if (r < 0)
- return bus_log_create_error(r);
-
- p = eq;
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
- if (r < 0) {
- log_error("Failed to parse Environment value %s", eq);
- return -EINVAL;
- }
- if (r == 0)
- break;
-
- if (streq(field, "Environment")) {
- if (!env_assignment_is_valid(word)) {
- log_error("Invalid environment assignment: %s", word);
- return -EINVAL;
- }
- } else { /* PassEnvironment */
- if (!env_name_is_valid(word)) {
- log_error("Invalid environment variable name: %s", word);
- return -EINVAL;
- }
- }
-
- r = sd_bus_message_append_basic(m, 's', word);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
-
- } else if (streq(field, "KillSignal")) {
- int sig;
-
- sig = signal_from_string_try_harder(eq);
- if (sig < 0) {
- log_error("Failed to parse %s value %s.", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", sig);
-
- } else if (streq(field, "TimerSlackNSec")) {
- nsec_t n;
-
- r = parse_nsec(eq, &n);
- if (r < 0) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "t", n);
- } else if (streq(field, "OOMScoreAdjust")) {
- int oa;
-
- r = safe_atoi(eq, &oa);
- if (r < 0) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
-
- if (!oom_score_adjust_is_valid(oa)) {
- log_error("OOM score adjust value out of range");
- return -EINVAL;
- }
-
- r = sd_bus_message_append(m, "v", "i", oa);
- } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
- "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
- const char *p;
-
- r = sd_bus_message_open_container(m, 'v', "as");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, 'a', "s");
- if (r < 0)
- return bus_log_create_error(r);
-
- p = eq;
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
- int offset;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
- if (r < 0) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
- if (r == 0)
- break;
-
- if (!utf8_is_valid(word)) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
-
- offset = word[0] == '-';
- if (!path_is_absolute(word + offset)) {
- log_error("Failed to parse %s value %s", field, eq);
- return -EINVAL;
- }
-
- path_kill_slashes(word + offset);
-
- r = sd_bus_message_append_basic(m, 's', word);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
-
- } else if (streq(field, "RuntimeDirectory")) {
- const char *p;
-
- r = sd_bus_message_open_container(m, 'v', "as");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, 'a', "s");
- if (r < 0)
- return bus_log_create_error(r);
-
- p = eq;
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
- if (r < 0)
- return log_error_errno(r, "Failed to parse %s value %s", field, eq);
-
- if (r == 0)
- break;
-
- r = sd_bus_message_append_basic(m, 's', word);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
-
- } else {
- log_error("Unknown assignment %s.", assignment);
- return -EINVAL;
- }
-
-finish:
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- return 0;
-}
-
-int bus_append_unit_property_assignment_many(sd_bus_message *m, char **l) {
- char **i;
- int r;
-
- assert(m);
-
- STRV_FOREACH(i, l) {
- r = bus_append_unit_property_assignment(m, *i);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-typedef struct BusWaitForJobs {
- sd_bus *bus;
- Set *jobs;
-
- char *name;
- char *result;
-
- sd_bus_slot *slot_job_removed;
- sd_bus_slot *slot_disconnected;
-} BusWaitForJobs;
-
-static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- assert(m);
-
- log_error("Warning! D-Bus connection terminated.");
- sd_bus_close(sd_bus_message_get_bus(m));
-
- return 0;
-}
-
-static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- const char *path, *unit, *result;
- BusWaitForJobs *d = userdata;
- uint32_t id;
- char *found;
- int r;
-
- assert(m);
- assert(d);
-
- r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
- if (r < 0) {
- bus_log_parse_error(r);
- return 0;
- }
-
- found = set_remove(d->jobs, (char*) path);
- if (!found)
- return 0;
-
- free(found);
-
- if (!isempty(result))
- d->result = strdup(result);
-
- if (!isempty(unit))
- d->name = strdup(unit);
-
- return 0;
-}
-
-void bus_wait_for_jobs_free(BusWaitForJobs *d) {
- if (!d)
- return;
-
- set_free_free(d->jobs);
-
- sd_bus_slot_unref(d->slot_disconnected);
- sd_bus_slot_unref(d->slot_job_removed);
-
- sd_bus_unref(d->bus);
-
- free(d->name);
- free(d->result);
-
- free(d);
-}
-
-int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
- _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
- int r;
-
- assert(bus);
- assert(ret);
-
- d = new0(BusWaitForJobs, 1);
- if (!d)
- return -ENOMEM;
-
- d->bus = sd_bus_ref(bus);
-
- /* When we are a bus client we match by sender. Direct
- * connections OTOH have no initialized sender field, and
- * hence we ignore the sender then */
- r = sd_bus_add_match(
- bus,
- &d->slot_job_removed,
- bus->bus_client ?
- "type='signal',"
- "sender='org.freedesktop.systemd1',"
- "interface='org.freedesktop.systemd1.Manager',"
- "member='JobRemoved',"
- "path='/org/freedesktop/systemd1'" :
- "type='signal',"
- "interface='org.freedesktop.systemd1.Manager',"
- "member='JobRemoved',"
- "path='/org/freedesktop/systemd1'",
- match_job_removed, d);
- if (r < 0)
- return r;
-
- r = sd_bus_add_match(
- bus,
- &d->slot_disconnected,
- "type='signal',"
- "sender='org.freedesktop.DBus.Local',"
- "interface='org.freedesktop.DBus.Local',"
- "member='Disconnected'",
- match_disconnected, d);
- if (r < 0)
- return r;
-
- *ret = d;
- d = NULL;
-
- return 0;
-}
-
-static int bus_process_wait(sd_bus *bus) {
- int r;
-
- for (;;) {
- r = sd_bus_process(bus, NULL);
- if (r < 0)
- return r;
- if (r > 0)
- return 0;
-
- r = sd_bus_wait(bus, (uint64_t) -1);
- if (r < 0)
- return r;
- }
-}
-
-static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
- _cleanup_free_ char *dbus_path = NULL;
-
- assert(d);
- assert(d->name);
- assert(result);
-
- dbus_path = unit_dbus_path_from_name(d->name);
- if (!dbus_path)
- return -ENOMEM;
-
- return sd_bus_get_property_string(d->bus,
- "org.freedesktop.systemd1",
- dbus_path,
- "org.freedesktop.systemd1.Service",
- "Result",
- NULL,
- result);
-}
-
-static const struct {
- const char *result, *explanation;
-} explanations [] = {
- { "resources", "of unavailable resources or another system error" },
- { "timeout", "a timeout was exceeded" },
- { "exit-code", "the control process exited with error code" },
- { "signal", "a fatal signal was delivered to the control process" },
- { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
- { "watchdog", "the service failed to send watchdog ping" },
- { "start-limit", "start of the service was attempted too often" }
-};
-
-static void log_job_error_with_service_result(const char* service, const char *result, const char* const* extra_args) {
- _cleanup_free_ char *service_shell_quoted = NULL;
- const char *systemctl = "systemctl", *journalctl = "journalctl";
-
- assert(service);
-
- service_shell_quoted = shell_maybe_quote(service);
-
- if (extra_args && extra_args[1]) {
- _cleanup_free_ char *t;
-
- t = strv_join((char**) extra_args, " ");
- systemctl = strjoina("systemctl ", t ? : "<args>");
- journalctl = strjoina("journalctl ", t ? : "<args>");
- }
-
- if (!isempty(result)) {
- unsigned i;
-
- for (i = 0; i < ELEMENTSOF(explanations); ++i)
- if (streq(result, explanations[i].result))
- break;
-
- if (i < ELEMENTSOF(explanations)) {
- log_error("Job for %s failed because %s.\n"
- "See \"%s status %s\" and \"%s -xe\" for details.\n",
- service,
- explanations[i].explanation,
- systemctl,
- service_shell_quoted ?: "<service>",
- journalctl);
- goto finish;
- }
- }
-
- log_error("Job for %s failed.\n"
- "See \"%s status %s\" and \"%s -xe\" for details.\n",
- service,
- systemctl,
- service_shell_quoted ?: "<service>",
- journalctl);
-
-finish:
- /* For some results maybe additional explanation is required */
- if (streq_ptr(result, "start-limit"))
- log_info("To force a start use \"%1$s reset-failed %2$s\"\n"
- "followed by \"%1$s start %2$s\" again.",
- systemctl,
- service_shell_quoted ?: "<service>");
-}
-
-static int check_wait_response(BusWaitForJobs *d, bool quiet, const char* const* extra_args) {
- int r = 0;
-
- assert(d->result);
-
- if (!quiet) {
- if (streq(d->result, "canceled"))
- log_error("Job for %s canceled.", strna(d->name));
- else if (streq(d->result, "timeout"))
- log_error("Job for %s timed out.", strna(d->name));
- else if (streq(d->result, "dependency"))
- log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
- else if (streq(d->result, "invalid"))
- log_error("%s is not active, cannot reload.", strna(d->name));
- else if (streq(d->result, "assert"))
- log_error("Assertion failed on job for %s.", strna(d->name));
- else if (streq(d->result, "unsupported"))
- log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
- else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
- if (d->name) {
- int q;
- _cleanup_free_ char *result = NULL;
-
- q = bus_job_get_service_result(d, &result);
- if (q < 0)
- log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
-
- log_job_error_with_service_result(d->name, result, extra_args);
- } else
- log_error("Job failed. See \"journalctl -xe\" for details.");
- }
- }
-
- if (streq(d->result, "canceled"))
- r = -ECANCELED;
- else if (streq(d->result, "timeout"))
- r = -ETIME;
- else if (streq(d->result, "dependency"))
- r = -EIO;
- else if (streq(d->result, "invalid"))
- r = -ENOEXEC;
- else if (streq(d->result, "assert"))
- r = -EPROTO;
- else if (streq(d->result, "unsupported"))
- r = -EOPNOTSUPP;
- else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
- r = -EIO;
-
- return r;
-}
-
-int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char* const* extra_args) {
- int r = 0;
-
- assert(d);
-
- while (!set_isempty(d->jobs)) {
- int q;
-
- q = bus_process_wait(d->bus);
- if (q < 0)
- return log_error_errno(q, "Failed to wait for response: %m");
-
- if (d->result) {
- q = check_wait_response(d, quiet, extra_args);
- /* Return the first error as it is most likely to be
- * meaningful. */
- if (q < 0 && r == 0)
- r = q;
-
- log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
- }
-
- d->name = mfree(d->name);
- d->result = mfree(d->result);
- }
-
- return r;
-}
-
-int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
- int r;
-
- assert(d);
-
- r = set_ensure_allocated(&d->jobs, &string_hash_ops);
- if (r < 0)
- return r;
-
- return set_put_strdup(d->jobs, path);
-}
-
-int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) {
- int r;
-
- r = bus_wait_for_jobs_add(d, path);
- if (r < 0)
- return log_oom();
-
- return bus_wait_for_jobs(d, quiet, NULL);
-}
-
-int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
- const char *type, *path, *source;
- int r;
-
- /* changes is dereferenced when calling unit_file_dump_changes() later,
- * so we have to make sure this is not NULL. */
- assert(changes);
- assert(n_changes);
-
- r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
- if (r < 0)
- return bus_log_parse_error(r);
-
- while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
- /* We expect only "success" changes to be sent over the bus.
- Hence, reject anything negative. */
- UnitFileChangeType ch = unit_file_change_type_from_string(type);
-
- if (ch < 0) {
- log_notice("Manager reported unknown change type \"%s\" for path \"%s\", ignoring.", type, path);
- continue;
- }
-
- r = unit_file_changes_add(changes, n_changes, ch, path, source);
- if (r < 0)
- return r;
- }
- if (r < 0)
- return bus_log_parse_error(r);
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return bus_log_parse_error(r);
-
- unit_file_dump_changes(0, NULL, *changes, *n_changes, false);
- return 0;
-}
-
-struct CGroupInfo {
- char *cgroup_path;
- bool is_const; /* If false, cgroup_path should be free()'d */
-
- Hashmap *pids; /* PID → process name */
- bool done;
-
- struct CGroupInfo *parent;
- LIST_FIELDS(struct CGroupInfo, siblings);
- LIST_HEAD(struct CGroupInfo, children);
- size_t n_children;
-};
-
-static bool IS_ROOT(const char *p) {
- return isempty(p) || streq(p, "/");
-}
-
-static int add_cgroup(Hashmap *cgroups, const char *path, bool is_const, struct CGroupInfo **ret) {
- struct CGroupInfo *parent = NULL, *cg;
- int r;
-
- assert(cgroups);
- assert(ret);
-
- if (IS_ROOT(path))
- path = "/";
-
- cg = hashmap_get(cgroups, path);
- if (cg) {
- *ret = cg;
- return 0;
- }
-
- if (!IS_ROOT(path)) {
- const char *e, *pp;
-
- e = strrchr(path, '/');
- if (!e)
- return -EINVAL;
-
- pp = strndupa(path, e - path);
- if (!pp)
- return -ENOMEM;
-
- r = add_cgroup(cgroups, pp, false, &parent);
- if (r < 0)
- return r;
- }
-
- cg = new0(struct CGroupInfo, 1);
- if (!cg)
- return -ENOMEM;
-
- if (is_const)
- cg->cgroup_path = (char*) path;
- else {
- cg->cgroup_path = strdup(path);
- if (!cg->cgroup_path) {
- free(cg);
- return -ENOMEM;
- }
- }
-
- cg->is_const = is_const;
- cg->parent = parent;
-
- r = hashmap_put(cgroups, cg->cgroup_path, cg);
- if (r < 0) {
- if (!is_const)
- free(cg->cgroup_path);
- free(cg);
- return r;
- }
-
- if (parent) {
- LIST_PREPEND(siblings, parent->children, cg);
- parent->n_children++;
- }
-
- *ret = cg;
- return 1;
-}
-
-static int add_process(
- Hashmap *cgroups,
- const char *path,
- pid_t pid,
- const char *name) {
-
- struct CGroupInfo *cg;
- int r;
-
- assert(cgroups);
- assert(name);
- assert(pid > 0);
-
- r = add_cgroup(cgroups, path, true, &cg);
- if (r < 0)
- return r;
-
- r = hashmap_ensure_allocated(&cg->pids, &trivial_hash_ops);
- if (r < 0)
- return r;
-
- return hashmap_put(cg->pids, PID_TO_PTR(pid), (void*) name);
-}
-
-static void remove_cgroup(Hashmap *cgroups, struct CGroupInfo *cg) {
- assert(cgroups);
- assert(cg);
-
- while (cg->children)
- remove_cgroup(cgroups, cg->children);
-
- hashmap_remove(cgroups, cg->cgroup_path);
-
- if (!cg->is_const)
- free(cg->cgroup_path);
-
- hashmap_free(cg->pids);
-
- if (cg->parent)
- LIST_REMOVE(siblings, cg->parent->children, cg);
-
- free(cg);
-}
-
-static int cgroup_info_compare_func(const void *a, const void *b) {
- const struct CGroupInfo *x = *(const struct CGroupInfo* const*) a, *y = *(const struct CGroupInfo* const*) b;
-
- assert(x);
- assert(y);
-
- return strcmp(x->cgroup_path, y->cgroup_path);
-}
-
-static int dump_processes(
- Hashmap *cgroups,
- const char *cgroup_path,
- const char *prefix,
- unsigned n_columns,
- OutputFlags flags) {
-
- struct CGroupInfo *cg;
- int r;
-
- assert(prefix);
-
- if (IS_ROOT(cgroup_path))
- cgroup_path = "/";
-
- cg = hashmap_get(cgroups, cgroup_path);
- if (!cg)
- return 0;
-
- if (!hashmap_isempty(cg->pids)) {
- const char *name;
- size_t n = 0, i;
- pid_t *pids;
- void *pidp;
- Iterator j;
- int width;
-
- /* Order processes by their PID */
- pids = newa(pid_t, hashmap_size(cg->pids));
-
- HASHMAP_FOREACH_KEY(name, pidp, cg->pids, j)
- pids[n++] = PTR_TO_PID(pidp);
-
- assert(n == hashmap_size(cg->pids));
- qsort_safe(pids, n, sizeof(pid_t), pid_compare_func);
-
- width = DECIMAL_STR_WIDTH(pids[n-1]);
-
- for (i = 0; i < n; i++) {
- _cleanup_free_ char *e = NULL;
- const char *special;
- bool more;
-
- name = hashmap_get(cg->pids, PID_TO_PTR(pids[i]));
- assert(name);
-
- if (n_columns != 0) {
- unsigned k;
-
- k = MAX(LESS_BY(n_columns, 2U + width + 1U), 20U);
-
- e = ellipsize(name, k, 100);
- if (e)
- name = e;
- }
-
- more = i+1 < n || cg->children;
- special = special_glyph(more ? TREE_BRANCH : TREE_RIGHT);
-
- fprintf(stdout, "%s%s%*"PID_PRI" %s\n",
- prefix,
- special,
- width, pids[i],
- name);
- }
- }
-
- if (cg->children) {
- struct CGroupInfo **children, *child;
- size_t n = 0, i;
-
- /* Order subcgroups by their name */
- children = newa(struct CGroupInfo*, cg->n_children);
- LIST_FOREACH(siblings, child, cg->children)
- children[n++] = child;
- assert(n == cg->n_children);
- qsort_safe(children, n, sizeof(struct CGroupInfo*), cgroup_info_compare_func);
-
- if (n_columns != 0)
- n_columns = MAX(LESS_BY(n_columns, 2U), 20U);
-
- for (i = 0; i < n; i++) {
- _cleanup_free_ char *pp = NULL;
- const char *name, *special;
- bool more;
-
- child = children[i];
-
- name = strrchr(child->cgroup_path, '/');
- if (!name)
- return -EINVAL;
- name++;
-
- more = i+1 < n;
- special = special_glyph(more ? TREE_BRANCH : TREE_RIGHT);
-
- fputs(prefix, stdout);
- fputs(special, stdout);
- fputs(name, stdout);
- fputc('\n', stdout);
-
- special = special_glyph(more ? TREE_VERTICAL : TREE_SPACE);
-
- pp = strappend(prefix, special);
- if (!pp)
- return -ENOMEM;
-
- r = dump_processes(cgroups, child->cgroup_path, pp, n_columns, flags);
- if (r < 0)
- return r;
- }
- }
-
- cg->done = true;
- return 0;
-}
-
-static int dump_extra_processes(
- Hashmap *cgroups,
- const char *prefix,
- unsigned n_columns,
- OutputFlags flags) {
-
- _cleanup_free_ pid_t *pids = NULL;
- _cleanup_hashmap_free_ Hashmap *names = NULL;
- struct CGroupInfo *cg;
- size_t n_allocated = 0, n = 0, k;
- Iterator i;
- int width, r;
-
- /* Prints the extra processes, i.e. those that are in cgroups we haven't displayed yet. We show them as
- * combined, sorted, linear list. */
-
- HASHMAP_FOREACH(cg, cgroups, i) {
- const char *name;
- void *pidp;
- Iterator j;
-
- if (cg->done)
- continue;
-
- if (hashmap_isempty(cg->pids))
- continue;
-
- r = hashmap_ensure_allocated(&names, &trivial_hash_ops);
- if (r < 0)
- return r;
-
- if (!GREEDY_REALLOC(pids, n_allocated, n + hashmap_size(cg->pids)))
- return -ENOMEM;
-
- HASHMAP_FOREACH_KEY(name, pidp, cg->pids, j) {
- pids[n++] = PTR_TO_PID(pidp);
-
- r = hashmap_put(names, pidp, (void*) name);
- if (r < 0)
- return r;
- }
- }
-
- if (n == 0)
- return 0;
-
- qsort_safe(pids, n, sizeof(pid_t), pid_compare_func);
- width = DECIMAL_STR_WIDTH(pids[n-1]);
-
- for (k = 0; k < n; k++) {
- _cleanup_free_ char *e = NULL;
- const char *name;
-
- name = hashmap_get(names, PID_TO_PTR(pids[k]));
- assert(name);
-
- if (n_columns != 0) {
- unsigned z;
-
- z = MAX(LESS_BY(n_columns, 2U + width + 1U), 20U);
-
- e = ellipsize(name, z, 100);
- if (e)
- name = e;
- }
-
- fprintf(stdout, "%s%s %*" PID_PRI " %s\n",
- prefix,
- special_glyph(TRIANGULAR_BULLET),
- width, pids[k],
- name);
- }
-
- return 0;
-}
-
-int unit_show_processes(
- sd_bus *bus,
- const char *unit,
- const char *cgroup_path,
- const char *prefix,
- unsigned n_columns,
- OutputFlags flags,
- sd_bus_error *error) {
-
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- Hashmap *cgroups = NULL;
- struct CGroupInfo *cg;
- int r;
-
- assert(bus);
- assert(unit);
-
- if (flags & OUTPUT_FULL_WIDTH)
- n_columns = 0;
- else if (n_columns <= 0)
- n_columns = columns();
-
- prefix = strempty(prefix);
-
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "GetUnitProcesses",
- error,
- &reply,
- "s",
- unit);
- if (r < 0)
- return r;
-
- cgroups = hashmap_new(&string_hash_ops);
- if (!cgroups)
- return -ENOMEM;
-
- r = sd_bus_message_enter_container(reply, 'a', "(sus)");
- if (r < 0)
- goto finish;
-
- for (;;) {
- const char *path = NULL, *name = NULL;
- uint32_t pid;
-
- r = sd_bus_message_read(reply, "(sus)", &path, &pid, &name);
- if (r < 0)
- goto finish;
- if (r == 0)
- break;
-
- r = add_process(cgroups, path, pid, name);
- if (r < 0)
- goto finish;
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- goto finish;
-
- r = dump_processes(cgroups, cgroup_path, prefix, n_columns, flags);
- if (r < 0)
- goto finish;
-
- r = dump_extra_processes(cgroups, prefix, n_columns, flags);
-
-finish:
- while ((cg = hashmap_first(cgroups)))
- remove_cgroup(cgroups, cg);
-
- hashmap_free(cgroups);
-
- return r;
-}
diff --git a/src/shared/bus-unit-util.h b/src/shared/bus-unit-util.h
deleted file mode 100644
index d102ea180e..0000000000
--- a/src/shared/bus-unit-util.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-
-#include "output-mode.h"
-#include "install.h"
-
-typedef struct UnitInfo {
- const char *machine;
- const char *id;
- const char *description;
- const char *load_state;
- const char *active_state;
- const char *sub_state;
- const char *following;
- const char *unit_path;
- uint32_t job_id;
- const char *job_type;
- const char *job_path;
-} UnitInfo;
-
-int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u);
-
-int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment);
-int bus_append_unit_property_assignment_many(sd_bus_message *m, char **l);
-
-typedef struct BusWaitForJobs BusWaitForJobs;
-
-int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret);
-void bus_wait_for_jobs_free(BusWaitForJobs *d);
-int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path);
-int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char* const* extra_args);
-int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(BusWaitForJobs*, bus_wait_for_jobs_free);
-
-int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes);
-
-int unit_show_processes(sd_bus *bus, const char *unit, const char *cgroup_path, const char *prefix, unsigned n_columns, OutputFlags flags, sd_bus_error *error);
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
deleted file mode 100644
index bb90c89cc2..0000000000
--- a/src/shared/bus-util.c
+++ /dev/null
@@ -1,1567 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "sd-bus-protocol.h"
-#include "sd-bus.h"
-#include "sd-daemon.h"
-#include "sd-event.h"
-#include "sd-id128.h"
-
-#include "alloc-util.h"
-#include "bus-internal.h"
-#include "bus-label.h"
-#include "bus-message.h"
-#include "bus-util.h"
-#include "def.h"
-#include "escape.h"
-#include "fd-util.h"
-#include "missing.h"
-#include "parse-util.h"
-#include "proc-cmdline.h"
-#include "rlimit-util.h"
-#include "stdio-util.h"
-#include "strv.h"
-#include "user-util.h"
-
-static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- sd_event *e = userdata;
-
- assert(m);
- assert(e);
-
- sd_bus_close(sd_bus_message_get_bus(m));
- sd_event_exit(e, 0);
-
- return 1;
-}
-
-int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
- _cleanup_free_ char *match = NULL;
- const char *unique;
- int r;
-
- assert(e);
- assert(bus);
- assert(name);
-
- /* We unregister the name here and then wait for the
- * NameOwnerChanged signal for this event to arrive before we
- * quit. We do this in order to make sure that any queued
- * requests are still processed before we really exit. */
-
- r = sd_bus_get_unique_name(bus, &unique);
- if (r < 0)
- return r;
-
- r = asprintf(&match,
- "sender='org.freedesktop.DBus',"
- "type='signal',"
- "interface='org.freedesktop.DBus',"
- "member='NameOwnerChanged',"
- "path='/org/freedesktop/DBus',"
- "arg0='%s',"
- "arg1='%s',"
- "arg2=''", name, unique);
- if (r < 0)
- return -ENOMEM;
-
- r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
- if (r < 0)
- return r;
-
- r = sd_bus_release_name(bus, name);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-int bus_event_loop_with_idle(
- sd_event *e,
- sd_bus *bus,
- const char *name,
- usec_t timeout,
- check_idle_t check_idle,
- void *userdata) {
- bool exiting = false;
- int r, code;
-
- assert(e);
- assert(bus);
- assert(name);
-
- for (;;) {
- bool idle;
-
- r = sd_event_get_state(e);
- if (r < 0)
- return r;
- if (r == SD_EVENT_FINISHED)
- break;
-
- if (check_idle)
- idle = check_idle(userdata);
- else
- idle = true;
-
- r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout);
- if (r < 0)
- return r;
-
- if (r == 0 && !exiting && idle) {
-
- r = sd_bus_try_close(bus);
- if (r == -EBUSY)
- continue;
-
- /* Fallback for dbus1 connections: we
- * unregister the name and wait for the
- * response to come through for it */
- if (r == -EOPNOTSUPP) {
-
- /* Inform the service manager that we
- * are going down, so that it will
- * queue all further start requests,
- * instead of assuming we are already
- * running. */
- sd_notify(false, "STOPPING=1");
-
- r = bus_async_unregister_and_exit(e, bus, name);
- if (r < 0)
- return r;
-
- exiting = true;
- continue;
- }
-
- if (r < 0)
- return r;
-
- sd_event_exit(e, 0);
- break;
- }
- }
-
- r = sd_event_get_exit_code(e, &code);
- if (r < 0)
- return r;
-
- return code;
-}
-
-int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *rep = NULL;
- int r, has_owner = 0;
-
- assert(c);
- assert(name);
-
- r = sd_bus_call_method(c,
- "org.freedesktop.DBus",
- "/org/freedesktop/dbus",
- "org.freedesktop.DBus",
- "NameHasOwner",
- error,
- &rep,
- "s",
- name);
- if (r < 0)
- return r;
-
- r = sd_bus_message_read_basic(rep, 'b', &has_owner);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
-
- return has_owner;
-}
-
-static int check_good_user(sd_bus_message *m, uid_t good_user) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- uid_t sender_uid;
- int r;
-
- assert(m);
-
- if (good_user == UID_INVALID)
- return 0;
-
- r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds);
- if (r < 0)
- return r;
-
- /* Don't trust augmented credentials for authorization */
- assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
-
- r = sd_bus_creds_get_euid(creds, &sender_uid);
- if (r < 0)
- return r;
-
- return sender_uid == good_user;
-}
-
-int bus_test_polkit(
- sd_bus_message *call,
- int capability,
- const char *action,
- const char **details,
- uid_t good_user,
- bool *_challenge,
- sd_bus_error *e) {
-
- int r;
-
- assert(call);
- assert(action);
-
- /* Tests non-interactively! */
-
- r = check_good_user(call, good_user);
- if (r != 0)
- return r;
-
- r = sd_bus_query_sender_privilege(call, capability);
- if (r < 0)
- return r;
- else if (r > 0)
- return 1;
-#ifdef ENABLE_POLKIT
- else {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- int authorized = false, challenge = false;
- const char *sender, **k, **v;
-
- sender = sd_bus_message_get_sender(call);
- if (!sender)
- return -EBADMSG;
-
- r = sd_bus_message_new_method_call(
- call->bus,
- &request,
- "org.freedesktop.PolicyKit1",
- "/org/freedesktop/PolicyKit1/Authority",
- "org.freedesktop.PolicyKit1.Authority",
- "CheckAuthorization");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(
- request,
- "(sa{sv})s",
- "system-bus-name", 1, "name", "s", sender,
- action);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(request, 'a', "{ss}");
- if (r < 0)
- return r;
-
- STRV_FOREACH_PAIR(k, v, details) {
- r = sd_bus_message_append(request, "{ss}", *k, *v);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(request);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(request, "us", 0, NULL);
- if (r < 0)
- return r;
-
- r = sd_bus_call(call->bus, request, 0, e, &reply);
- if (r < 0) {
- /* Treat no PK available as access denied */
- if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
- sd_bus_error_free(e);
- return -EACCES;
- }
-
- return r;
- }
-
- r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
- if (r < 0)
- return r;
-
- r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
- if (r < 0)
- return r;
-
- if (authorized)
- return 1;
-
- if (_challenge) {
- *_challenge = challenge;
- return 0;
- }
- }
-#endif
-
- return -EACCES;
-}
-
-#ifdef ENABLE_POLKIT
-
-typedef struct AsyncPolkitQuery {
- sd_bus_message *request, *reply;
- sd_bus_message_handler_t callback;
- void *userdata;
- sd_bus_slot *slot;
- Hashmap *registry;
-} AsyncPolkitQuery;
-
-static void async_polkit_query_free(AsyncPolkitQuery *q) {
-
- if (!q)
- return;
-
- sd_bus_slot_unref(q->slot);
-
- if (q->registry && q->request)
- hashmap_remove(q->registry, q->request);
-
- sd_bus_message_unref(q->request);
- sd_bus_message_unref(q->reply);
-
- free(q);
-}
-
-static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
- _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
- AsyncPolkitQuery *q = userdata;
- int r;
-
- assert(reply);
- assert(q);
-
- q->slot = sd_bus_slot_unref(q->slot);
- q->reply = sd_bus_message_ref(reply);
-
- r = sd_bus_message_rewind(q->request, true);
- if (r < 0) {
- r = sd_bus_reply_method_errno(q->request, r, NULL);
- goto finish;
- }
-
- r = q->callback(q->request, q->userdata, &error_buffer);
- r = bus_maybe_reply_error(q->request, r, &error_buffer);
-
-finish:
- async_polkit_query_free(q);
-
- return r;
-}
-
-#endif
-
-int bus_verify_polkit_async(
- sd_bus_message *call,
- int capability,
- const char *action,
- const char **details,
- bool interactive,
- uid_t good_user,
- Hashmap **registry,
- sd_bus_error *error) {
-
-#ifdef ENABLE_POLKIT
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
- AsyncPolkitQuery *q;
- const char *sender, **k, **v;
- sd_bus_message_handler_t callback;
- void *userdata;
- int c;
-#endif
- int r;
-
- assert(call);
- assert(action);
- assert(registry);
-
- r = check_good_user(call, good_user);
- if (r != 0)
- return r;
-
-#ifdef ENABLE_POLKIT
- q = hashmap_get(*registry, call);
- if (q) {
- int authorized, challenge;
-
- /* This is the second invocation of this function, and
- * there's already a response from polkit, let's
- * process it */
- assert(q->reply);
-
- if (sd_bus_message_is_method_error(q->reply, NULL)) {
- const sd_bus_error *e;
-
- /* Copy error from polkit reply */
- e = sd_bus_message_get_error(q->reply);
- sd_bus_error_copy(error, e);
-
- /* Treat no PK available as access denied */
- if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
- return -EACCES;
-
- return -sd_bus_error_get_errno(e);
- }
-
- r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
- if (r >= 0)
- r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
-
- if (r < 0)
- return r;
-
- if (authorized)
- return 1;
-
- if (challenge)
- return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
-
- return -EACCES;
- }
-#endif
-
- r = sd_bus_query_sender_privilege(call, capability);
- if (r < 0)
- return r;
- else if (r > 0)
- return 1;
-
-#ifdef ENABLE_POLKIT
- if (sd_bus_get_current_message(call->bus) != call)
- return -EINVAL;
-
- callback = sd_bus_get_current_handler(call->bus);
- if (!callback)
- return -EINVAL;
-
- userdata = sd_bus_get_current_userdata(call->bus);
-
- sender = sd_bus_message_get_sender(call);
- if (!sender)
- return -EBADMSG;
-
- c = sd_bus_message_get_allow_interactive_authorization(call);
- if (c < 0)
- return c;
- if (c > 0)
- interactive = true;
-
- r = hashmap_ensure_allocated(registry, NULL);
- if (r < 0)
- return r;
-
- r = sd_bus_message_new_method_call(
- call->bus,
- &pk,
- "org.freedesktop.PolicyKit1",
- "/org/freedesktop/PolicyKit1/Authority",
- "org.freedesktop.PolicyKit1.Authority",
- "CheckAuthorization");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(
- pk,
- "(sa{sv})s",
- "system-bus-name", 1, "name", "s", sender,
- action);
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(pk, 'a', "{ss}");
- if (r < 0)
- return r;
-
- STRV_FOREACH_PAIR(k, v, details) {
- r = sd_bus_message_append(pk, "{ss}", *k, *v);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(pk);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(pk, "us", !!interactive, NULL);
- if (r < 0)
- return r;
-
- q = new0(AsyncPolkitQuery, 1);
- if (!q)
- return -ENOMEM;
-
- q->request = sd_bus_message_ref(call);
- q->callback = callback;
- q->userdata = userdata;
-
- r = hashmap_put(*registry, call, q);
- if (r < 0) {
- async_polkit_query_free(q);
- return r;
- }
-
- q->registry = *registry;
-
- r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
- if (r < 0) {
- async_polkit_query_free(q);
- return r;
- }
-
- return 0;
-#endif
-
- return -EACCES;
-}
-
-void bus_verify_polkit_async_registry_free(Hashmap *registry) {
-#ifdef ENABLE_POLKIT
- AsyncPolkitQuery *q;
-
- while ((q = hashmap_steal_first(registry)))
- async_polkit_query_free(q);
-
- hashmap_free(registry);
-#endif
-}
-
-int bus_check_peercred(sd_bus *c) {
- struct ucred ucred;
- socklen_t l;
- int fd;
-
- assert(c);
-
- fd = sd_bus_get_fd(c);
- if (fd < 0)
- return fd;
-
- l = sizeof(struct ucred);
- if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
- return -errno;
-
- if (l != sizeof(struct ucred))
- return -E2BIG;
-
- if (ucred.uid != 0 && ucred.uid != geteuid())
- return -EPERM;
-
- return 1;
-}
-
-int bus_connect_system_systemd(sd_bus **_bus) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
- int r;
-
- assert(_bus);
-
- if (geteuid() != 0)
- return sd_bus_default_system(_bus);
-
- /* If we are root and kdbus is not available, then let's talk
- * directly to the system instance, instead of going via the
- * bus */
-
- r = sd_bus_new(&bus);
- if (r < 0)
- return r;
-
- r = sd_bus_set_address(bus, KERNEL_SYSTEM_BUS_ADDRESS);
- if (r < 0)
- return r;
-
- bus->bus_client = true;
-
- r = sd_bus_start(bus);
- if (r >= 0) {
- *_bus = bus;
- bus = NULL;
- return 0;
- }
-
- bus = sd_bus_unref(bus);
-
- r = sd_bus_new(&bus);
- if (r < 0)
- return r;
-
- r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
- if (r < 0)
- return r;
-
- r = sd_bus_start(bus);
- if (r < 0)
- return sd_bus_default_system(_bus);
-
- r = bus_check_peercred(bus);
- if (r < 0)
- return r;
-
- *_bus = bus;
- bus = NULL;
-
- return 0;
-}
-
-int bus_connect_user_systemd(sd_bus **_bus) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
- _cleanup_free_ char *ee = NULL;
- const char *e;
- int r;
-
- /* Try via kdbus first, and then directly */
-
- assert(_bus);
-
- r = sd_bus_new(&bus);
- if (r < 0)
- return r;
-
- if (asprintf(&bus->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()) < 0)
- return -ENOMEM;
-
- bus->bus_client = true;
-
- r = sd_bus_start(bus);
- if (r >= 0) {
- *_bus = bus;
- bus = NULL;
- return 0;
- }
-
- bus = sd_bus_unref(bus);
-
- e = secure_getenv("XDG_RUNTIME_DIR");
- if (!e)
- return sd_bus_default_user(_bus);
-
- ee = bus_address_escape(e);
- if (!ee)
- return -ENOMEM;
-
- r = sd_bus_new(&bus);
- if (r < 0)
- return r;
-
- bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
- if (!bus->address)
- return -ENOMEM;
-
- r = sd_bus_start(bus);
- if (r < 0)
- return sd_bus_default_user(_bus);
-
- r = bus_check_peercred(bus);
- if (r < 0)
- return r;
-
- *_bus = bus;
- bus = NULL;
-
- return 0;
-}
-
-#define print_property(name, fmt, ...) \
- do { \
- if (value) \
- printf(fmt "\n", __VA_ARGS__); \
- else \
- printf("%s=" fmt "\n", name, __VA_ARGS__); \
- } while(0)
-
-int bus_print_property(const char *name, sd_bus_message *property, bool value, bool all) {
- char type;
- const char *contents;
- int r;
-
- assert(name);
- assert(property);
-
- r = sd_bus_message_peek_type(property, &type, &contents);
- if (r < 0)
- return r;
-
- switch (type) {
-
- case SD_BUS_TYPE_STRING: {
- const char *s;
-
- r = sd_bus_message_read_basic(property, type, &s);
- if (r < 0)
- return r;
-
- if (all || !isempty(s)) {
- _cleanup_free_ char *escaped = NULL;
-
- escaped = xescape(s, "\n");
- if (!escaped)
- return -ENOMEM;
-
- print_property(name, "%s", escaped);
- }
-
- return 1;
- }
-
- case SD_BUS_TYPE_BOOLEAN: {
- int b;
-
- r = sd_bus_message_read_basic(property, type, &b);
- if (r < 0)
- return r;
-
- print_property(name, "%s", yes_no(b));
-
- return 1;
- }
-
- case SD_BUS_TYPE_UINT64: {
- uint64_t u;
-
- r = sd_bus_message_read_basic(property, type, &u);
- if (r < 0)
- return r;
-
- /* Yes, heuristics! But we can change this check
- * should it turn out to not be sufficient */
-
- if (endswith(name, "Timestamp")) {
- char timestamp[FORMAT_TIMESTAMP_MAX], *t;
-
- t = format_timestamp(timestamp, sizeof(timestamp), u);
- if (t || all)
- print_property(name, "%s", strempty(t));
-
- } else if (strstr(name, "USec")) {
- char timespan[FORMAT_TIMESPAN_MAX];
-
- print_property(name, "%s", format_timespan(timespan, sizeof(timespan), u, 0));
- } else
- print_property(name, "%"PRIu64, u);
-
- return 1;
- }
-
- case SD_BUS_TYPE_INT64: {
- int64_t i;
-
- r = sd_bus_message_read_basic(property, type, &i);
- if (r < 0)
- return r;
-
- print_property(name, "%"PRIi64, i);
-
- return 1;
- }
-
- case SD_BUS_TYPE_UINT32: {
- uint32_t u;
-
- r = sd_bus_message_read_basic(property, type, &u);
- if (r < 0)
- return r;
-
- if (strstr(name, "UMask") || strstr(name, "Mode"))
- print_property(name, "%04o", u);
- else
- print_property(name, "%"PRIu32, u);
-
- return 1;
- }
-
- case SD_BUS_TYPE_INT32: {
- int32_t i;
-
- r = sd_bus_message_read_basic(property, type, &i);
- if (r < 0)
- return r;
-
- print_property(name, "%"PRIi32, i);
- return 1;
- }
-
- case SD_BUS_TYPE_DOUBLE: {
- double d;
-
- r = sd_bus_message_read_basic(property, type, &d);
- if (r < 0)
- return r;
-
- print_property(name, "%g", d);
- return 1;
- }
-
- case SD_BUS_TYPE_ARRAY:
- if (streq(contents, "s")) {
- bool first = true;
- const char *str;
-
- r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
- _cleanup_free_ char *escaped = NULL;
-
- if (first && !value)
- printf("%s=", name);
-
- escaped = xescape(str, "\n ");
- if (!escaped)
- return -ENOMEM;
-
- printf("%s%s", first ? "" : " ", escaped);
-
- first = false;
- }
- if (r < 0)
- return r;
-
- if (first && all && !value)
- printf("%s=", name);
- if (!first || all)
- puts("");
-
- r = sd_bus_message_exit_container(property);
- if (r < 0)
- return r;
-
- return 1;
-
- } else if (streq(contents, "y")) {
- const uint8_t *u;
- size_t n;
-
- r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
- if (r < 0)
- return r;
-
- if (all || n > 0) {
- unsigned int i;
-
- if (!value)
- printf("%s=", name);
-
- for (i = 0; i < n; i++)
- printf("%02x", u[i]);
-
- puts("");
- }
-
- return 1;
-
- } else if (streq(contents, "u")) {
- uint32_t *u;
- size_t n;
-
- r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
- if (r < 0)
- return r;
-
- if (all || n > 0) {
- unsigned int i;
-
- if (!value)
- printf("%s=", name);
-
- for (i = 0; i < n; i++)
- printf("%08x", u[i]);
-
- puts("");
- }
-
- return 1;
- }
-
- break;
- }
-
- return 0;
-}
-
-int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool value, bool all) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- int r;
-
- assert(bus);
- assert(path);
-
- r = sd_bus_call_method(bus,
- dest,
- path,
- "org.freedesktop.DBus.Properties",
- "GetAll",
- &error,
- &reply,
- "s", "");
- if (r < 0)
- return r;
-
- r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
- const char *name;
- const char *contents;
-
- r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
- if (r < 0)
- return r;
-
- if (!filter || strv_find(filter, name)) {
- r = sd_bus_message_peek_type(reply, NULL, &contents);
- if (r < 0)
- return r;
-
- r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
- if (r < 0)
- return r;
-
- r = bus_print_property(name, reply, value, all);
- if (r < 0)
- return r;
- if (r == 0) {
- if (all)
- printf("%s=[unprintable]\n", name);
- /* skip what we didn't read */
- r = sd_bus_message_skip(reply, contents);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return r;
- } else {
- r = sd_bus_message_skip(reply, "v");
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return r;
- }
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
- sd_id128_t *p = userdata;
- const void *v;
- size_t n;
- int r;
-
- r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
- if (r < 0)
- return r;
-
- if (n == 0)
- *p = SD_ID128_NULL;
- else if (n == 16)
- memcpy((*p).bytes, v, n);
- else
- return -EINVAL;
-
- return 0;
-}
-
-static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
- char type;
- int r;
-
- r = sd_bus_message_peek_type(m, &type, NULL);
- if (r < 0)
- return r;
-
- switch (type) {
-
- case SD_BUS_TYPE_STRING: {
- char **p = userdata;
- const char *s;
-
- r = sd_bus_message_read_basic(m, type, &s);
- if (r < 0)
- return r;
-
- if (isempty(s))
- s = NULL;
-
- return free_and_strdup(p, s);
- }
-
- case SD_BUS_TYPE_ARRAY: {
- _cleanup_strv_free_ char **l = NULL;
- char ***p = userdata;
-
- r = bus_message_read_strv_extend(m, &l);
- if (r < 0)
- return r;
-
- strv_free(*p);
- *p = l;
- l = NULL;
- return 0;
- }
-
- case SD_BUS_TYPE_BOOLEAN: {
- unsigned b;
- int *p = userdata;
-
- r = sd_bus_message_read_basic(m, type, &b);
- if (r < 0)
- return r;
-
- *p = b;
- return 0;
- }
-
- case SD_BUS_TYPE_INT32:
- case SD_BUS_TYPE_UINT32: {
- uint32_t u, *p = userdata;
-
- r = sd_bus_message_read_basic(m, type, &u);
- if (r < 0)
- return r;
-
- *p = u;
- return 0;
- }
-
- case SD_BUS_TYPE_INT64:
- case SD_BUS_TYPE_UINT64: {
- uint64_t t, *p = userdata;
-
- r = sd_bus_message_read_basic(m, type, &t);
- if (r < 0)
- return r;
-
- *p = t;
- return 0;
- }
-
- case SD_BUS_TYPE_DOUBLE: {
- double d, *p = userdata;
-
- r = sd_bus_message_read_basic(m, type, &d);
- if (r < 0)
- return r;
-
- *p = d;
- return 0;
- }}
-
- return -EOPNOTSUPP;
-}
-
-int bus_message_map_all_properties(
- sd_bus_message *m,
- const struct bus_properties_map *map,
- void *userdata) {
-
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- int r;
-
- assert(m);
- assert(map);
-
- r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
- if (r < 0)
- return r;
-
- while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
- const struct bus_properties_map *prop;
- const char *member;
- const char *contents;
- void *v;
- unsigned i;
-
- r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
- if (r < 0)
- return r;
-
- for (i = 0, prop = NULL; map[i].member; i++)
- if (streq(map[i].member, member)) {
- prop = &map[i];
- break;
- }
-
- if (prop) {
- r = sd_bus_message_peek_type(m, NULL, &contents);
- if (r < 0)
- return r;
-
- r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
- if (r < 0)
- return r;
-
- v = (uint8_t *)userdata + prop->offset;
- if (map[i].set)
- r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v);
- else
- r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v);
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return r;
- } else {
- r = sd_bus_message_skip(m, "v");
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return r;
- }
- if (r < 0)
- return r;
-
- return sd_bus_message_exit_container(m);
-}
-
-int bus_message_map_properties_changed(
- sd_bus_message *m,
- const struct bus_properties_map *map,
- void *userdata) {
-
- const char *member;
- int r, invalidated, i;
-
- assert(m);
- assert(map);
-
- r = bus_message_map_all_properties(m, map, userdata);
- if (r < 0)
- return r;
-
- r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
- if (r < 0)
- return r;
-
- invalidated = 0;
- while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0)
- for (i = 0; map[i].member; i++)
- if (streq(map[i].member, member)) {
- ++invalidated;
- break;
- }
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return r;
-
- return invalidated;
-}
-
-int bus_map_all_properties(
- sd_bus *bus,
- const char *destination,
- const char *path,
- const struct bus_properties_map *map,
- void *userdata) {
-
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- int r;
-
- assert(bus);
- assert(destination);
- assert(path);
- assert(map);
-
- r = sd_bus_call_method(
- bus,
- destination,
- path,
- "org.freedesktop.DBus.Properties",
- "GetAll",
- &error,
- &m,
- "s", "");
- if (r < 0)
- return r;
-
- return bus_message_map_all_properties(m, map, userdata);
-}
-
-int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **ret) {
- _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
- int r;
-
- assert(transport >= 0);
- assert(transport < _BUS_TRANSPORT_MAX);
- assert(ret);
-
- assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
- assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
-
- switch (transport) {
-
- case BUS_TRANSPORT_LOCAL:
- if (user)
- r = sd_bus_default_user(&bus);
- else
- r = sd_bus_default_system(&bus);
-
- break;
-
- case BUS_TRANSPORT_REMOTE:
- r = sd_bus_open_system_remote(&bus, host);
- break;
-
- case BUS_TRANSPORT_MACHINE:
- r = sd_bus_open_system_machine(&bus, host);
- break;
-
- default:
- assert_not_reached("Hmm, unknown transport type.");
- }
- if (r < 0)
- return r;
-
- r = sd_bus_set_exit_on_disconnect(bus, true);
- if (r < 0)
- return r;
-
- *ret = bus;
- bus = NULL;
-
- return 0;
-}
-
-int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
- int r;
-
- assert(transport >= 0);
- assert(transport < _BUS_TRANSPORT_MAX);
- assert(bus);
-
- assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
- assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
-
- switch (transport) {
-
- case BUS_TRANSPORT_LOCAL:
- if (user)
- r = bus_connect_user_systemd(bus);
- else
- r = bus_connect_system_systemd(bus);
-
- break;
-
- case BUS_TRANSPORT_REMOTE:
- r = sd_bus_open_system_remote(bus, host);
- break;
-
- case BUS_TRANSPORT_MACHINE:
- r = sd_bus_open_system_machine(bus, host);
- break;
-
- default:
- assert_not_reached("Hmm, unknown transport type.");
- }
-
- return r;
-}
-
-int bus_property_get_bool(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- int b = *(bool*) userdata;
-
- return sd_bus_message_append_basic(reply, 'b', &b);
-}
-
-int bus_property_get_id128(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- sd_id128_t *id = userdata;
-
- if (sd_id128_is_null(*id)) /* Add an empty array if the ID is zero */
- return sd_bus_message_append(reply, "ay", 0);
- else
- return sd_bus_message_append_array(reply, 'y', id->bytes, 16);
-}
-
-#if __SIZEOF_SIZE_T__ != 8
-int bus_property_get_size(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- uint64_t sz = *(size_t*) userdata;
-
- return sd_bus_message_append_basic(reply, 't', &sz);
-}
-#endif
-
-#if __SIZEOF_LONG__ != 8
-int bus_property_get_long(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- int64_t l = *(long*) userdata;
-
- return sd_bus_message_append_basic(reply, 'x', &l);
-}
-
-int bus_property_get_ulong(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- uint64_t ul = *(unsigned long*) userdata;
-
- return sd_bus_message_append_basic(reply, 't', &ul);
-}
-#endif
-
-int bus_log_parse_error(int r) {
- return log_error_errno(r, "Failed to parse bus message: %m");
-}
-
-int bus_log_create_error(int r) {
- return log_error_errno(r, "Failed to create bus message: %m");
-}
-
-/**
- * bus_path_encode_unique() - encode unique object path
- * @b: bus connection or NULL
- * @prefix: object path prefix
- * @sender_id: unique-name of client, or NULL
- * @external_id: external ID to be chosen by client, or NULL
- * @ret_path: storage for encoded object path pointer
- *
- * Whenever we provide a bus API that allows clients to create and manage
- * server-side objects, we need to provide a unique name for these objects. If
- * we let the server choose the name, we suffer from a race condition: If a
- * client creates an object asynchronously, it cannot destroy that object until
- * it received the method reply. It cannot know the name of the new object,
- * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
- *
- * Therefore, many APIs allow the client to choose the unique name for newly
- * created objects. There're two problems to solve, though:
- * 1) Object names are usually defined via dbus object paths, which are
- * usually globally namespaced. Therefore, multiple clients must be able
- * to choose unique object names without interference.
- * 2) If multiple libraries share the same bus connection, they must be
- * able to choose unique object names without interference.
- * The first problem is solved easily by prefixing a name with the
- * unique-bus-name of a connection. The server side must enforce this and
- * reject any other name. The second problem is solved by providing unique
- * suffixes from within sd-bus.
- *
- * This helper allows clients to create unique object-paths. It uses the
- * template '/prefix/sender_id/external_id' and returns the new path in
- * @ret_path (must be freed by the caller).
- * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
- * NULL, this function allocates a unique suffix via @b (by requesting a new
- * cookie). If both @sender_id and @external_id are given, @b can be passed as
- * NULL.
- *
- * Returns: 0 on success, negative error code on failure.
- */
-int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
- _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
- char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
- int r;
-
- assert_return(b || (sender_id && external_id), -EINVAL);
- assert_return(object_path_is_valid(prefix), -EINVAL);
- assert_return(ret_path, -EINVAL);
-
- if (!sender_id) {
- r = sd_bus_get_unique_name(b, &sender_id);
- if (r < 0)
- return r;
- }
-
- if (!external_id) {
- xsprintf(external_buf, "%"PRIu64, ++b->cookie);
- external_id = external_buf;
- }
-
- sender_label = bus_label_escape(sender_id);
- if (!sender_label)
- return -ENOMEM;
-
- external_label = bus_label_escape(external_id);
- if (!external_label)
- return -ENOMEM;
-
- p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
- if (!p)
- return -ENOMEM;
-
- *ret_path = p;
- return 0;
-}
-
-/**
- * bus_path_decode_unique() - decode unique object path
- * @path: object path to decode
- * @prefix: object path prefix
- * @ret_sender: output parameter for sender-id label
- * @ret_external: output parameter for external-id label
- *
- * This does the reverse of bus_path_encode_unique() (see its description for
- * details). Both trailing labels, sender-id and external-id, are unescaped and
- * returned in the given output parameters (the caller must free them).
- *
- * Note that this function returns 0 if the path does not match the template
- * (see bus_path_encode_unique()), 1 if it matched.
- *
- * Returns: Negative error code on failure, 0 if the given object path does not
- * match the template (return parameters are set to NULL), 1 if it was
- * parsed successfully (return parameters contain allocated labels).
- */
-int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
- const char *p, *q;
- char *sender, *external;
-
- assert(object_path_is_valid(path));
- assert(object_path_is_valid(prefix));
- assert(ret_sender);
- assert(ret_external);
-
- p = object_path_startswith(path, prefix);
- if (!p) {
- *ret_sender = NULL;
- *ret_external = NULL;
- return 0;
- }
-
- q = strchr(p, '/');
- if (!q) {
- *ret_sender = NULL;
- *ret_external = NULL;
- return 0;
- }
-
- sender = bus_label_unescape_n(p, q - p);
- external = bus_label_unescape(q + 1);
- if (!sender || !external) {
- free(sender);
- free(external);
- return -ENOMEM;
- }
-
- *ret_sender = sender;
- *ret_external = external;
- return 1;
-}
-
-int bus_property_get_rlimit(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- void *userdata,
- sd_bus_error *error) {
-
- struct rlimit *rl;
- uint64_t u;
- rlim_t x;
- const char *is_soft;
-
- assert(bus);
- assert(reply);
- assert(userdata);
-
- is_soft = endswith(property, "Soft");
- rl = *(struct rlimit**) userdata;
- if (rl)
- x = is_soft ? rl->rlim_cur : rl->rlim_max;
- else {
- struct rlimit buf = {};
- int z;
- const char *s;
-
- s = is_soft ? strndupa(property, is_soft - property) : property;
-
- z = rlimit_from_string(strstr(s, "Limit"));
- assert(z >= 0);
-
- getrlimit(z, &buf);
- x = is_soft ? buf.rlim_cur : buf.rlim_max;
- }
-
- /* rlim_t might have different sizes, let's map
- * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
- * all archs */
- u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
-
- return sd_bus_message_append(reply, "t", u);
-}
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
deleted file mode 100644
index 934e0b5b77..0000000000
--- a/src/shared/bus-util.h
+++ /dev/null
@@ -1,161 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "sd-bus.h"
-#include "sd-event.h"
-
-#include "hashmap.h"
-#include "macro.h"
-#include "string-util.h"
-
-typedef enum BusTransport {
- BUS_TRANSPORT_LOCAL,
- BUS_TRANSPORT_REMOTE,
- BUS_TRANSPORT_MACHINE,
- _BUS_TRANSPORT_MAX,
- _BUS_TRANSPORT_INVALID = -1
-} BusTransport;
-
-typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
-
-struct bus_properties_map {
- const char *member;
- const char *signature;
- bus_property_set_t set;
- size_t offset;
-};
-
-int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
-
-int bus_message_map_all_properties(sd_bus_message *m, const struct bus_properties_map *map, void *userdata);
-int bus_message_map_properties_changed(sd_bus_message *m, const struct bus_properties_map *map, void *userdata);
-int bus_map_all_properties(sd_bus *bus, const char *destination, const char *path, const struct bus_properties_map *map, void *userdata);
-
-int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name);
-
-typedef bool (*check_idle_t)(void *userdata);
-
-int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t timeout, check_idle_t check_idle, void *userdata);
-
-int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error);
-
-int bus_check_peercred(sd_bus *c);
-
-int bus_test_polkit(sd_bus_message *call, int capability, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e);
-
-int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, const char **details, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error);
-void bus_verify_polkit_async_registry_free(Hashmap *registry);
-
-int bus_connect_system_systemd(sd_bus **_bus);
-int bus_connect_user_systemd(sd_bus **_bus);
-
-int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
-int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
-
-int bus_print_property(const char *name, sd_bus_message *property, bool value, bool all);
-int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool value, bool all);
-
-int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
-int bus_property_get_id128(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
-
-#define bus_property_get_usec ((sd_bus_property_get_t) NULL)
-#define bus_property_set_usec ((sd_bus_property_set_t) NULL)
-
-assert_cc(sizeof(int) == sizeof(int32_t));
-#define bus_property_get_int ((sd_bus_property_get_t) NULL)
-
-assert_cc(sizeof(unsigned) == sizeof(unsigned));
-#define bus_property_get_unsigned ((sd_bus_property_get_t) NULL)
-
-/* On 64bit machines we can use the default serializer for size_t and
- * friends, otherwise we need to cast this manually */
-#if __SIZEOF_SIZE_T__ == 8
-#define bus_property_get_size ((sd_bus_property_get_t) NULL)
-#else
-int bus_property_get_size(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
-#endif
-
-#if __SIZEOF_LONG__ == 8
-#define bus_property_get_long ((sd_bus_property_get_t) NULL)
-#define bus_property_get_ulong ((sd_bus_property_get_t) NULL)
-#else
-int bus_property_get_long(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
-int bus_property_get_ulong(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
-#endif
-
-/* uid_t and friends on Linux 32 bit. This means we can just use the
- * default serializer for 32bit unsigned, for serializing it, and map
- * it to NULL here */
-assert_cc(sizeof(uid_t) == sizeof(uint32_t));
-#define bus_property_get_uid ((sd_bus_property_get_t) NULL)
-
-assert_cc(sizeof(gid_t) == sizeof(uint32_t));
-#define bus_property_get_gid ((sd_bus_property_get_t) NULL)
-
-assert_cc(sizeof(pid_t) == sizeof(uint32_t));
-#define bus_property_get_pid ((sd_bus_property_get_t) NULL)
-
-assert_cc(sizeof(mode_t) == sizeof(uint32_t));
-#define bus_property_get_mode ((sd_bus_property_get_t) NULL)
-
-int bus_log_parse_error(int r);
-int bus_log_create_error(int r);
-
-#define BUS_DEFINE_PROPERTY_GET_ENUM(function, name, type) \
- int function(sd_bus *bus, \
- const char *path, \
- const char *interface, \
- const char *property, \
- sd_bus_message *reply, \
- void *userdata, \
- sd_bus_error *error) { \
- \
- const char *value; \
- type *field = userdata; \
- int r; \
- \
- assert(bus); \
- assert(reply); \
- assert(field); \
- \
- value = strempty(name##_to_string(*field)); \
- \
- r = sd_bus_message_append_basic(reply, 's', value); \
- if (r < 0) \
- return r; \
- \
- return 1; \
- } \
- struct __useless_struct_to_allow_trailing_semicolon__
-
-#define BUS_PROPERTY_DUAL_TIMESTAMP(name, offset, flags) \
- SD_BUS_PROPERTY(name, "t", bus_property_get_usec, (offset) + offsetof(struct dual_timestamp, realtime), (flags)), \
- SD_BUS_PROPERTY(name "Monotonic", "t", bus_property_get_usec, (offset) + offsetof(struct dual_timestamp, monotonic), (flags))
-
-int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path);
-int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
-
-int bus_property_get_rlimit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
deleted file mode 100644
index 3e451db715..0000000000
--- a/src/shared/cgroup-show.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <dirent.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "cgroup-show.h"
-#include "cgroup-util.h"
-#include "fd-util.h"
-#include "formats-util.h"
-#include "locale-util.h"
-#include "macro.h"
-#include "output-mode.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "string-util.h"
-#include "terminal-util.h"
-
-static void show_pid_array(
- pid_t pids[],
- unsigned n_pids,
- const char *prefix,
- unsigned n_columns,
- bool extra,
- bool more,
- OutputFlags flags) {
-
- unsigned i, j, pid_width;
-
- if (n_pids == 0)
- return;
-
- qsort(pids, n_pids, sizeof(pid_t), pid_compare_func);
-
- /* Filter duplicates */
- for (j = 0, i = 1; i < n_pids; i++) {
- if (pids[i] == pids[j])
- continue;
- pids[++j] = pids[i];
- }
- n_pids = j + 1;
- pid_width = DECIMAL_STR_WIDTH(pids[j]);
-
- if (flags & OUTPUT_FULL_WIDTH)
- n_columns = 0;
- else {
- if (n_columns > pid_width+2)
- n_columns -= pid_width+2;
- else
- n_columns = 20;
- }
- for (i = 0; i < n_pids; i++) {
- _cleanup_free_ char *t = NULL;
-
- get_process_cmdline(pids[i], n_columns, true, &t);
-
- if (extra)
- printf("%s%s ", prefix, special_glyph(TRIANGULAR_BULLET));
- else
- printf("%s%s", prefix, special_glyph(((more || i < n_pids-1) ? TREE_BRANCH : TREE_RIGHT)));
-
- printf("%*"PID_PRI" %s\n", pid_width, pids[i], strna(t));
- }
-}
-
-static int show_cgroup_one_by_path(
- const char *path,
- const char *prefix,
- unsigned n_columns,
- bool more,
- OutputFlags flags) {
-
- char *fn;
- _cleanup_fclose_ FILE *f = NULL;
- size_t n = 0, n_allocated = 0;
- _cleanup_free_ pid_t *pids = NULL;
- _cleanup_free_ char *p = NULL;
- pid_t pid;
- int r;
-
- r = cg_mangle_path(path, &p);
- if (r < 0)
- return r;
-
- fn = strjoina(p, "/cgroup.procs");
- f = fopen(fn, "re");
- if (!f)
- return -errno;
-
- while ((r = cg_read_pid(f, &pid)) > 0) {
-
- if (!(flags & OUTPUT_KERNEL_THREADS) && is_kernel_thread(pid) > 0)
- continue;
-
- if (!GREEDY_REALLOC(pids, n_allocated, n + 1))
- return -ENOMEM;
-
- assert(n < n_allocated);
- pids[n++] = pid;
- }
-
- if (r < 0)
- return r;
-
- show_pid_array(pids, n, prefix, n_columns, false, more, flags);
-
- return 0;
-}
-
-int show_cgroup_by_path(
- const char *path,
- const char *prefix,
- unsigned n_columns,
- OutputFlags flags) {
-
- _cleanup_free_ char *fn = NULL, *p1 = NULL, *last = NULL, *p2 = NULL;
- _cleanup_closedir_ DIR *d = NULL;
- char *gn = NULL;
- bool shown_pids = false;
- int r;
-
- assert(path);
-
- if (n_columns <= 0)
- n_columns = columns();
-
- prefix = strempty(prefix);
-
- r = cg_mangle_path(path, &fn);
- if (r < 0)
- return r;
-
- d = opendir(fn);
- if (!d)
- return -errno;
-
- while ((r = cg_read_subgroup(d, &gn)) > 0) {
- _cleanup_free_ char *k = NULL;
-
- k = strjoin(fn, "/", gn, NULL);
- free(gn);
- if (!k)
- return -ENOMEM;
-
- if (!(flags & OUTPUT_SHOW_ALL) && cg_is_empty_recursive(NULL, k) > 0)
- continue;
-
- if (!shown_pids) {
- show_cgroup_one_by_path(path, prefix, n_columns, true, flags);
- shown_pids = true;
- }
-
- if (last) {
- printf("%s%s%s\n", prefix, special_glyph(TREE_BRANCH), cg_unescape(basename(last)));
-
- if (!p1) {
- p1 = strappend(prefix, special_glyph(TREE_VERTICAL));
- if (!p1)
- return -ENOMEM;
- }
-
- show_cgroup_by_path(last, p1, n_columns-2, flags);
- free(last);
- }
-
- last = k;
- k = NULL;
- }
-
- if (r < 0)
- return r;
-
- if (!shown_pids)
- show_cgroup_one_by_path(path, prefix, n_columns, !!last, flags);
-
- if (last) {
- printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), cg_unescape(basename(last)));
-
- if (!p2) {
- p2 = strappend(prefix, " ");
- if (!p2)
- return -ENOMEM;
- }
-
- show_cgroup_by_path(last, p2, n_columns-2, flags);
- }
-
- return 0;
-}
-
-int show_cgroup(const char *controller,
- const char *path,
- const char *prefix,
- unsigned n_columns,
- OutputFlags flags) {
- _cleanup_free_ char *p = NULL;
- int r;
-
- assert(path);
-
- r = cg_get_path(controller, path, NULL, &p);
- if (r < 0)
- return r;
-
- return show_cgroup_by_path(p, prefix, n_columns, flags);
-}
-
-static int show_extra_pids(
- const char *controller,
- const char *path,
- const char *prefix,
- unsigned n_columns,
- const pid_t pids[],
- unsigned n_pids,
- OutputFlags flags) {
-
- _cleanup_free_ pid_t *copy = NULL;
- unsigned i, j;
- int r;
-
- assert(path);
-
- if (n_pids <= 0)
- return 0;
-
- if (n_columns <= 0)
- n_columns = columns();
-
- prefix = strempty(prefix);
-
- copy = new(pid_t, n_pids);
- if (!copy)
- return -ENOMEM;
-
- for (i = 0, j = 0; i < n_pids; i++) {
- _cleanup_free_ char *k = NULL;
-
- r = cg_pid_get_path(controller, pids[i], &k);
- if (r < 0)
- return r;
-
- if (path_startswith(k, path))
- continue;
-
- copy[j++] = pids[i];
- }
-
- show_pid_array(copy, j, prefix, n_columns, true, false, flags);
-
- return 0;
-}
-
-int show_cgroup_and_extra(
- const char *controller,
- const char *path,
- const char *prefix,
- unsigned n_columns,
- const pid_t extra_pids[],
- unsigned n_extra_pids,
- OutputFlags flags) {
-
- int r;
-
- assert(path);
-
- r = show_cgroup(controller, path, prefix, n_columns, flags);
- if (r < 0)
- return r;
-
- return show_extra_pids(controller, path, prefix, n_columns, extra_pids, n_extra_pids, flags);
-}
-
-int show_cgroup_and_extra_by_spec(
- const char *spec,
- const char *prefix,
- unsigned n_columns,
- const pid_t extra_pids[],
- unsigned n_extra_pids,
- OutputFlags flags) {
-
- _cleanup_free_ char *controller = NULL, *path = NULL;
- int r;
-
- assert(spec);
-
- r = cg_split_spec(spec, &controller, &path);
- if (r < 0)
- return r;
-
- return show_cgroup_and_extra(controller, path, prefix, n_columns, extra_pids, n_extra_pids, flags);
-}
diff --git a/src/shared/cgroup-show.h b/src/shared/cgroup-show.h
deleted file mode 100644
index 5c1d6e6d98..0000000000
--- a/src/shared/cgroup-show.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <sys/types.h>
-
-#include "logs-show.h"
-#include "output-mode.h"
-
-int show_cgroup_by_path(const char *path, const char *prefix, unsigned columns, OutputFlags flags);
-int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned columns, OutputFlags flags);
-
-int show_cgroup_and_extra_by_spec(const char *spec, const char *prefix, unsigned n_columns, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
-int show_cgroup_and_extra(const char *controller, const char *path, const char *prefix, unsigned n_columns, const pid_t extra_pids[], unsigned n_extra_pids, OutputFlags flags);
diff --git a/src/shared/clean-ipc.c b/src/shared/clean-ipc.c
deleted file mode 100644
index d5db604f03..0000000000
--- a/src/shared/clean-ipc.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <mqueue.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ipc.h>
-#include <sys/msg.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "clean-ipc.h"
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "formats-util.h"
-#include "log.h"
-#include "macro.h"
-#include "string-util.h"
-#include "strv.h"
-#include "user-util.h"
-
-static bool match_uid_gid(uid_t subject_uid, gid_t subject_gid, uid_t delete_uid, gid_t delete_gid) {
-
- if (uid_is_valid(delete_uid) && subject_uid == delete_uid)
- return true;
-
- if (gid_is_valid(delete_gid) && subject_gid == delete_gid)
- return true;
-
- return false;
-}
-
-static int clean_sysvipc_shm(uid_t delete_uid, gid_t delete_gid) {
- _cleanup_fclose_ FILE *f = NULL;
- char line[LINE_MAX];
- bool first = true;
- int ret = 0;
-
- f = fopen("/proc/sysvipc/shm", "re");
- if (!f) {
- if (errno == ENOENT)
- return 0;
-
- return log_warning_errno(errno, "Failed to open /proc/sysvipc/shm: %m");
- }
-
- FOREACH_LINE(line, f, goto fail) {
- unsigned n_attached;
- pid_t cpid, lpid;
- uid_t uid, cuid;
- gid_t gid, cgid;
- int shmid;
-
- if (first) {
- first = false;
- continue;
- }
-
- truncate_nl(line);
-
- if (sscanf(line, "%*i %i %*o %*u " PID_FMT " " PID_FMT " %u " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
- &shmid, &cpid, &lpid, &n_attached, &uid, &gid, &cuid, &cgid) != 8)
- continue;
-
- if (n_attached > 0)
- continue;
-
- if (!match_uid_gid(uid, gid, delete_uid, delete_gid))
- continue;
-
- if (shmctl(shmid, IPC_RMID, NULL) < 0) {
-
- /* Ignore entries that are already deleted */
- if (errno == EIDRM || errno == EINVAL)
- continue;
-
- ret = log_warning_errno(errno,
- "Failed to remove SysV shared memory segment %i: %m",
- shmid);
- } else
- log_debug("Removed SysV shared memory segment %i.", shmid);
- }
-
- return ret;
-
-fail:
- return log_warning_errno(errno, "Failed to read /proc/sysvipc/shm: %m");
-}
-
-static int clean_sysvipc_sem(uid_t delete_uid, gid_t delete_gid) {
- _cleanup_fclose_ FILE *f = NULL;
- char line[LINE_MAX];
- bool first = true;
- int ret = 0;
-
- f = fopen("/proc/sysvipc/sem", "re");
- if (!f) {
- if (errno == ENOENT)
- return 0;
-
- return log_warning_errno(errno, "Failed to open /proc/sysvipc/sem: %m");
- }
-
- FOREACH_LINE(line, f, goto fail) {
- uid_t uid, cuid;
- gid_t gid, cgid;
- int semid;
-
- if (first) {
- first = false;
- continue;
- }
-
- truncate_nl(line);
-
- if (sscanf(line, "%*i %i %*o %*u " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
- &semid, &uid, &gid, &cuid, &cgid) != 5)
- continue;
-
- if (!match_uid_gid(uid, gid, delete_uid, delete_gid))
- continue;
-
- if (semctl(semid, 0, IPC_RMID) < 0) {
-
- /* Ignore entries that are already deleted */
- if (errno == EIDRM || errno == EINVAL)
- continue;
-
- ret = log_warning_errno(errno,
- "Failed to remove SysV semaphores object %i: %m",
- semid);
- } else
- log_debug("Removed SysV semaphore %i.", semid);
- }
-
- return ret;
-
-fail:
- return log_warning_errno(errno, "Failed to read /proc/sysvipc/sem: %m");
-}
-
-static int clean_sysvipc_msg(uid_t delete_uid, gid_t delete_gid) {
- _cleanup_fclose_ FILE *f = NULL;
- char line[LINE_MAX];
- bool first = true;
- int ret = 0;
-
- f = fopen("/proc/sysvipc/msg", "re");
- if (!f) {
- if (errno == ENOENT)
- return 0;
-
- return log_warning_errno(errno, "Failed to open /proc/sysvipc/msg: %m");
- }
-
- FOREACH_LINE(line, f, goto fail) {
- uid_t uid, cuid;
- gid_t gid, cgid;
- pid_t cpid, lpid;
- int msgid;
-
- if (first) {
- first = false;
- continue;
- }
-
- truncate_nl(line);
-
- if (sscanf(line, "%*i %i %*o %*u %*u " PID_FMT " " PID_FMT " " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
- &msgid, &cpid, &lpid, &uid, &gid, &cuid, &cgid) != 7)
- continue;
-
- if (!match_uid_gid(uid, gid, delete_uid, delete_gid))
- continue;
-
- if (msgctl(msgid, IPC_RMID, NULL) < 0) {
-
- /* Ignore entries that are already deleted */
- if (errno == EIDRM || errno == EINVAL)
- continue;
-
- ret = log_warning_errno(errno,
- "Failed to remove SysV message queue %i: %m",
- msgid);
- } else
- log_debug("Removed SysV message queue %i.", msgid);
- }
-
- return ret;
-
-fail:
- return log_warning_errno(errno, "Failed to read /proc/sysvipc/msg: %m");
-}
-
-static int clean_posix_shm_internal(DIR *dir, uid_t uid, gid_t gid) {
- struct dirent *de;
- int ret = 0, r;
-
- assert(dir);
-
- FOREACH_DIRENT_ALL(de, dir, goto fail) {
- struct stat st;
-
- if (STR_IN_SET(de->d_name, "..", "."))
- continue;
-
- if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
- if (errno == ENOENT)
- continue;
-
- ret = log_warning_errno(errno, "Failed to stat() POSIX shared memory segment %s: %m", de->d_name);
- continue;
- }
-
- if (!match_uid_gid(st.st_uid, st.st_gid, uid, gid))
- continue;
-
- if (S_ISDIR(st.st_mode)) {
- _cleanup_closedir_ DIR *kid;
-
- kid = xopendirat(dirfd(dir), de->d_name, O_NOFOLLOW|O_NOATIME);
- if (!kid) {
- if (errno != ENOENT)
- ret = log_warning_errno(errno, "Failed to enter shared memory directory %s: %m", de->d_name);
- } else {
- r = clean_posix_shm_internal(kid, uid, gid);
- if (r < 0)
- ret = r;
- }
-
- if (unlinkat(dirfd(dir), de->d_name, AT_REMOVEDIR) < 0) {
-
- if (errno == ENOENT)
- continue;
-
- ret = log_warning_errno(errno, "Failed to remove POSIX shared memory directory %s: %m", de->d_name);
- } else
- log_debug("Removed POSIX shared memory directory %s", de->d_name);
- } else {
-
- if (unlinkat(dirfd(dir), de->d_name, 0) < 0) {
-
- if (errno == ENOENT)
- continue;
-
- ret = log_warning_errno(errno, "Failed to remove POSIX shared memory segment %s: %m", de->d_name);
- } else
- log_debug("Removed POSIX shared memory segment %s", de->d_name);
- }
- }
-
- return ret;
-
-fail:
- return log_warning_errno(errno, "Failed to read /dev/shm: %m");
-}
-
-static int clean_posix_shm(uid_t uid, gid_t gid) {
- _cleanup_closedir_ DIR *dir = NULL;
-
- dir = opendir("/dev/shm");
- if (!dir) {
- if (errno == ENOENT)
- return 0;
-
- return log_warning_errno(errno, "Failed to open /dev/shm: %m");
- }
-
- return clean_posix_shm_internal(dir, uid, gid);
-}
-
-static int clean_posix_mq(uid_t uid, gid_t gid) {
- _cleanup_closedir_ DIR *dir = NULL;
- struct dirent *de;
- int ret = 0;
-
- dir = opendir("/dev/mqueue");
- if (!dir) {
- if (errno == ENOENT)
- return 0;
-
- return log_warning_errno(errno, "Failed to open /dev/mqueue: %m");
- }
-
- FOREACH_DIRENT_ALL(de, dir, goto fail) {
- struct stat st;
- char fn[1+strlen(de->d_name)+1];
-
- if (STR_IN_SET(de->d_name, "..", "."))
- continue;
-
- if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
- if (errno == ENOENT)
- continue;
-
- ret = log_warning_errno(errno,
- "Failed to stat() MQ segment %s: %m",
- de->d_name);
- continue;
- }
-
- if (!match_uid_gid(st.st_uid, st.st_gid, uid, gid))
- continue;
-
- fn[0] = '/';
- strcpy(fn+1, de->d_name);
-
- if (mq_unlink(fn) < 0) {
- if (errno == ENOENT)
- continue;
-
- ret = log_warning_errno(errno,
- "Failed to unlink POSIX message queue %s: %m",
- fn);
- } else
- log_debug("Removed POSIX message queue %s", fn);
- }
-
- return ret;
-
-fail:
- return log_warning_errno(errno, "Failed to read /dev/mqueue: %m");
-}
-
-int clean_ipc(uid_t uid, gid_t gid) {
- int ret = 0, r;
-
- /* Anything to do? */
- if (!uid_is_valid(uid) && !gid_is_valid(gid))
- return 0;
-
- /* Refuse to clean IPC of the root user */
- if (uid == 0 && gid == 0)
- return 0;
-
- r = clean_sysvipc_shm(uid, gid);
- if (r < 0)
- ret = r;
-
- r = clean_sysvipc_sem(uid, gid);
- if (r < 0)
- ret = r;
-
- r = clean_sysvipc_msg(uid, gid);
- if (r < 0)
- ret = r;
-
- r = clean_posix_shm(uid, gid);
- if (r < 0)
- ret = r;
-
- r = clean_posix_mq(uid, gid);
- if (r < 0)
- ret = r;
-
- return ret;
-}
-
-int clean_ipc_by_uid(uid_t uid) {
- return clean_ipc(uid, GID_INVALID);
-}
-
-int clean_ipc_by_gid(gid_t gid) {
- return clean_ipc(UID_INVALID, gid);
-}
diff --git a/src/shared/clean-ipc.h b/src/shared/clean-ipc.h
deleted file mode 100644
index 6ca57f44fd..0000000000
--- a/src/shared/clean-ipc.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/types.h>
-
-int clean_ipc(uid_t uid, gid_t gid);
-int clean_ipc_by_uid(uid_t uid);
-int clean_ipc_by_gid(gid_t gid);
diff --git a/src/shared/condition.c b/src/shared/condition.c
deleted file mode 100644
index 8bd6a51a99..0000000000
--- a/src/shared/condition.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <fnmatch.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "sd-id128.h"
-
-#include "alloc-util.h"
-#include "apparmor-util.h"
-#include "architecture.h"
-#include "audit-util.h"
-#include "cap-list.h"
-#include "condition.h"
-#include "extract-word.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "glob-util.h"
-#include "hostname-util.h"
-#include "ima-util.h"
-#include "list.h"
-#include "macro.h"
-#include "mount-util.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "proc-cmdline.h"
-#include "selinux-util.h"
-#include "smack-util.h"
-#include "stat-util.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "util.h"
-#include "virt.h"
-
-Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
- Condition *c;
- int r;
-
- assert(type >= 0);
- assert(type < _CONDITION_TYPE_MAX);
- assert((!parameter) == (type == CONDITION_NULL));
-
- c = new0(Condition, 1);
- if (!c)
- return NULL;
-
- c->type = type;
- c->trigger = trigger;
- c->negate = negate;
-
- r = free_and_strdup(&c->parameter, parameter);
- if (r < 0) {
- free(c);
- return NULL;
- }
-
- return c;
-}
-
-void condition_free(Condition *c) {
- assert(c);
-
- free(c->parameter);
- free(c);
-}
-
-Condition* condition_free_list(Condition *first) {
- Condition *c, *n;
-
- LIST_FOREACH_SAFE(conditions, c, n, first)
- condition_free(c);
-
- return NULL;
-}
-
-static int condition_test_kernel_command_line(Condition *c) {
- _cleanup_free_ char *line = NULL;
- const char *p;
- bool equal;
- int r;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_KERNEL_COMMAND_LINE);
-
- r = proc_cmdline(&line);
- if (r < 0)
- return r;
-
- equal = !!strchr(c->parameter, '=');
- p = line;
-
- for (;;) {
- _cleanup_free_ char *word = NULL;
- bool found;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- if (equal)
- found = streq(word, c->parameter);
- else {
- const char *f;
-
- f = startswith(word, c->parameter);
- found = f && (*f == '=' || *f == 0);
- }
-
- if (found)
- return true;
- }
-
- return false;
-}
-
-static int condition_test_virtualization(Condition *c) {
- int b, v;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_VIRTUALIZATION);
-
- if (streq(c->parameter, "private-users"))
- return running_in_userns();
-
- v = detect_virtualization();
- if (v < 0)
- return v;
-
- /* First, compare with yes/no */
- b = parse_boolean(c->parameter);
- if (b >= 0)
- return b == !!v;
-
- /* Then, compare categorization */
- if (streq(c->parameter, "vm"))
- return VIRTUALIZATION_IS_VM(v);
-
- if (streq(c->parameter, "container"))
- return VIRTUALIZATION_IS_CONTAINER(v);
-
- /* Finally compare id */
- return v != VIRTUALIZATION_NONE && streq(c->parameter, virtualization_to_string(v));
-}
-
-static int condition_test_architecture(Condition *c) {
- int a, b;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_ARCHITECTURE);
-
- a = uname_architecture();
- if (a < 0)
- return a;
-
- if (streq(c->parameter, "native"))
- b = native_architecture();
- else {
- b = architecture_from_string(c->parameter);
- if (b < 0) /* unknown architecture? Then it's definitely not ours */
- return false;
- }
-
- return a == b;
-}
-
-static int condition_test_host(Condition *c) {
- _cleanup_free_ char *h = NULL;
- sd_id128_t x, y;
- int r;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_HOST);
-
- if (sd_id128_from_string(c->parameter, &x) >= 0) {
-
- r = sd_id128_get_machine(&y);
- if (r < 0)
- return r;
-
- return sd_id128_equal(x, y);
- }
-
- h = gethostname_malloc();
- if (!h)
- return -ENOMEM;
-
- return fnmatch(c->parameter, h, FNM_CASEFOLD) == 0;
-}
-
-static int condition_test_ac_power(Condition *c) {
- int r;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_AC_POWER);
-
- r = parse_boolean(c->parameter);
- if (r < 0)
- return r;
-
- return (on_ac_power() != 0) == !!r;
-}
-
-static int condition_test_security(Condition *c) {
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_SECURITY);
-
- if (streq(c->parameter, "selinux"))
- return mac_selinux_have();
- if (streq(c->parameter, "smack"))
- return mac_smack_use();
- if (streq(c->parameter, "apparmor"))
- return mac_apparmor_use();
- if (streq(c->parameter, "audit"))
- return use_audit();
- if (streq(c->parameter, "ima"))
- return use_ima();
-
- return false;
-}
-
-static int condition_test_capability(Condition *c) {
- _cleanup_fclose_ FILE *f = NULL;
- int value;
- char line[LINE_MAX];
- unsigned long long capabilities = -1;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_CAPABILITY);
-
- /* If it's an invalid capability, we don't have it */
- value = capability_from_name(c->parameter);
- if (value < 0)
- return -EINVAL;
-
- /* If it's a valid capability we default to assume
- * that we have it */
-
- f = fopen("/proc/self/status", "re");
- if (!f)
- return -errno;
-
- while (fgets(line, sizeof(line), f)) {
- truncate_nl(line);
-
- if (startswith(line, "CapBnd:")) {
- (void) sscanf(line+7, "%llx", &capabilities);
- break;
- }
- }
-
- return !!(capabilities & (1ULL << value));
-}
-
-static int condition_test_needs_update(Condition *c) {
- const char *p;
- struct stat usr, other;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_NEEDS_UPDATE);
-
- /* If the file system is read-only we shouldn't suggest an update */
- if (path_is_read_only_fs(c->parameter) > 0)
- return false;
-
- /* Any other failure means we should allow the condition to be true,
- * so that we rather invoke too many update tools than too
- * few. */
-
- if (!path_is_absolute(c->parameter))
- return true;
-
- p = strjoina(c->parameter, "/.updated");
- if (lstat(p, &other) < 0)
- return true;
-
- if (lstat("/usr/", &usr) < 0)
- return true;
-
- /*
- * First, compare seconds as they are always accurate...
- */
- if (usr.st_mtim.tv_sec != other.st_mtim.tv_sec)
- return usr.st_mtim.tv_sec > other.st_mtim.tv_sec;
-
- /*
- * ...then compare nanoseconds.
- *
- * A false positive is only possible when /usr's nanoseconds > 0
- * (otherwise /usr cannot be strictly newer than the target file)
- * AND the target file's nanoseconds == 0
- * (otherwise the filesystem supports nsec timestamps, see stat(2)).
- */
- if (usr.st_mtim.tv_nsec > 0 && other.st_mtim.tv_nsec == 0) {
- _cleanup_free_ char *timestamp_str = NULL;
- uint64_t timestamp;
- int r;
-
- r = parse_env_file(p, NULL, "TIMESTAMP_NSEC", &timestamp_str, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p);
- return true;
- } else if (r == 0) {
- log_debug("No data in timestamp file '%s', using mtime", p);
- return true;
- }
-
- r = safe_atou64(timestamp_str, &timestamp);
- if (r < 0) {
- log_error_errno(r, "Failed to parse timestamp value '%s' in file '%s', using mtime: %m", timestamp_str, p);
- return true;
- }
-
- timespec_store(&other.st_mtim, timestamp);
- }
-
- return usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec;
-}
-
-static int condition_test_first_boot(Condition *c) {
- int r;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_FIRST_BOOT);
-
- r = parse_boolean(c->parameter);
- if (r < 0)
- return r;
-
- return (access("/run/systemd/first-boot", F_OK) >= 0) == !!r;
-}
-
-static int condition_test_path_exists(Condition *c) {
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_PATH_EXISTS);
-
- return access(c->parameter, F_OK) >= 0;
-}
-
-static int condition_test_path_exists_glob(Condition *c) {
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_PATH_EXISTS_GLOB);
-
- return glob_exists(c->parameter) > 0;
-}
-
-static int condition_test_path_is_directory(Condition *c) {
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_PATH_IS_DIRECTORY);
-
- return is_dir(c->parameter, true) > 0;
-}
-
-static int condition_test_path_is_symbolic_link(Condition *c) {
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_PATH_IS_SYMBOLIC_LINK);
-
- return is_symlink(c->parameter) > 0;
-}
-
-static int condition_test_path_is_mount_point(Condition *c) {
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_PATH_IS_MOUNT_POINT);
-
- return path_is_mount_point(c->parameter, AT_SYMLINK_FOLLOW) > 0;
-}
-
-static int condition_test_path_is_read_write(Condition *c) {
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_PATH_IS_READ_WRITE);
-
- return path_is_read_only_fs(c->parameter) <= 0;
-}
-
-static int condition_test_directory_not_empty(Condition *c) {
- int r;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_DIRECTORY_NOT_EMPTY);
-
- r = dir_is_empty(c->parameter);
- return r <= 0 && r != -ENOENT;
-}
-
-static int condition_test_file_not_empty(Condition *c) {
- struct stat st;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_FILE_NOT_EMPTY);
-
- return (stat(c->parameter, &st) >= 0 &&
- S_ISREG(st.st_mode) &&
- st.st_size > 0);
-}
-
-static int condition_test_file_is_executable(Condition *c) {
- struct stat st;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_FILE_IS_EXECUTABLE);
-
- return (stat(c->parameter, &st) >= 0 &&
- S_ISREG(st.st_mode) &&
- (st.st_mode & 0111));
-}
-
-static int condition_test_null(Condition *c) {
- assert(c);
- assert(c->type == CONDITION_NULL);
-
- /* Note that during parsing we already evaluate the string and
- * store it in c->negate */
- return true;
-}
-
-int condition_test(Condition *c) {
-
- static int (*const condition_tests[_CONDITION_TYPE_MAX])(Condition *c) = {
- [CONDITION_PATH_EXISTS] = condition_test_path_exists,
- [CONDITION_PATH_EXISTS_GLOB] = condition_test_path_exists_glob,
- [CONDITION_PATH_IS_DIRECTORY] = condition_test_path_is_directory,
- [CONDITION_PATH_IS_SYMBOLIC_LINK] = condition_test_path_is_symbolic_link,
- [CONDITION_PATH_IS_MOUNT_POINT] = condition_test_path_is_mount_point,
- [CONDITION_PATH_IS_READ_WRITE] = condition_test_path_is_read_write,
- [CONDITION_DIRECTORY_NOT_EMPTY] = condition_test_directory_not_empty,
- [CONDITION_FILE_NOT_EMPTY] = condition_test_file_not_empty,
- [CONDITION_FILE_IS_EXECUTABLE] = condition_test_file_is_executable,
- [CONDITION_KERNEL_COMMAND_LINE] = condition_test_kernel_command_line,
- [CONDITION_VIRTUALIZATION] = condition_test_virtualization,
- [CONDITION_SECURITY] = condition_test_security,
- [CONDITION_CAPABILITY] = condition_test_capability,
- [CONDITION_HOST] = condition_test_host,
- [CONDITION_AC_POWER] = condition_test_ac_power,
- [CONDITION_ARCHITECTURE] = condition_test_architecture,
- [CONDITION_NEEDS_UPDATE] = condition_test_needs_update,
- [CONDITION_FIRST_BOOT] = condition_test_first_boot,
- [CONDITION_NULL] = condition_test_null,
- };
-
- int r, b;
-
- assert(c);
- assert(c->type >= 0);
- assert(c->type < _CONDITION_TYPE_MAX);
-
- r = condition_tests[c->type](c);
- if (r < 0) {
- c->result = CONDITION_ERROR;
- return r;
- }
-
- b = (r > 0) == !c->negate;
- c->result = b ? CONDITION_SUCCEEDED : CONDITION_FAILED;
- return b;
-}
-
-void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) {
- assert(c);
- assert(f);
-
- if (!prefix)
- prefix = "";
-
- fprintf(f,
- "%s\t%s: %s%s%s %s\n",
- prefix,
- to_string(c->type),
- c->trigger ? "|" : "",
- c->negate ? "!" : "",
- c->parameter,
- condition_result_to_string(c->result));
-}
-
-void condition_dump_list(Condition *first, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) {
- Condition *c;
-
- LIST_FOREACH(conditions, c, first)
- condition_dump(c, f, prefix, to_string);
-}
-
-static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
- [CONDITION_ARCHITECTURE] = "ConditionArchitecture",
- [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
- [CONDITION_HOST] = "ConditionHost",
- [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
- [CONDITION_SECURITY] = "ConditionSecurity",
- [CONDITION_CAPABILITY] = "ConditionCapability",
- [CONDITION_AC_POWER] = "ConditionACPower",
- [CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
- [CONDITION_FIRST_BOOT] = "ConditionFirstBoot",
- [CONDITION_PATH_EXISTS] = "ConditionPathExists",
- [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob",
- [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory",
- [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
- [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
- [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
- [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
- [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
- [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
- [CONDITION_NULL] = "ConditionNull"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);
-
-static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
- [CONDITION_ARCHITECTURE] = "AssertArchitecture",
- [CONDITION_VIRTUALIZATION] = "AssertVirtualization",
- [CONDITION_HOST] = "AssertHost",
- [CONDITION_KERNEL_COMMAND_LINE] = "AssertKernelCommandLine",
- [CONDITION_SECURITY] = "AssertSecurity",
- [CONDITION_CAPABILITY] = "AssertCapability",
- [CONDITION_AC_POWER] = "AssertACPower",
- [CONDITION_NEEDS_UPDATE] = "AssertNeedsUpdate",
- [CONDITION_FIRST_BOOT] = "AssertFirstBoot",
- [CONDITION_PATH_EXISTS] = "AssertPathExists",
- [CONDITION_PATH_EXISTS_GLOB] = "AssertPathExistsGlob",
- [CONDITION_PATH_IS_DIRECTORY] = "AssertPathIsDirectory",
- [CONDITION_PATH_IS_SYMBOLIC_LINK] = "AssertPathIsSymbolicLink",
- [CONDITION_PATH_IS_MOUNT_POINT] = "AssertPathIsMountPoint",
- [CONDITION_PATH_IS_READ_WRITE] = "AssertPathIsReadWrite",
- [CONDITION_DIRECTORY_NOT_EMPTY] = "AssertDirectoryNotEmpty",
- [CONDITION_FILE_NOT_EMPTY] = "AssertFileNotEmpty",
- [CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable",
- [CONDITION_NULL] = "AssertNull"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(assert_type, ConditionType);
-
-static const char* const condition_result_table[_CONDITION_RESULT_MAX] = {
- [CONDITION_UNTESTED] = "untested",
- [CONDITION_SUCCEEDED] = "succeeded",
- [CONDITION_FAILED] = "failed",
- [CONDITION_ERROR] = "error",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(condition_result, ConditionResult);
diff --git a/src/shared/condition.h b/src/shared/condition.h
deleted file mode 100644
index bdda04b770..0000000000
--- a/src/shared/condition.h
+++ /dev/null
@@ -1,94 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stdio.h>
-
-#include "list.h"
-#include "macro.h"
-
-typedef enum ConditionType {
- CONDITION_ARCHITECTURE,
- CONDITION_VIRTUALIZATION,
- CONDITION_HOST,
- CONDITION_KERNEL_COMMAND_LINE,
- CONDITION_SECURITY,
- CONDITION_CAPABILITY,
- CONDITION_AC_POWER,
-
- CONDITION_NEEDS_UPDATE,
- CONDITION_FIRST_BOOT,
-
- CONDITION_PATH_EXISTS,
- CONDITION_PATH_EXISTS_GLOB,
- CONDITION_PATH_IS_DIRECTORY,
- CONDITION_PATH_IS_SYMBOLIC_LINK,
- CONDITION_PATH_IS_MOUNT_POINT,
- CONDITION_PATH_IS_READ_WRITE,
- CONDITION_DIRECTORY_NOT_EMPTY,
- CONDITION_FILE_NOT_EMPTY,
- CONDITION_FILE_IS_EXECUTABLE,
-
- CONDITION_NULL,
-
- _CONDITION_TYPE_MAX,
- _CONDITION_TYPE_INVALID = -1
-} ConditionType;
-
-typedef enum ConditionResult {
- CONDITION_UNTESTED,
- CONDITION_SUCCEEDED,
- CONDITION_FAILED,
- CONDITION_ERROR,
- _CONDITION_RESULT_MAX,
- _CONDITION_RESULT_INVALID = -1
-} ConditionResult;
-
-typedef struct Condition {
- ConditionType type:8;
-
- bool trigger:1;
- bool negate:1;
-
- ConditionResult result:6;
-
- char *parameter;
-
- LIST_FIELDS(struct Condition, conditions);
-} Condition;
-
-Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate);
-void condition_free(Condition *c);
-Condition* condition_free_list(Condition *c);
-
-int condition_test(Condition *c);
-
-void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t));
-void condition_dump_list(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t));
-
-const char* condition_type_to_string(ConditionType t) _const_;
-ConditionType condition_type_from_string(const char *s) _pure_;
-
-const char* assert_type_to_string(ConditionType t) _const_;
-ConditionType assert_type_from_string(const char *s) _pure_;
-
-const char* condition_result_to_string(ConditionResult r) _const_;
-ConditionResult condition_result_from_string(const char *s) _pure_;
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
deleted file mode 100644
index 2ec0155b71..0000000000
--- a/src/shared/conf-parser.c
+++ /dev/null
@@ -1,961 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <limits.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "alloc-util.h"
-#include "conf-files.h"
-#include "conf-parser.h"
-#include "extract-word.h"
-#include "fd-util.h"
-#include "fs-util.h"
-#include "log.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "signal-util.h"
-#include "socket-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "syslog-util.h"
-#include "time-util.h"
-#include "utf8.h"
-
-int config_item_table_lookup(
- const void *table,
- const char *section,
- const char *lvalue,
- ConfigParserCallback *func,
- int *ltype,
- void **data,
- void *userdata) {
-
- const ConfigTableItem *t;
-
- assert(table);
- assert(lvalue);
- assert(func);
- assert(ltype);
- assert(data);
-
- for (t = table; t->lvalue; t++) {
-
- if (!streq(lvalue, t->lvalue))
- continue;
-
- if (!streq_ptr(section, t->section))
- continue;
-
- *func = t->parse;
- *ltype = t->ltype;
- *data = t->data;
- return 1;
- }
-
- return 0;
-}
-
-int config_item_perf_lookup(
- const void *table,
- const char *section,
- const char *lvalue,
- ConfigParserCallback *func,
- int *ltype,
- void **data,
- void *userdata) {
-
- ConfigPerfItemLookup lookup = (ConfigPerfItemLookup) table;
- const ConfigPerfItem *p;
-
- assert(table);
- assert(lvalue);
- assert(func);
- assert(ltype);
- assert(data);
-
- if (!section)
- p = lookup(lvalue, strlen(lvalue));
- else {
- char *key;
-
- key = strjoin(section, ".", lvalue, NULL);
- if (!key)
- return -ENOMEM;
-
- p = lookup(key, strlen(key));
- free(key);
- }
-
- if (!p)
- return 0;
-
- *func = p->parse;
- *ltype = p->ltype;
- *data = (uint8_t*) userdata + p->offset;
- return 1;
-}
-
-/* Run the user supplied parser for an assignment */
-static int next_assignment(const char *unit,
- const char *filename,
- unsigned line,
- ConfigItemLookup lookup,
- const void *table,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- const char *rvalue,
- bool relaxed,
- void *userdata) {
-
- ConfigParserCallback func = NULL;
- int ltype = 0;
- void *data = NULL;
- int r;
-
- assert(filename);
- assert(line > 0);
- assert(lookup);
- assert(lvalue);
- assert(rvalue);
-
- r = lookup(table, section, lvalue, &func, &ltype, &data, userdata);
- if (r < 0)
- return r;
-
- if (r > 0) {
- if (func)
- return func(unit, filename, line, section, section_line,
- lvalue, ltype, rvalue, data, userdata);
-
- return 0;
- }
-
- /* Warn about unknown non-extension fields. */
- if (!relaxed && !startswith(lvalue, "X-"))
- log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown lvalue '%s' in section '%s'", lvalue, section);
-
- return 0;
-}
-
-/* Parse a variable assignment line */
-static int parse_line(const char* unit,
- const char *filename,
- unsigned line,
- const char *sections,
- ConfigItemLookup lookup,
- const void *table,
- bool relaxed,
- bool allow_include,
- char **section,
- unsigned *section_line,
- bool *section_ignored,
- char *l,
- void *userdata) {
-
- char *e;
-
- assert(filename);
- assert(line > 0);
- assert(lookup);
- assert(l);
-
- l = strstrip(l);
-
- if (!*l)
- return 0;
-
- if (strchr(COMMENTS "\n", *l))
- return 0;
-
- if (startswith(l, ".include ")) {
- _cleanup_free_ char *fn = NULL;
-
- /* .includes are a bad idea, we only support them here
- * for historical reasons. They create cyclic include
- * problems and make it difficult to detect
- * configuration file changes with an easy
- * stat(). Better approaches, such as .d/ drop-in
- * snippets exist.
- *
- * Support for them should be eventually removed. */
-
- if (!allow_include) {
- log_syntax(unit, LOG_ERR, filename, line, 0, ".include not allowed here. Ignoring.");
- return 0;
- }
-
- fn = file_in_same_dir(filename, strstrip(l+9));
- if (!fn)
- return -ENOMEM;
-
- return config_parse(unit, fn, NULL, sections, lookup, table, relaxed, false, false, userdata);
- }
-
- if (*l == '[') {
- size_t k;
- char *n;
-
- k = strlen(l);
- assert(k > 0);
-
- if (l[k-1] != ']') {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid section header '%s'", l);
- return -EBADMSG;
- }
-
- n = strndup(l+1, k-2);
- if (!n)
- return -ENOMEM;
-
- if (sections && !nulstr_contains(sections, n)) {
-
- if (!relaxed && !startswith(n, "X-"))
- log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown section '%s'. Ignoring.", n);
-
- free(n);
- *section = mfree(*section);
- *section_line = 0;
- *section_ignored = true;
- } else {
- free(*section);
- *section = n;
- *section_line = line;
- *section_ignored = false;
- }
-
- return 0;
- }
-
- if (sections && !*section) {
-
- if (!relaxed && !*section_ignored)
- log_syntax(unit, LOG_WARNING, filename, line, 0, "Assignment outside of section. Ignoring.");
-
- return 0;
- }
-
- e = strchr(l, '=');
- if (!e) {
- log_syntax(unit, LOG_WARNING, filename, line, 0, "Missing '='.");
- return -EINVAL;
- }
-
- *e = 0;
- e++;
-
- return next_assignment(unit,
- filename,
- line,
- lookup,
- table,
- *section,
- *section_line,
- strstrip(l),
- strstrip(e),
- relaxed,
- userdata);
-}
-
-/* Go through the file and parse each line */
-int config_parse(const char *unit,
- const char *filename,
- FILE *f,
- const char *sections,
- ConfigItemLookup lookup,
- const void *table,
- bool relaxed,
- bool allow_include,
- bool warn,
- void *userdata) {
-
- _cleanup_free_ char *section = NULL, *continuation = NULL;
- _cleanup_fclose_ FILE *ours = NULL;
- unsigned line = 0, section_line = 0;
- bool section_ignored = false, allow_bom = true;
- int r;
-
- assert(filename);
- assert(lookup);
-
- if (!f) {
- f = ours = fopen(filename, "re");
- if (!f) {
- /* Only log on request, except for ENOENT,
- * since we return 0 to the caller. */
- if (warn || errno == ENOENT)
- log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR,
- "Failed to open configuration file '%s': %m", filename);
- return errno == ENOENT ? 0 : -errno;
- }
- }
-
- fd_warn_permissions(filename, fileno(f));
-
- for (;;) {
- char buf[LINE_MAX], *l, *p, *c = NULL, *e;
- bool escaped = false;
-
- if (!fgets(buf, sizeof buf, f)) {
- if (feof(f))
- break;
-
- return log_error_errno(errno, "Failed to read configuration file '%s': %m", filename);
- }
-
- l = buf;
- if (allow_bom && startswith(l, UTF8_BYTE_ORDER_MARK))
- l += strlen(UTF8_BYTE_ORDER_MARK);
- allow_bom = false;
-
- truncate_nl(l);
-
- if (continuation) {
- c = strappend(continuation, l);
- if (!c) {
- if (warn)
- log_oom();
- return -ENOMEM;
- }
-
- continuation = mfree(continuation);
- p = c;
- } else
- p = l;
-
- for (e = p; *e; e++) {
- if (escaped)
- escaped = false;
- else if (*e == '\\')
- escaped = true;
- }
-
- if (escaped) {
- *(e-1) = ' ';
-
- if (c)
- continuation = c;
- else {
- continuation = strdup(l);
- if (!continuation) {
- if (warn)
- log_oom();
- return -ENOMEM;
- }
- }
-
- continue;
- }
-
- r = parse_line(unit,
- filename,
- ++line,
- sections,
- lookup,
- table,
- relaxed,
- allow_include,
- &section,
- &section_line,
- &section_ignored,
- p,
- userdata);
- free(c);
-
- if (r < 0) {
- if (warn)
- log_warning_errno(r, "Failed to parse file '%s': %m",
- filename);
- return r;
- }
- }
-
- return 0;
-}
-
-static int config_parse_many_files(
- const char *conf_file,
- char **files,
- const char *sections,
- ConfigItemLookup lookup,
- const void *table,
- bool relaxed,
- void *userdata) {
-
- char **fn;
- int r;
-
- if (conf_file) {
- r = config_parse(NULL, conf_file, NULL, sections, lookup, table, relaxed, false, true, userdata);
- if (r < 0)
- return r;
- }
-
- STRV_FOREACH(fn, files) {
- r = config_parse(NULL, *fn, NULL, sections, lookup, table, relaxed, false, true, userdata);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-/* Parse each config file in the directories specified as nulstr. */
-int config_parse_many_nulstr(
- const char *conf_file,
- const char *conf_file_dirs,
- const char *sections,
- ConfigItemLookup lookup,
- const void *table,
- bool relaxed,
- void *userdata) {
-
- _cleanup_strv_free_ char **files = NULL;
- int r;
-
- r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs);
- if (r < 0)
- return r;
-
- return config_parse_many_files(conf_file, files,
- sections, lookup, table, relaxed, userdata);
-}
-
-/* Parse each config file in the directories specified as strv. */
-int config_parse_many(
- const char *conf_file,
- const char* const* conf_file_dirs,
- const char *dropin_dirname,
- const char *sections,
- ConfigItemLookup lookup,
- const void *table,
- bool relaxed,
- void *userdata) {
-
- _cleanup_strv_free_ char **dropin_dirs = NULL;
- _cleanup_strv_free_ char **files = NULL;
- const char *suffix;
- int r;
-
- suffix = strjoina("/", dropin_dirname);
- r = strv_extend_strv_concat(&dropin_dirs, (char**) conf_file_dirs, suffix);
- if (r < 0)
- return r;
-
- r = conf_files_list_strv(&files, ".conf", NULL, (const char* const*) dropin_dirs);
- if (r < 0)
- return r;
-
- return config_parse_many_files(conf_file, files,
- sections, lookup, table, relaxed, userdata);
-}
-
-#define DEFINE_PARSER(type, vartype, conv_func) \
- int config_parse_##type( \
- const char *unit, \
- const char *filename, \
- unsigned line, \
- const char *section, \
- unsigned section_line, \
- const char *lvalue, \
- int ltype, \
- const char *rvalue, \
- void *data, \
- void *userdata) { \
- \
- vartype *i = data; \
- int r; \
- \
- assert(filename); \
- assert(lvalue); \
- assert(rvalue); \
- assert(data); \
- \
- r = conv_func(rvalue, i); \
- if (r < 0) \
- log_syntax(unit, LOG_ERR, filename, line, r, \
- "Failed to parse %s value, ignoring: %s", \
- #type, rvalue); \
- \
- return 0; \
- } \
- struct __useless_struct_to_allow_trailing_semicolon__
-
-DEFINE_PARSER(int, int, safe_atoi);
-DEFINE_PARSER(long, long, safe_atoli);
-DEFINE_PARSER(uint16, uint16_t, safe_atou16);
-DEFINE_PARSER(uint32, uint32_t, safe_atou32);
-DEFINE_PARSER(uint64, uint64_t, safe_atou64);
-DEFINE_PARSER(unsigned, unsigned, safe_atou);
-DEFINE_PARSER(double, double, safe_atod);
-DEFINE_PARSER(nsec, nsec_t, parse_nsec);
-DEFINE_PARSER(sec, usec_t, parse_sec);
-DEFINE_PARSER(mode, mode_t, parse_mode);
-
-int config_parse_iec_size(const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- size_t *sz = data;
- uint64_t v;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = parse_size(rvalue, 1024, &v);
- if (r < 0 || (uint64_t) (size_t) v != v) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
- return 0;
- }
-
- *sz = (size_t) v;
- return 0;
-}
-
-int config_parse_si_size(const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- size_t *sz = data;
- uint64_t v;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = parse_size(rvalue, 1000, &v);
- if (r < 0 || (uint64_t) (size_t) v != v) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
- return 0;
- }
-
- *sz = (size_t) v;
- return 0;
-}
-
-int config_parse_iec_uint64(const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- uint64_t *bytes = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = parse_size(rvalue, 1024, bytes);
- if (r < 0)
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
-
- return 0;
-}
-
-int config_parse_bool(const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- int k;
- bool *b = data;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- k = parse_boolean(rvalue);
- if (k < 0) {
- log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue);
- return 0;
- }
-
- *b = !!k;
- return 0;
-}
-
-int config_parse_tristate(
- const char* unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- int k, *t = data;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- /* A tristate is pretty much a boolean, except that it can
- * also take the special value -1, indicating "uninitialized",
- * much like NULL is for a pointer type. */
-
- k = parse_boolean(rvalue);
- if (k < 0) {
- log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue);
- return 0;
- }
-
- *t = !!k;
- return 0;
-}
-
-int config_parse_string(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char **s = data, *n;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (!utf8_is_valid(rvalue)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return 0;
- }
-
- if (isempty(rvalue))
- n = NULL;
- else {
- n = strdup(rvalue);
- if (!n)
- return log_oom();
- }
-
- free(*s);
- *s = n;
-
- return 0;
-}
-
-int config_parse_path(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char **s = data, *n;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (!utf8_is_valid(rvalue)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return 0;
- }
-
- if (!path_is_absolute(rvalue)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", rvalue);
- return 0;
- }
-
- n = strdup(rvalue);
- if (!n)
- return log_oom();
-
- path_kill_slashes(n);
-
- free(*s);
- *s = n;
-
- return 0;
-}
-
-int config_parse_strv(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char ***sv = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (isempty(rvalue)) {
- char **empty;
-
- /* Empty assignment resets the list. As a special rule
- * we actually fill in a real empty array here rather
- * than NULL, since some code wants to know if
- * something was set at all... */
- empty = new0(char*, 1);
- if (!empty)
- return log_oom();
-
- strv_free(*sv);
- *sv = empty;
-
- return 0;
- }
-
- for (;;) {
- char *word = NULL;
-
- r = extract_first_word(&rvalue, &word, WHITESPACE, EXTRACT_QUOTES|EXTRACT_RETAIN_ESCAPE);
- if (r == 0)
- break;
- if (r == -ENOMEM)
- return log_oom();
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
- break;
- }
-
- if (!utf8_is_valid(word)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- free(word);
- continue;
- }
- r = strv_consume(sv, word);
- if (r < 0)
- return log_oom();
- }
-
- return 0;
-}
-
-int config_parse_log_facility(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
-
- int *o = data, x;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- x = log_facility_unshifted_from_string(rvalue);
- if (x < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse log facility, ignoring: %s", rvalue);
- return 0;
- }
-
- *o = (x << 3) | LOG_PRI(*o);
-
- return 0;
-}
-
-int config_parse_log_level(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
-
- int *o = data, x;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- x = log_level_from_string(rvalue);
- if (x < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse log level, ignoring: %s", rvalue);
- return 0;
- }
-
- *o = (*o & LOG_FACMASK) | x;
- return 0;
-}
-
-int config_parse_signal(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- int *sig = data, r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(sig);
-
- r = signal_from_string_try_harder(rvalue);
- if (r <= 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse signal name, ignoring: %s", rvalue);
- return 0;
- }
-
- *sig = r;
- return 0;
-}
-
-int config_parse_personality(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- unsigned long *personality = data, p;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(personality);
-
- p = personality_from_string(rvalue);
- if (p == PERSONALITY_INVALID) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse personality, ignoring: %s", rvalue);
- return 0;
- }
-
- *personality = p;
- return 0;
-}
-
-int config_parse_ifname(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char **s = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (isempty(rvalue)) {
- *s = mfree(*s);
- return 0;
- }
-
- if (!ifname_valid(rvalue)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue);
- return 0;
- }
-
- r = free_and_strdup(s, rvalue);
- if (r < 0)
- return log_oom();
-
- return 0;
-}
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
deleted file mode 100644
index 26ff3df16f..0000000000
--- a/src/shared/conf-parser.h
+++ /dev/null
@@ -1,242 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <syslog.h>
-
-#include "alloc-util.h"
-#include "log.h"
-#include "macro.h"
-
-/* An abstract parser for simple, line based, shallow configuration
- * files consisting of variable assignments only. */
-
-/* Prototype for a parser for a specific configuration setting */
-typedef int (*ConfigParserCallback)(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata);
-
-/* Wraps information for parsing a specific configuration variable, to
- * be stored in a simple array */
-typedef struct ConfigTableItem {
- const char *section; /* Section */
- const char *lvalue; /* Name of the variable */
- ConfigParserCallback parse; /* Function that is called to parse the variable's value */
- int ltype; /* Distinguish different variables passed to the same callback */
- void *data; /* Where to store the variable's data */
-} ConfigTableItem;
-
-/* Wraps information for parsing a specific configuration variable, to
- * be stored in a gperf perfect hashtable */
-typedef struct ConfigPerfItem {
- const char *section_and_lvalue; /* Section + "." + name of the variable */
- ConfigParserCallback parse; /* Function that is called to parse the variable's value */
- int ltype; /* Distinguish different variables passed to the same callback */
- size_t offset; /* Offset where to store data, from the beginning of userdata */
-} ConfigPerfItem;
-
-/* Prototype for a low-level gperf lookup function */
-typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lvalue, unsigned length);
-
-/* Prototype for a generic high-level lookup function */
-typedef int (*ConfigItemLookup)(
- const void *table,
- const char *section,
- const char *lvalue,
- ConfigParserCallback *func,
- int *ltype,
- void **data,
- void *userdata);
-
-/* Linear table search implementation of ConfigItemLookup, based on
- * ConfigTableItem arrays */
-int config_item_table_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
-
-/* gperf implementation of ConfigItemLookup, based on gperf
- * ConfigPerfItem tables */
-int config_item_perf_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
-
-int config_parse(
- const char *unit,
- const char *filename,
- FILE *f,
- const char *sections, /* nulstr */
- ConfigItemLookup lookup,
- const void *table,
- bool relaxed,
- bool allow_include,
- bool warn,
- void *userdata);
-
-int config_parse_many_nulstr(
- const char *conf_file, /* possibly NULL */
- const char *conf_file_dirs, /* nulstr */
- const char *sections, /* nulstr */
- ConfigItemLookup lookup,
- const void *table,
- bool relaxed,
- void *userdata);
-
-int config_parse_many(
- const char *conf_file, /* possibly NULL */
- const char* const* conf_file_dirs,
- const char *dropin_dirname,
- const char *sections, /* nulstr */
- ConfigItemLookup lookup,
- const void *table,
- bool relaxed,
- void *userdata);
-
-/* Generic parsers */
-int config_parse_int(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unsigned(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_long(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_uint16(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_uint32(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_uint64(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_double(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_iec_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_si_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_iec_uint64(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_bool(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_tristate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_string(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_nsec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_signal(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_personality(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_ifname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-
-#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
- int function(const char *unit, \
- const char *filename, \
- unsigned line, \
- const char *section, \
- unsigned section_line, \
- const char *lvalue, \
- int ltype, \
- const char *rvalue, \
- void *data, \
- void *userdata) { \
- \
- type *i = data, x; \
- \
- assert(filename); \
- assert(lvalue); \
- assert(rvalue); \
- assert(data); \
- \
- if ((x = name##_from_string(rvalue)) < 0) { \
- log_syntax(unit, LOG_ERR, filename, line, -x, \
- msg ", ignoring: %s", rvalue); \
- return 0; \
- } \
- \
- *i = x; \
- return 0; \
- }
-
-#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \
- int function(const char *unit, \
- const char *filename, \
- unsigned line, \
- const char *section, \
- unsigned section_line, \
- const char *lvalue, \
- int ltype, \
- const char *rvalue, \
- void *data, \
- void *userdata) { \
- \
- type **enums = data, x, *ys; \
- _cleanup_free_ type *xs = NULL; \
- const char *word, *state; \
- size_t l, i = 0; \
- \
- assert(filename); \
- assert(lvalue); \
- assert(rvalue); \
- assert(data); \
- \
- xs = new0(type, 1); \
- if (!xs) \
- return -ENOMEM; \
- \
- *xs = invalid; \
- \
- FOREACH_WORD(word, l, rvalue, state) { \
- _cleanup_free_ char *en = NULL; \
- type *new_xs; \
- \
- en = strndup(word, l); \
- if (!en) \
- return -ENOMEM; \
- \
- if ((x = name##_from_string(en)) < 0) { \
- log_syntax(unit, LOG_ERR, filename, line, \
- -x, msg ", ignoring: %s", en); \
- continue; \
- } \
- \
- for (ys = xs; x != invalid && *ys != invalid; ys++) { \
- if (*ys == x) { \
- log_syntax(unit, LOG_ERR, filename, \
- line, -x, \
- "Duplicate entry, ignoring: %s", \
- en); \
- x = invalid; \
- } \
- } \
- \
- if (x == invalid) \
- continue; \
- \
- *(xs + i) = x; \
- new_xs = realloc(xs, (++i + 1) * sizeof(type)); \
- if (new_xs) \
- xs = new_xs; \
- else \
- return -ENOMEM; \
- \
- *(xs + i) = invalid; \
- } \
- \
- free(*enums); \
- *enums = xs; \
- xs = NULL; \
- \
- return 0; \
- }
diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c
deleted file mode 100644
index b2d464c117..0000000000
--- a/src/shared/dev-setup.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010-2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "dev-setup.h"
-#include "label.h"
-#include "log.h"
-#include "path-util.h"
-#include "user-util.h"
-#include "util.h"
-
-int dev_setup(const char *prefix, uid_t uid, gid_t gid) {
- static const char symlinks[] =
- "-/proc/kcore\0" "/dev/core\0"
- "/proc/self/fd\0" "/dev/fd\0"
- "/proc/self/fd/0\0" "/dev/stdin\0"
- "/proc/self/fd/1\0" "/dev/stdout\0"
- "/proc/self/fd/2\0" "/dev/stderr\0";
-
- const char *j, *k;
- int r;
-
- NULSTR_FOREACH_PAIR(j, k, symlinks) {
- _cleanup_free_ char *link_name = NULL;
- const char *n;
-
- if (j[0] == '-') {
- j++;
-
- if (access(j, F_OK) < 0)
- continue;
- }
-
- if (prefix) {
- link_name = prefix_root(prefix, k);
- if (!link_name)
- return -ENOMEM;
-
- n = link_name;
- } else
- n = k;
-
- r = symlink_label(j, n);
- if (r < 0)
- log_debug_errno(r, "Failed to symlink %s to %s: %m", j, n);
-
- if (uid != UID_INVALID || gid != GID_INVALID)
- if (lchown(n, uid, gid) < 0)
- log_debug_errno(errno, "Failed to chown %s: %m", n);
- }
-
- return 0;
-}
diff --git a/src/shared/dev-setup.h b/src/shared/dev-setup.h
deleted file mode 100644
index 5766a62060..0000000000
--- a/src/shared/dev-setup.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010-2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/types.h>
-
-int dev_setup(const char *prefix, uid_t uid, gid_t gid);
diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c
deleted file mode 100644
index 892f0aadf5..0000000000
--- a/src/shared/dns-domain.c
+++ /dev/null
@@ -1,1326 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
- ***/
-
-#ifdef HAVE_LIBIDN
-#include <idna.h>
-#include <stringprep.h>
-#endif
-
-#include <endian.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-
-#include "alloc-util.h"
-#include "dns-domain.h"
-#include "hashmap.h"
-#include "hexdecoct.h"
-#include "in-addr-util.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "utf8.h"
-
-int dns_label_unescape(const char **name, char *dest, size_t sz) {
- const char *n;
- char *d;
- int r = 0;
-
- assert(name);
- assert(*name);
-
- n = *name;
- d = dest;
-
- for (;;) {
- if (*n == '.') {
- n++;
- break;
- }
-
- if (*n == 0)
- break;
-
- if (r >= DNS_LABEL_MAX)
- return -EINVAL;
-
- if (sz <= 0)
- return -ENOBUFS;
-
- if (*n == '\\') {
- /* Escaped character */
-
- n++;
-
- if (*n == 0)
- /* Ending NUL */
- return -EINVAL;
-
- else if (*n == '\\' || *n == '.') {
- /* Escaped backslash or dot */
-
- if (d)
- *(d++) = *n;
- sz--;
- r++;
- n++;
-
- } else if (n[0] >= '0' && n[0] <= '9') {
- unsigned k;
-
- /* Escaped literal ASCII character */
-
- if (!(n[1] >= '0' && n[1] <= '9') ||
- !(n[2] >= '0' && n[2] <= '9'))
- return -EINVAL;
-
- k = ((unsigned) (n[0] - '0') * 100) +
- ((unsigned) (n[1] - '0') * 10) +
- ((unsigned) (n[2] - '0'));
-
- /* Don't allow anything that doesn't
- * fit in 8bit. Note that we do allow
- * control characters, as some servers
- * (e.g. cloudflare) are happy to
- * generate labels with them
- * inside. */
- if (k > 255)
- return -EINVAL;
-
- if (d)
- *(d++) = (char) k;
- sz--;
- r++;
-
- n += 3;
- } else
- return -EINVAL;
-
- } else if ((uint8_t) *n >= (uint8_t) ' ' && *n != 127) {
-
- /* Normal character */
-
- if (d)
- *(d++) = *n;
- sz--;
- r++;
- n++;
- } else
- return -EINVAL;
- }
-
- /* Empty label that is not at the end? */
- if (r == 0 && *n)
- return -EINVAL;
-
- /* More than one trailing dot? */
- if (*n == '.')
- return -EINVAL;
-
- if (sz >= 1 && d)
- *d = 0;
-
- *name = n;
- return r;
-}
-
-/* @label_terminal: terminal character of a label, updated to point to the terminal character of
- * the previous label (always skipping one dot) or to NULL if there are no more
- * labels. */
-int dns_label_unescape_suffix(const char *name, const char **label_terminal, char *dest, size_t sz) {
- const char *terminal;
- int r;
-
- assert(name);
- assert(label_terminal);
- assert(dest);
-
- /* no more labels */
- if (!*label_terminal) {
- if (sz >= 1)
- *dest = 0;
-
- return 0;
- }
-
- terminal = *label_terminal;
- assert(*terminal == '.' || *terminal == 0);
-
- /* Skip current terminal character (and accept domain names ending it ".") */
- if (*terminal == 0)
- terminal--;
- if (terminal >= name && *terminal == '.')
- terminal--;
-
- /* Point name to the last label, and terminal to the preceding terminal symbol (or make it a NULL pointer) */
- for (;;) {
- if (terminal < name) {
- /* Reached the first label, so indicate that there are no more */
- terminal = NULL;
- break;
- }
-
- /* Find the start of the last label */
- if (*terminal == '.') {
- const char *y;
- unsigned slashes = 0;
-
- for (y = terminal - 1; y >= name && *y == '\\'; y--)
- slashes++;
-
- if (slashes % 2 == 0) {
- /* The '.' was not escaped */
- name = terminal + 1;
- break;
- } else {
- terminal = y;
- continue;
- }
- }
-
- terminal--;
- }
-
- r = dns_label_unescape(&name, dest, sz);
- if (r < 0)
- return r;
-
- *label_terminal = terminal;
-
- return r;
-}
-
-int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) {
- char *q;
-
- /* DNS labels must be between 1 and 63 characters long. A
- * zero-length label does not exist. See RFC 2182, Section
- * 11. */
-
- if (l <= 0 || l > DNS_LABEL_MAX)
- return -EINVAL;
- if (sz < 1)
- return -ENOBUFS;
-
- assert(p);
- assert(dest);
-
- q = dest;
- while (l > 0) {
-
- if (*p == '.' || *p == '\\') {
-
- /* Dot or backslash */
-
- if (sz < 3)
- return -ENOBUFS;
-
- *(q++) = '\\';
- *(q++) = *p;
-
- sz -= 2;
-
- } else if (*p == '_' ||
- *p == '-' ||
- (*p >= '0' && *p <= '9') ||
- (*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z')) {
-
- /* Proper character */
-
- if (sz < 2)
- return -ENOBUFS;
-
- *(q++) = *p;
- sz -= 1;
-
- } else {
-
- /* Everything else */
-
- if (sz < 5)
- return -ENOBUFS;
-
- *(q++) = '\\';
- *(q++) = '0' + (char) ((uint8_t) *p / 100);
- *(q++) = '0' + (char) (((uint8_t) *p / 10) % 10);
- *(q++) = '0' + (char) ((uint8_t) *p % 10);
-
- sz -= 4;
- }
-
- p++;
- l--;
- }
-
- *q = 0;
- return (int) (q - dest);
-}
-
-int dns_label_escape_new(const char *p, size_t l, char **ret) {
- _cleanup_free_ char *s = NULL;
- int r;
-
- assert(p);
- assert(ret);
-
- if (l <= 0 || l > DNS_LABEL_MAX)
- return -EINVAL;
-
- s = new(char, DNS_LABEL_ESCAPED_MAX);
- if (!s)
- return -ENOMEM;
-
- r = dns_label_escape(p, l, s, DNS_LABEL_ESCAPED_MAX);
- if (r < 0)
- return r;
-
- *ret = s;
- s = NULL;
-
- return r;
-}
-
-int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
-#ifdef HAVE_LIBIDN
- _cleanup_free_ uint32_t *input = NULL;
- size_t input_size, l;
- const char *p;
- bool contains_8bit = false;
- char buffer[DNS_LABEL_MAX+1];
-
- assert(encoded);
- assert(decoded);
-
- /* Converts an U-label into an A-label */
-
- if (encoded_size <= 0)
- return -EINVAL;
-
- for (p = encoded; p < encoded + encoded_size; p++)
- if ((uint8_t) *p > 127)
- contains_8bit = true;
-
- if (!contains_8bit) {
- if (encoded_size > DNS_LABEL_MAX)
- return -EINVAL;
-
- return 0;
- }
-
- input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
- if (!input)
- return -ENOMEM;
-
- if (idna_to_ascii_4i(input, input_size, buffer, 0) != 0)
- return -EINVAL;
-
- l = strlen(buffer);
-
- /* Verify that the result is not longer than one DNS label. */
- if (l <= 0 || l > DNS_LABEL_MAX)
- return -EINVAL;
- if (l > decoded_max)
- return -ENOBUFS;
-
- memcpy(decoded, buffer, l);
-
- /* If there's room, append a trailing NUL byte, but only then */
- if (decoded_max > l)
- decoded[l] = 0;
-
- return (int) l;
-#else
- return 0;
-#endif
-}
-
-int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
-#ifdef HAVE_LIBIDN
- size_t input_size, output_size;
- _cleanup_free_ uint32_t *input = NULL;
- _cleanup_free_ char *result = NULL;
- uint32_t *output = NULL;
- size_t w;
-
- /* To be invoked after unescaping. Converts an A-label into an U-label. */
-
- assert(encoded);
- assert(decoded);
-
- if (encoded_size <= 0 || encoded_size > DNS_LABEL_MAX)
- return -EINVAL;
-
- if (encoded_size < sizeof(IDNA_ACE_PREFIX)-1)
- return 0;
-
- if (memcmp(encoded, IDNA_ACE_PREFIX, sizeof(IDNA_ACE_PREFIX) -1) != 0)
- return 0;
-
- input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
- if (!input)
- return -ENOMEM;
-
- output_size = input_size;
- output = newa(uint32_t, output_size);
-
- idna_to_unicode_44i(input, input_size, output, &output_size, 0);
-
- result = stringprep_ucs4_to_utf8(output, output_size, NULL, &w);
- if (!result)
- return -ENOMEM;
- if (w <= 0)
- return -EINVAL;
- if (w > decoded_max)
- return -ENOBUFS;
-
- memcpy(decoded, result, w);
-
- /* Append trailing NUL byte if there's space, but only then. */
- if (decoded_max > w)
- decoded[w] = 0;
-
- return w;
-#else
- return 0;
-#endif
-}
-
-int dns_name_concat(const char *a, const char *b, char **_ret) {
- _cleanup_free_ char *ret = NULL;
- size_t n = 0, allocated = 0;
- const char *p;
- bool first = true;
- int r;
-
- if (a)
- p = a;
- else if (b) {
- p = b;
- b = NULL;
- } else
- goto finish;
-
- for (;;) {
- char label[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&p, label, sizeof(label));
- if (r < 0)
- return r;
- if (r == 0) {
- if (*p != 0)
- return -EINVAL;
-
- if (b) {
- /* Now continue with the second string, if there is one */
- p = b;
- b = NULL;
- continue;
- }
-
- break;
- }
-
- if (_ret) {
- if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
- return -ENOMEM;
-
- r = dns_label_escape(label, r, ret + n + !first, DNS_LABEL_ESCAPED_MAX);
- if (r < 0)
- return r;
-
- if (!first)
- ret[n] = '.';
- } else {
- char escaped[DNS_LABEL_ESCAPED_MAX];
-
- r = dns_label_escape(label, r, escaped, sizeof(escaped));
- if (r < 0)
- return r;
- }
-
- if (!first)
- n++;
- else
- first = false;
-
- n += r;
- }
-
-finish:
- if (n > DNS_HOSTNAME_MAX)
- return -EINVAL;
-
- if (_ret) {
- if (n == 0) {
- /* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */
- if (!GREEDY_REALLOC(ret, allocated, 2))
- return -ENOMEM;
-
- ret[n++] = '.';
- } else {
- if (!GREEDY_REALLOC(ret, allocated, n + 1))
- return -ENOMEM;
- }
-
- ret[n] = 0;
- *_ret = ret;
- ret = NULL;
- }
-
- return 0;
-}
-
-void dns_name_hash_func(const void *s, struct siphash *state) {
- const char *p = s;
- int r;
-
- assert(p);
-
- for (;;) {
- char label[DNS_LABEL_MAX+1];
-
- r = dns_label_unescape(&p, label, sizeof(label));
- if (r < 0)
- break;
- if (r == 0)
- break;
-
- ascii_strlower_n(label, r);
- siphash24_compress(label, r, state);
- siphash24_compress_byte(0, state); /* make sure foobar and foo.bar result in different hashes */
- }
-
- /* enforce that all names are terminated by the empty label */
- string_hash_func("", state);
-}
-
-int dns_name_compare_func(const void *a, const void *b) {
- const char *x, *y;
- int r, q;
-
- assert(a);
- assert(b);
-
- x = (const char *) a + strlen(a);
- y = (const char *) b + strlen(b);
-
- for (;;) {
- char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
-
- if (x == NULL && y == NULL)
- return 0;
-
- r = dns_label_unescape_suffix(a, &x, la, sizeof(la));
- q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb));
- if (r < 0 || q < 0)
- return r - q;
-
- r = ascii_strcasecmp_nn(la, r, lb, q);
- if (r != 0)
- return r;
- }
-}
-
-const struct hash_ops dns_name_hash_ops = {
- .hash = dns_name_hash_func,
- .compare = dns_name_compare_func
-};
-
-int dns_name_equal(const char *x, const char *y) {
- int r, q;
-
- assert(x);
- assert(y);
-
- for (;;) {
- char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&x, la, sizeof(la));
- if (r < 0)
- return r;
-
- q = dns_label_unescape(&y, lb, sizeof(lb));
- if (q < 0)
- return q;
-
- if (r != q)
- return false;
- if (r == 0)
- return true;
-
- if (ascii_strcasecmp_n(la, lb, r) != 0)
- return false;
- }
-}
-
-int dns_name_endswith(const char *name, const char *suffix) {
- const char *n, *s, *saved_n = NULL;
- int r, q;
-
- assert(name);
- assert(suffix);
-
- n = name;
- s = suffix;
-
- for (;;) {
- char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&n, ln, sizeof(ln));
- if (r < 0)
- return r;
-
- if (!saved_n)
- saved_n = n;
-
- q = dns_label_unescape(&s, ls, sizeof(ls));
- if (q < 0)
- return q;
-
- if (r == 0 && q == 0)
- return true;
- if (r == 0 && saved_n == n)
- return false;
-
- if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
-
- /* Not the same, let's jump back, and try with the next label again */
- s = suffix;
- n = saved_n;
- saved_n = NULL;
- }
- }
-}
-
-int dns_name_startswith(const char *name, const char *prefix) {
- const char *n, *p;
- int r, q;
-
- assert(name);
- assert(prefix);
-
- n = name;
- p = prefix;
-
- for (;;) {
- char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&p, lp, sizeof(lp));
- if (r < 0)
- return r;
- if (r == 0)
- return true;
-
- q = dns_label_unescape(&n, ln, sizeof(ln));
- if (q < 0)
- return q;
-
- if (r != q)
- return false;
- if (ascii_strcasecmp_n(ln, lp, r) != 0)
- return false;
- }
-}
-
-int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret) {
- const char *n, *s, *saved_before = NULL, *saved_after = NULL, *prefix;
- int r, q;
-
- assert(name);
- assert(old_suffix);
- assert(new_suffix);
- assert(ret);
-
- n = name;
- s = old_suffix;
-
- for (;;) {
- char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
-
- if (!saved_before)
- saved_before = n;
-
- r = dns_label_unescape(&n, ln, sizeof(ln));
- if (r < 0)
- return r;
-
- if (!saved_after)
- saved_after = n;
-
- q = dns_label_unescape(&s, ls, sizeof(ls));
- if (q < 0)
- return q;
-
- if (r == 0 && q == 0)
- break;
- if (r == 0 && saved_after == n) {
- *ret = NULL; /* doesn't match */
- return 0;
- }
-
- if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
-
- /* Not the same, let's jump back, and try with the next label again */
- s = old_suffix;
- n = saved_after;
- saved_after = saved_before = NULL;
- }
- }
-
- /* Found it! Now generate the new name */
- prefix = strndupa(name, saved_before - name);
-
- r = dns_name_concat(prefix, new_suffix, ret);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-int dns_name_between(const char *a, const char *b, const char *c) {
- int n;
-
- /* Determine if b is strictly greater than a and strictly smaller than c.
- We consider the order of names to be circular, so that if a is
- strictly greater than c, we consider b to be between them if it is
- either greater than a or smaller than c. This is how the canonical
- DNS name order used in NSEC records work. */
-
- n = dns_name_compare_func(a, c);
- if (n == 0)
- return -EINVAL;
- else if (n < 0)
- /* a<---b--->c */
- return dns_name_compare_func(a, b) < 0 &&
- dns_name_compare_func(b, c) < 0;
- else
- /* <--b--c a--b--> */
- return dns_name_compare_func(b, c) < 0 ||
- dns_name_compare_func(a, b) < 0;
-}
-
-int dns_name_reverse(int family, const union in_addr_union *a, char **ret) {
- const uint8_t *p;
- int r;
-
- assert(a);
- assert(ret);
-
- p = (const uint8_t*) a;
-
- if (family == AF_INET)
- r = asprintf(ret, "%u.%u.%u.%u.in-addr.arpa", p[3], p[2], p[1], p[0]);
- else if (family == AF_INET6)
- r = asprintf(ret, "%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.ip6.arpa",
- hexchar(p[15] & 0xF), hexchar(p[15] >> 4), hexchar(p[14] & 0xF), hexchar(p[14] >> 4),
- hexchar(p[13] & 0xF), hexchar(p[13] >> 4), hexchar(p[12] & 0xF), hexchar(p[12] >> 4),
- hexchar(p[11] & 0xF), hexchar(p[11] >> 4), hexchar(p[10] & 0xF), hexchar(p[10] >> 4),
- hexchar(p[ 9] & 0xF), hexchar(p[ 9] >> 4), hexchar(p[ 8] & 0xF), hexchar(p[ 8] >> 4),
- hexchar(p[ 7] & 0xF), hexchar(p[ 7] >> 4), hexchar(p[ 6] & 0xF), hexchar(p[ 6] >> 4),
- hexchar(p[ 5] & 0xF), hexchar(p[ 5] >> 4), hexchar(p[ 4] & 0xF), hexchar(p[ 4] >> 4),
- hexchar(p[ 3] & 0xF), hexchar(p[ 3] >> 4), hexchar(p[ 2] & 0xF), hexchar(p[ 2] >> 4),
- hexchar(p[ 1] & 0xF), hexchar(p[ 1] >> 4), hexchar(p[ 0] & 0xF), hexchar(p[ 0] >> 4));
- else
- return -EAFNOSUPPORT;
- if (r < 0)
- return -ENOMEM;
-
- return 0;
-}
-
-int dns_name_address(const char *p, int *family, union in_addr_union *address) {
- int r;
-
- assert(p);
- assert(family);
- assert(address);
-
- r = dns_name_endswith(p, "in-addr.arpa");
- if (r < 0)
- return r;
- if (r > 0) {
- uint8_t a[4];
- unsigned i;
-
- for (i = 0; i < ELEMENTSOF(a); i++) {
- char label[DNS_LABEL_MAX+1];
-
- r = dns_label_unescape(&p, label, sizeof(label));
- if (r < 0)
- return r;
- if (r == 0)
- return -EINVAL;
- if (r > 3)
- return -EINVAL;
-
- r = safe_atou8(label, &a[i]);
- if (r < 0)
- return r;
- }
-
- r = dns_name_equal(p, "in-addr.arpa");
- if (r <= 0)
- return r;
-
- *family = AF_INET;
- address->in.s_addr = htobe32(((uint32_t) a[3] << 24) |
- ((uint32_t) a[2] << 16) |
- ((uint32_t) a[1] << 8) |
- (uint32_t) a[0]);
-
- return 1;
- }
-
- r = dns_name_endswith(p, "ip6.arpa");
- if (r < 0)
- return r;
- if (r > 0) {
- struct in6_addr a;
- unsigned i;
-
- for (i = 0; i < ELEMENTSOF(a.s6_addr); i++) {
- char label[DNS_LABEL_MAX+1];
- int x, y;
-
- r = dns_label_unescape(&p, label, sizeof(label));
- if (r <= 0)
- return r;
- if (r != 1)
- return -EINVAL;
- x = unhexchar(label[0]);
- if (x < 0)
- return -EINVAL;
-
- r = dns_label_unescape(&p, label, sizeof(label));
- if (r <= 0)
- return r;
- if (r != 1)
- return -EINVAL;
- y = unhexchar(label[0]);
- if (y < 0)
- return -EINVAL;
-
- a.s6_addr[ELEMENTSOF(a.s6_addr) - i - 1] = (uint8_t) y << 4 | (uint8_t) x;
- }
-
- r = dns_name_equal(p, "ip6.arpa");
- if (r <= 0)
- return r;
-
- *family = AF_INET6;
- address->in6 = a;
- return 1;
- }
-
- return 0;
-}
-
-bool dns_name_is_root(const char *name) {
-
- assert(name);
-
- /* There are exactly two ways to encode the root domain name:
- * as empty string, or with a single dot. */
-
- return STR_IN_SET(name, "", ".");
-}
-
-bool dns_name_is_single_label(const char *name) {
- int r;
-
- assert(name);
-
- r = dns_name_parent(&name);
- if (r <= 0)
- return false;
-
- return dns_name_is_root(name);
-}
-
-/* Encode a domain name according to RFC 1035 Section 3.1, without compression */
-int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical) {
- uint8_t *label_length, *out;
- int r;
-
- assert(domain);
- assert(buffer);
-
- out = buffer;
-
- do {
- /* Reserve a byte for label length */
- if (len <= 0)
- return -ENOBUFS;
- len--;
- label_length = out;
- out++;
-
- /* Convert and copy a single label. Note that
- * dns_label_unescape() returns 0 when it hits the end
- * of the domain name, which we rely on here to encode
- * the trailing NUL byte. */
- r = dns_label_unescape(&domain, (char *) out, len);
- if (r < 0)
- return r;
-
- /* Optionally, output the name in DNSSEC canonical
- * format, as described in RFC 4034, section 6.2. Or
- * in other words: in lower-case. */
- if (canonical)
- ascii_strlower_n((char*) out, (size_t) r);
-
- /* Fill label length, move forward */
- *label_length = r;
- out += r;
- len -= r;
-
- } while (r != 0);
-
- /* Verify the maximum size of the encoded name. The trailing
- * dot + NUL byte account are included this time, hence
- * compare against DNS_HOSTNAME_MAX + 2 (which is 255) this
- * time. */
- if (out - buffer > DNS_HOSTNAME_MAX + 2)
- return -EINVAL;
-
- return out - buffer;
-}
-
-static bool srv_type_label_is_valid(const char *label, size_t n) {
- size_t k;
-
- assert(label);
-
- if (n < 2) /* Label needs to be at least 2 chars long */
- return false;
-
- if (label[0] != '_') /* First label char needs to be underscore */
- return false;
-
- /* Second char must be a letter */
- if (!(label[1] >= 'A' && label[1] <= 'Z') &&
- !(label[1] >= 'a' && label[1] <= 'z'))
- return false;
-
- /* Third and further chars must be alphanumeric or a hyphen */
- for (k = 2; k < n; k++) {
- if (!(label[k] >= 'A' && label[k] <= 'Z') &&
- !(label[k] >= 'a' && label[k] <= 'z') &&
- !(label[k] >= '0' && label[k] <= '9') &&
- label[k] != '-')
- return false;
- }
-
- return true;
-}
-
-bool dns_srv_type_is_valid(const char *name) {
- unsigned c = 0;
- int r;
-
- if (!name)
- return false;
-
- for (;;) {
- char label[DNS_LABEL_MAX];
-
- /* This more or less implements RFC 6335, Section 5.1 */
-
- r = dns_label_unescape(&name, label, sizeof(label));
- if (r < 0)
- return false;
- if (r == 0)
- break;
-
- if (c >= 2)
- return false;
-
- if (!srv_type_label_is_valid(label, r))
- return false;
-
- c++;
- }
-
- return c == 2; /* exactly two labels */
-}
-
-bool dns_service_name_is_valid(const char *name) {
- size_t l;
-
- /* This more or less implements RFC 6763, Section 4.1.1 */
-
- if (!name)
- return false;
-
- if (!utf8_is_valid(name))
- return false;
-
- if (string_has_cc(name, NULL))
- return false;
-
- l = strlen(name);
- if (l <= 0)
- return false;
- if (l > 63)
- return false;
-
- return true;
-}
-
-int dns_service_join(const char *name, const char *type, const char *domain, char **ret) {
- char escaped[DNS_LABEL_ESCAPED_MAX];
- _cleanup_free_ char *n = NULL;
- int r;
-
- assert(type);
- assert(domain);
- assert(ret);
-
- if (!dns_srv_type_is_valid(type))
- return -EINVAL;
-
- if (!name)
- return dns_name_concat(type, domain, ret);
-
- if (!dns_service_name_is_valid(name))
- return -EINVAL;
-
- r = dns_label_escape(name, strlen(name), escaped, sizeof(escaped));
- if (r < 0)
- return r;
-
- r = dns_name_concat(type, domain, &n);
- if (r < 0)
- return r;
-
- return dns_name_concat(escaped, n, ret);
-}
-
-static bool dns_service_name_label_is_valid(const char *label, size_t n) {
- char *s;
-
- assert(label);
-
- if (memchr(label, 0, n))
- return false;
-
- s = strndupa(label, n);
- return dns_service_name_is_valid(s);
-}
-
-int dns_service_split(const char *joined, char **_name, char **_type, char **_domain) {
- _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
- const char *p = joined, *q = NULL, *d = NULL;
- char a[DNS_LABEL_MAX], b[DNS_LABEL_MAX], c[DNS_LABEL_MAX];
- int an, bn, cn, r;
- unsigned x = 0;
-
- assert(joined);
-
- /* Get first label from the full name */
- an = dns_label_unescape(&p, a, sizeof(a));
- if (an < 0)
- return an;
-
- if (an > 0) {
- x++;
-
- /* If there was a first label, try to get the second one */
- bn = dns_label_unescape(&p, b, sizeof(b));
- if (bn < 0)
- return bn;
-
- if (bn > 0) {
- x++;
-
- /* If there was a second label, try to get the third one */
- q = p;
- cn = dns_label_unescape(&p, c, sizeof(c));
- if (cn < 0)
- return cn;
-
- if (cn > 0)
- x++;
- } else
- cn = 0;
- } else
- an = 0;
-
- if (x >= 2 && srv_type_label_is_valid(b, bn)) {
-
- if (x >= 3 && srv_type_label_is_valid(c, cn)) {
-
- if (dns_service_name_label_is_valid(a, an)) {
- /* OK, got <name> . <type> . <type2> . <domain> */
-
- name = strndup(a, an);
- if (!name)
- return -ENOMEM;
-
- type = strjoin(b, ".", c, NULL);
- if (!type)
- return -ENOMEM;
-
- d = p;
- goto finish;
- }
-
- } else if (srv_type_label_is_valid(a, an)) {
-
- /* OK, got <type> . <type2> . <domain> */
-
- name = NULL;
-
- type = strjoin(a, ".", b, NULL);
- if (!type)
- return -ENOMEM;
-
- d = q;
- goto finish;
- }
- }
-
- name = NULL;
- type = NULL;
- d = joined;
-
-finish:
- r = dns_name_normalize(d, &domain);
- if (r < 0)
- return r;
-
- if (_domain) {
- *_domain = domain;
- domain = NULL;
- }
-
- if (_type) {
- *_type = type;
- type = NULL;
- }
-
- if (_name) {
- *_name = name;
- name = NULL;
- }
-
- return 0;
-}
-
-static int dns_name_build_suffix_table(const char *name, const char*table[]) {
- const char *p;
- unsigned n = 0;
- int r;
-
- assert(name);
- assert(table);
-
- p = name;
- for (;;) {
- if (n > DNS_N_LABELS_MAX)
- return -EINVAL;
-
- table[n] = p;
- r = dns_name_parent(&p);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- n++;
- }
-
- return (int) n;
-}
-
-int dns_name_suffix(const char *name, unsigned n_labels, const char **ret) {
- const char* labels[DNS_N_LABELS_MAX+1];
- int n;
-
- assert(name);
- assert(ret);
-
- n = dns_name_build_suffix_table(name, labels);
- if (n < 0)
- return n;
-
- if ((unsigned) n < n_labels)
- return -EINVAL;
-
- *ret = labels[n - n_labels];
- return (int) (n - n_labels);
-}
-
-int dns_name_skip(const char *a, unsigned n_labels, const char **ret) {
- int r;
-
- assert(a);
- assert(ret);
-
- for (; n_labels > 0; n_labels--) {
- r = dns_name_parent(&a);
- if (r < 0)
- return r;
- if (r == 0) {
- *ret = "";
- return 0;
- }
- }
-
- *ret = a;
- return 1;
-}
-
-int dns_name_count_labels(const char *name) {
- unsigned n = 0;
- const char *p;
- int r;
-
- assert(name);
-
- p = name;
- for (;;) {
- r = dns_name_parent(&p);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- if (n >= DNS_N_LABELS_MAX)
- return -EINVAL;
-
- n++;
- }
-
- return (int) n;
-}
-
-int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b) {
- int r;
-
- assert(a);
- assert(b);
-
- r = dns_name_skip(a, n_labels, &a);
- if (r <= 0)
- return r;
-
- return dns_name_equal(a, b);
-}
-
-int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
- const char *a_labels[DNS_N_LABELS_MAX+1], *b_labels[DNS_N_LABELS_MAX+1];
- int n = 0, m = 0, k = 0, r, q;
-
- assert(a);
- assert(b);
- assert(ret);
-
- /* Determines the common suffix of domain names a and b */
-
- n = dns_name_build_suffix_table(a, a_labels);
- if (n < 0)
- return n;
-
- m = dns_name_build_suffix_table(b, b_labels);
- if (m < 0)
- return m;
-
- for (;;) {
- char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
- const char *x, *y;
-
- if (k >= n || k >= m) {
- *ret = a_labels[n - k];
- return 0;
- }
-
- x = a_labels[n - 1 - k];
- r = dns_label_unescape(&x, la, sizeof(la));
- if (r < 0)
- return r;
-
- y = b_labels[m - 1 - k];
- q = dns_label_unescape(&y, lb, sizeof(lb));
- if (q < 0)
- return q;
-
- if (r != q || ascii_strcasecmp_n(la, lb, r) != 0) {
- *ret = a_labels[n - k];
- return 0;
- }
-
- k++;
- }
-}
-
-int dns_name_apply_idna(const char *name, char **ret) {
- _cleanup_free_ char *buf = NULL;
- size_t n = 0, allocated = 0;
- bool first = true;
- int r, q;
-
- assert(name);
- assert(ret);
-
- for (;;) {
- char label[DNS_LABEL_MAX];
-
- r = dns_label_unescape(&name, label, sizeof(label));
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- q = dns_label_apply_idna(label, r, label, sizeof(label));
- if (q < 0)
- return q;
- if (q > 0)
- r = q;
-
- if (!GREEDY_REALLOC(buf, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
- return -ENOMEM;
-
- r = dns_label_escape(label, r, buf + n + !first, DNS_LABEL_ESCAPED_MAX);
- if (r < 0)
- return r;
-
- if (first)
- first = false;
- else
- buf[n++] = '.';
-
- n +=r;
- }
-
- if (n > DNS_HOSTNAME_MAX)
- return -EINVAL;
-
- if (!GREEDY_REALLOC(buf, allocated, n + 1))
- return -ENOMEM;
-
- buf[n] = 0;
- *ret = buf;
- buf = NULL;
-
- return (int) n;
-}
diff --git a/src/shared/dns-domain.h b/src/shared/dns-domain.h
deleted file mode 100644
index af780f0b8b..0000000000
--- a/src/shared/dns-domain.h
+++ /dev/null
@@ -1,109 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
- ***/
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "hashmap.h"
-#include "in-addr-util.h"
-
-/* Length of a single label, with all escaping removed, excluding any trailing dot or NUL byte */
-#define DNS_LABEL_MAX 63
-
-/* Worst case length of a single label, with all escaping applied and room for a trailing NUL byte. */
-#define DNS_LABEL_ESCAPED_MAX (DNS_LABEL_MAX*4+1)
-
-/* Maximum length of a full hostname, consisting of a series of unescaped labels, and no trailing dot or NUL byte */
-#define DNS_HOSTNAME_MAX 253
-
-/* Maximum length of a full hostname, on the wire, including the final NUL byte */
-#define DNS_WIRE_FOMAT_HOSTNAME_MAX 255
-
-/* Maximum number of labels per valid hostname */
-#define DNS_N_LABELS_MAX 127
-
-int dns_label_unescape(const char **name, char *dest, size_t sz);
-int dns_label_unescape_suffix(const char *name, const char **label_end, char *dest, size_t sz);
-int dns_label_escape(const char *p, size_t l, char *dest, size_t sz);
-int dns_label_escape_new(const char *p, size_t l, char **ret);
-
-static inline int dns_name_parent(const char **name) {
- return dns_label_unescape(name, NULL, DNS_LABEL_MAX);
-}
-
-int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
-int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
-
-int dns_name_concat(const char *a, const char *b, char **ret);
-
-static inline int dns_name_normalize(const char *s, char **ret) {
- /* dns_name_concat() normalizes as a side-effect */
- return dns_name_concat(s, NULL, ret);
-}
-
-static inline int dns_name_is_valid(const char *s) {
- int r;
-
- /* dns_name_normalize() verifies as a side effect */
- r = dns_name_normalize(s, NULL);
- if (r == -EINVAL)
- return 0;
- if (r < 0)
- return r;
- return 1;
-}
-
-void dns_name_hash_func(const void *s, struct siphash *state);
-int dns_name_compare_func(const void *a, const void *b);
-extern const struct hash_ops dns_name_hash_ops;
-
-int dns_name_between(const char *a, const char *b, const char *c);
-int dns_name_equal(const char *x, const char *y);
-int dns_name_endswith(const char *name, const char *suffix);
-int dns_name_startswith(const char *name, const char *prefix);
-
-int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret);
-
-int dns_name_reverse(int family, const union in_addr_union *a, char **ret);
-int dns_name_address(const char *p, int *family, union in_addr_union *a);
-
-bool dns_name_is_root(const char *name);
-bool dns_name_is_single_label(const char *name);
-
-int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical);
-
-bool dns_srv_type_is_valid(const char *name);
-bool dns_service_name_is_valid(const char *name);
-
-int dns_service_join(const char *name, const char *type, const char *domain, char **ret);
-int dns_service_split(const char *joined, char **name, char **type, char **domain);
-
-int dns_name_suffix(const char *name, unsigned n_labels, const char **ret);
-int dns_name_count_labels(const char *name);
-
-int dns_name_skip(const char *a, unsigned n_labels, const char **ret);
-int dns_name_equal_skip(const char *a, unsigned n_labels, const char *b);
-
-int dns_name_common_suffix(const char *a, const char *b, const char **ret);
-
-int dns_name_apply_idna(const char *name, char **ret);
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
deleted file mode 100644
index b9cd952ac8..0000000000
--- a/src/shared/dropin.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <dirent.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "alloc-util.h"
-#include "conf-files.h"
-#include "dropin.h"
-#include "escape.h"
-#include "fd-util.h"
-#include "fileio-label.h"
-#include "hashmap.h"
-#include "log.h"
-#include "macro.h"
-#include "mkdir.h"
-#include "path-util.h"
-#include "set.h"
-#include "string-util.h"
-#include "strv.h"
-#include "unit-name.h"
-
-int drop_in_file(const char *dir, const char *unit, unsigned level,
- const char *name, char **_p, char **_q) {
-
- _cleanup_free_ char *b = NULL;
- char *p, *q;
-
- char prefix[DECIMAL_STR_MAX(unsigned)];
-
- assert(unit);
- assert(name);
- assert(_p);
- assert(_q);
-
- sprintf(prefix, "%u", level);
-
- b = xescape(name, "/.");
- if (!b)
- return -ENOMEM;
-
- if (!filename_is_valid(b))
- return -EINVAL;
-
- p = strjoin(dir, "/", unit, ".d", NULL);
- if (!p)
- return -ENOMEM;
-
- q = strjoin(p, "/", prefix, "-", b, ".conf", NULL);
- if (!q) {
- free(p);
- return -ENOMEM;
- }
-
- *_p = p;
- *_q = q;
- return 0;
-}
-
-int write_drop_in(const char *dir, const char *unit, unsigned level,
- const char *name, const char *data) {
-
- _cleanup_free_ char *p = NULL, *q = NULL;
- int r;
-
- assert(dir);
- assert(unit);
- assert(name);
- assert(data);
-
- r = drop_in_file(dir, unit, level, name, &p, &q);
- if (r < 0)
- return r;
-
- (void) mkdir_p(p, 0755);
- return write_string_file_atomic_label(q, data);
-}
-
-int write_drop_in_format(const char *dir, const char *unit, unsigned level,
- const char *name, const char *format, ...) {
- _cleanup_free_ char *p = NULL;
- va_list ap;
- int r;
-
- assert(dir);
- assert(unit);
- assert(name);
- assert(format);
-
- va_start(ap, format);
- r = vasprintf(&p, format, ap);
- va_end(ap);
-
- if (r < 0)
- return -ENOMEM;
-
- return write_drop_in(dir, unit, level, name, p);
-}
-
-static int iterate_dir(
- const char *path,
- UnitDependency dependency,
- dependency_consumer_t consumer,
- void *arg,
- char ***strv) {
-
- _cleanup_closedir_ DIR *d = NULL;
- int r;
-
- assert(path);
-
- /* The config directories are special, since the order of the
- * drop-ins matters */
- if (dependency < 0) {
- r = strv_extend(strv, path);
- if (r < 0)
- return log_oom();
-
- return 0;
- }
-
- assert(consumer);
-
- d = opendir(path);
- if (!d) {
- if (errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open directory %s: %m", path);
- }
-
- for (;;) {
- struct dirent *de;
- _cleanup_free_ char *f = NULL;
-
- errno = 0;
- de = readdir(d);
- if (!de && errno > 0)
- return log_error_errno(errno, "Failed to read directory %s: %m", path);
-
- if (!de)
- break;
-
- if (hidden_or_backup_file(de->d_name))
- continue;
-
- f = strjoin(path, "/", de->d_name, NULL);
- if (!f)
- return log_oom();
-
- r = consumer(dependency, de->d_name, f, arg);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-int unit_file_process_dir(
- Set *unit_path_cache,
- const char *unit_path,
- const char *name,
- const char *suffix,
- UnitDependency dependency,
- dependency_consumer_t consumer,
- void *arg,
- char ***strv) {
-
- _cleanup_free_ char *path = NULL;
- int r;
-
- assert(unit_path);
- assert(name);
- assert(suffix);
-
- path = strjoin(unit_path, "/", name, suffix, NULL);
- if (!path)
- return log_oom();
-
- if (!unit_path_cache || set_get(unit_path_cache, path))
- (void) iterate_dir(path, dependency, consumer, arg, strv);
-
- if (unit_name_is_valid(name, UNIT_NAME_INSTANCE)) {
- _cleanup_free_ char *template = NULL, *p = NULL;
- /* Also try the template dir */
-
- r = unit_name_template(name, &template);
- if (r < 0)
- return log_error_errno(r, "Failed to generate template from unit name: %m");
-
- p = strjoin(unit_path, "/", template, suffix, NULL);
- if (!p)
- return log_oom();
-
- if (!unit_path_cache || set_get(unit_path_cache, p))
- (void) iterate_dir(p, dependency, consumer, arg, strv);
- }
-
- return 0;
-}
-
-int unit_file_find_dropin_paths(
- char **lookup_path,
- Set *unit_path_cache,
- Set *names,
- char ***paths) {
-
- _cleanup_strv_free_ char **strv = NULL, **ans = NULL;
- Iterator i;
- char *t;
- int r;
-
- assert(paths);
-
- SET_FOREACH(t, names, i) {
- char **p;
-
- STRV_FOREACH(p, lookup_path)
- unit_file_process_dir(unit_path_cache, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, NULL, NULL, &strv);
- }
-
- if (strv_isempty(strv))
- return 0;
-
- r = conf_files_list_strv(&ans, ".conf", NULL, (const char**) strv);
- if (r < 0)
- return log_warning_errno(r, "Failed to get list of configuration files: %m");
-
- *paths = ans;
- ans = NULL;
- return 1;
-}
diff --git a/src/shared/dropin.h b/src/shared/dropin.h
deleted file mode 100644
index c1936f397b..0000000000
--- a/src/shared/dropin.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "hashmap.h"
-#include "macro.h"
-#include "set.h"
-#include "unit-name.h"
-
-int drop_in_file(const char *dir, const char *unit, unsigned level,
- const char *name, char **_p, char **_q);
-
-int write_drop_in(const char *dir, const char *unit, unsigned level,
- const char *name, const char *data);
-
-int write_drop_in_format(const char *dir, const char *unit, unsigned level,
- const char *name, const char *format, ...) _printf_(5, 6);
-
-/**
- * This callback will be called for each directory entry @entry,
- * with @filepath being the full path to the entry.
- *
- * If return value is negative, loop will be aborted.
- */
-typedef int (*dependency_consumer_t)(UnitDependency dependency,
- const char *entry,
- const char* filepath,
- void *arg);
-
-int unit_file_process_dir(
- Set * unit_path_cache,
- const char *unit_path,
- const char *name,
- const char *suffix,
- UnitDependency dependency,
- dependency_consumer_t consumer,
- void *arg,
- char ***strv);
-
-int unit_file_find_dropin_paths(
- char **lookup_path,
- Set *unit_path_cache,
- Set *names,
- char ***paths);
diff --git a/src/shared/efivars.c b/src/shared/efivars.c
deleted file mode 100644
index 8631a5a5d9..0000000000
--- a/src/shared/efivars.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "sd-id128.h"
-
-#include "alloc-util.h"
-#include "dirent-util.h"
-#include "efivars.h"
-#include "fd-util.h"
-#include "io-util.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "stdio-util.h"
-#include "time-util.h"
-#include "utf8.h"
-#include "util.h"
-#include "virt.h"
-
-#ifdef ENABLE_EFI
-
-#define LOAD_OPTION_ACTIVE 0x00000001
-#define MEDIA_DEVICE_PATH 0x04
-#define MEDIA_HARDDRIVE_DP 0x01
-#define MEDIA_FILEPATH_DP 0x04
-#define SIGNATURE_TYPE_GUID 0x02
-#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
-#define END_DEVICE_PATH_TYPE 0x7f
-#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
-#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
-
-struct boot_option {
- uint32_t attr;
- uint16_t path_len;
- uint16_t title[];
-} _packed_;
-
-struct drive_path {
- uint32_t part_nr;
- uint64_t part_start;
- uint64_t part_size;
- char signature[16];
- uint8_t mbr_type;
- uint8_t signature_type;
-} _packed_;
-
-struct device_path {
- uint8_t type;
- uint8_t sub_type;
- uint16_t length;
- union {
- uint16_t path[0];
- struct drive_path drive;
- };
-} _packed_;
-
-bool is_efi_boot(void) {
- return access("/sys/firmware/efi", F_OK) >= 0;
-}
-
-static int read_flag(const char *varname) {
- int r;
- _cleanup_free_ void *v = NULL;
- size_t s;
- uint8_t b;
-
- r = efi_get_variable(EFI_VENDOR_GLOBAL, varname, NULL, &v, &s);
- if (r < 0)
- return r;
-
- if (s != 1)
- return -EINVAL;
-
- b = *(uint8_t *)v;
- r = b > 0;
- return r;
-}
-
-bool is_efi_secure_boot(void) {
- return read_flag("SecureBoot") > 0;
-}
-
-bool is_efi_secure_boot_setup_mode(void) {
- return read_flag("SetupMode") > 0;
-}
-
-int efi_reboot_to_firmware_supported(void) {
- int r;
- size_t s;
- uint64_t b;
- _cleanup_free_ void *v = NULL;
-
- if (!is_efi_boot() || detect_container() > 0)
- return -EOPNOTSUPP;
-
- r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s);
- if (r < 0)
- return r;
- else if (s != sizeof(uint64_t))
- return -EINVAL;
-
- b = *(uint64_t *)v;
- b &= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
- return b > 0 ? 0 : -EOPNOTSUPP;
-}
-
-static int get_os_indications(uint64_t *os_indication) {
- int r;
- size_t s;
- _cleanup_free_ void *v = NULL;
-
- r = efi_reboot_to_firmware_supported();
- if (r < 0)
- return r;
-
- r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndications", NULL, &v, &s);
- if (r == -ENOENT) {
- /* Some firmware implementations that do support
- * OsIndications and report that with
- * OsIndicationsSupported will remove the
- * OsIndications variable when it is unset. Let's
- * pretend it's 0 then, to hide this implementation
- * detail. Note that this call will return -ENOENT
- * then only if the support for OsIndications is
- * missing entirely, as determined by
- * efi_reboot_to_firmware_supported() above. */
- *os_indication = 0;
- return 0;
- } else if (r < 0)
- return r;
- else if (s != sizeof(uint64_t))
- return -EINVAL;
-
- *os_indication = *(uint64_t *)v;
- return 0;
-}
-
-int efi_get_reboot_to_firmware(void) {
- int r;
- uint64_t b;
-
- r = get_os_indications(&b);
- if (r < 0)
- return r;
-
- return !!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI);
-}
-
-int efi_set_reboot_to_firmware(bool value) {
- int r;
- uint64_t b, b_new;
-
- r = get_os_indications(&b);
- if (r < 0)
- return r;
-
- if (value)
- b_new = b | EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
- else
- b_new = b & ~EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
-
- /* Avoid writing to efi vars store if we can due to firmware bugs. */
- if (b != b_new)
- return efi_set_variable(EFI_VENDOR_GLOBAL, "OsIndications", &b_new, sizeof(uint64_t));
-
- return 0;
-}
-
-int efi_get_variable(
- sd_id128_t vendor,
- const char *name,
- uint32_t *attribute,
- void **value,
- size_t *size) {
-
- _cleanup_close_ int fd = -1;
- _cleanup_free_ char *p = NULL;
- uint32_t a;
- ssize_t n;
- struct stat st;
- _cleanup_free_ void *buf = NULL;
-
- assert(name);
- assert(value);
- assert(size);
-
- if (asprintf(&p,
- "/sys/firmware/efi/efivars/%s-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- name, SD_ID128_FORMAT_VAL(vendor)) < 0)
- return -ENOMEM;
-
- fd = open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- if (fstat(fd, &st) < 0)
- return -errno;
- if (st.st_size < 4)
- return -EIO;
- if (st.st_size > 4*1024*1024 + 4)
- return -E2BIG;
-
- n = read(fd, &a, sizeof(a));
- if (n < 0)
- return -errno;
- if (n != sizeof(a))
- return -EIO;
-
- buf = malloc(st.st_size - 4 + 2);
- if (!buf)
- return -ENOMEM;
-
- n = read(fd, buf, (size_t) st.st_size - 4);
- if (n < 0)
- return -errno;
- if (n != (ssize_t) st.st_size - 4)
- return -EIO;
-
- /* Always NUL terminate (2 bytes, to protect UTF-16) */
- ((char*) buf)[st.st_size - 4] = 0;
- ((char*) buf)[st.st_size - 4 + 1] = 0;
-
- *value = buf;
- buf = NULL;
- *size = (size_t) st.st_size - 4;
-
- if (attribute)
- *attribute = a;
-
- return 0;
-}
-
-int efi_set_variable(
- sd_id128_t vendor,
- const char *name,
- const void *value,
- size_t size) {
-
- struct var {
- uint32_t attr;
- char buf[];
- } _packed_ * _cleanup_free_ buf = NULL;
- _cleanup_free_ char *p = NULL;
- _cleanup_close_ int fd = -1;
-
- assert(name);
-
- if (asprintf(&p,
- "/sys/firmware/efi/efivars/%s-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- name, SD_ID128_FORMAT_VAL(vendor)) < 0)
- return -ENOMEM;
-
- if (size == 0) {
- if (unlink(p) < 0)
- return -errno;
- return 0;
- }
-
- fd = open(p, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0644);
- if (fd < 0)
- return -errno;
-
- buf = malloc(sizeof(uint32_t) + size);
- if (!buf)
- return -ENOMEM;
-
- buf->attr = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
- memcpy(buf->buf, value, size);
-
- return loop_write(fd, buf, sizeof(uint32_t) + size, false);
-}
-
-int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
- _cleanup_free_ void *s = NULL;
- size_t ss = 0;
- int r;
- char *x;
-
- r = efi_get_variable(vendor, name, NULL, &s, &ss);
- if (r < 0)
- return r;
-
- x = utf16_to_utf8(s, ss);
- if (!x)
- return -ENOMEM;
-
- *p = x;
- return 0;
-}
-
-static size_t utf16_size(const uint16_t *s) {
- size_t l = 0;
-
- while (s[l] > 0)
- l++;
-
- return (l+1) * sizeof(uint16_t);
-}
-
-static void efi_guid_to_id128(const void *guid, sd_id128_t *id128) {
- struct uuid {
- uint32_t u1;
- uint16_t u2;
- uint16_t u3;
- uint8_t u4[8];
- } _packed_;
- const struct uuid *uuid = guid;
-
- id128->bytes[0] = (uuid->u1 >> 24) & 0xff;
- id128->bytes[1] = (uuid->u1 >> 16) & 0xff;
- id128->bytes[2] = (uuid->u1 >> 8) & 0xff;
- id128->bytes[3] = (uuid->u1) & 0xff;
- id128->bytes[4] = (uuid->u2 >> 8) & 0xff;
- id128->bytes[5] = (uuid->u2) & 0xff;
- id128->bytes[6] = (uuid->u3 >> 8) & 0xff;
- id128->bytes[7] = (uuid->u3) & 0xff;
- memcpy(&id128->bytes[8], uuid->u4, sizeof(uuid->u4));
-}
-
-int efi_get_boot_option(
- uint16_t id,
- char **title,
- sd_id128_t *part_uuid,
- char **path,
- bool *active) {
-
- char boot_id[9];
- _cleanup_free_ uint8_t *buf = NULL;
- size_t l;
- struct boot_option *header;
- size_t title_size;
- _cleanup_free_ char *s = NULL, *p = NULL;
- sd_id128_t p_uuid = SD_ID128_NULL;
- int r;
-
- xsprintf(boot_id, "Boot%04X", id);
- r = efi_get_variable(EFI_VENDOR_GLOBAL, boot_id, NULL, (void **)&buf, &l);
- if (r < 0)
- return r;
- if (l < sizeof(struct boot_option))
- return -ENOENT;
-
- header = (struct boot_option *)buf;
- title_size = utf16_size(header->title);
- if (title_size > l - offsetof(struct boot_option, title))
- return -EINVAL;
-
- if (title) {
- s = utf16_to_utf8(header->title, title_size);
- if (!s)
- return -ENOMEM;
- }
-
- if (header->path_len > 0) {
- uint8_t *dbuf;
- size_t dnext;
-
- dbuf = buf + offsetof(struct boot_option, title) + title_size;
- dnext = 0;
- while (dnext < header->path_len) {
- struct device_path *dpath;
-
- dpath = (struct device_path *)(dbuf + dnext);
- if (dpath->length < 4)
- break;
-
- /* Type 0x7F – End of Hardware Device Path, Sub-Type 0xFF – End Entire Device Path */
- if (dpath->type == END_DEVICE_PATH_TYPE && dpath->sub_type == END_ENTIRE_DEVICE_PATH_SUBTYPE)
- break;
-
- dnext += dpath->length;
-
- /* Type 0x04 – Media Device Path */
- if (dpath->type != MEDIA_DEVICE_PATH)
- continue;
-
- /* Sub-Type 1 – Hard Drive */
- if (dpath->sub_type == MEDIA_HARDDRIVE_DP) {
- /* 0x02 – GUID Partition Table */
- if (dpath->drive.mbr_type != MBR_TYPE_EFI_PARTITION_TABLE_HEADER)
- continue;
-
- /* 0x02 – GUID signature */
- if (dpath->drive.signature_type != SIGNATURE_TYPE_GUID)
- continue;
-
- if (part_uuid)
- efi_guid_to_id128(dpath->drive.signature, &p_uuid);
- continue;
- }
-
- /* Sub-Type 4 – File Path */
- if (dpath->sub_type == MEDIA_FILEPATH_DP && !p && path) {
- p = utf16_to_utf8(dpath->path, dpath->length-4);
- efi_tilt_backslashes(p);
- continue;
- }
- }
- }
-
- if (title) {
- *title = s;
- s = NULL;
- }
- if (part_uuid)
- *part_uuid = p_uuid;
- if (path) {
- *path = p;
- p = NULL;
- }
- if (active)
- *active = !!(header->attr & LOAD_OPTION_ACTIVE);
-
- return 0;
-}
-
-static void to_utf16(uint16_t *dest, const char *src) {
- int i;
-
- for (i = 0; src[i] != '\0'; i++)
- dest[i] = src[i];
- dest[i] = '\0';
-}
-
-struct guid {
- uint32_t u1;
- uint16_t u2;
- uint16_t u3;
- uint8_t u4[8];
-} _packed_;
-
-static void id128_to_efi_guid(sd_id128_t id, void *guid) {
- struct guid *uuid = guid;
-
- uuid->u1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3];
- uuid->u2 = id.bytes[4] << 8 | id.bytes[5];
- uuid->u3 = id.bytes[6] << 8 | id.bytes[7];
- memcpy(uuid->u4, id.bytes+8, sizeof(uuid->u4));
-}
-
-static uint16_t *tilt_slashes(uint16_t *s) {
- uint16_t *p;
-
- for (p = s; *p; p++)
- if (*p == '/')
- *p = '\\';
-
- return s;
-}
-
-int efi_add_boot_option(uint16_t id, const char *title,
- uint32_t part, uint64_t pstart, uint64_t psize,
- sd_id128_t part_uuid, const char *path) {
- char boot_id[9];
- size_t size;
- size_t title_len;
- size_t path_len;
- struct boot_option *option;
- struct device_path *devicep;
- _cleanup_free_ char *buf = NULL;
-
- title_len = (strlen(title)+1) * 2;
- path_len = (strlen(path)+1) * 2;
-
- buf = calloc(sizeof(struct boot_option) + title_len +
- sizeof(struct drive_path) +
- sizeof(struct device_path) + path_len, 1);
- if (!buf)
- return -ENOMEM;
-
- /* header */
- option = (struct boot_option *)buf;
- option->attr = LOAD_OPTION_ACTIVE;
- option->path_len = offsetof(struct device_path, drive) + sizeof(struct drive_path) +
- offsetof(struct device_path, path) + path_len +
- offsetof(struct device_path, path);
- to_utf16(option->title, title);
- size = offsetof(struct boot_option, title) + title_len;
-
- /* partition info */
- devicep = (struct device_path *)(buf + size);
- devicep->type = MEDIA_DEVICE_PATH;
- devicep->sub_type = MEDIA_HARDDRIVE_DP;
- devicep->length = offsetof(struct device_path, drive) + sizeof(struct drive_path);
- devicep->drive.part_nr = part;
- devicep->drive.part_start = pstart;
- devicep->drive.part_size = psize;
- devicep->drive.signature_type = SIGNATURE_TYPE_GUID;
- devicep->drive.mbr_type = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
- id128_to_efi_guid(part_uuid, devicep->drive.signature);
- size += devicep->length;
-
- /* path to loader */
- devicep = (struct device_path *)(buf + size);
- devicep->type = MEDIA_DEVICE_PATH;
- devicep->sub_type = MEDIA_FILEPATH_DP;
- devicep->length = offsetof(struct device_path, path) + path_len;
- to_utf16(devicep->path, path);
- tilt_slashes(devicep->path);
- size += devicep->length;
-
- /* end of path */
- devicep = (struct device_path *)(buf + size);
- devicep->type = END_DEVICE_PATH_TYPE;
- devicep->sub_type = END_ENTIRE_DEVICE_PATH_SUBTYPE;
- devicep->length = offsetof(struct device_path, path);
- size += devicep->length;
-
- xsprintf(boot_id, "Boot%04X", id);
- return efi_set_variable(EFI_VENDOR_GLOBAL, boot_id, buf, size);
-}
-
-int efi_remove_boot_option(uint16_t id) {
- char boot_id[9];
-
- xsprintf(boot_id, "Boot%04X", id);
- return efi_set_variable(EFI_VENDOR_GLOBAL, boot_id, NULL, 0);
-}
-
-int efi_get_boot_order(uint16_t **order) {
- _cleanup_free_ void *buf = NULL;
- size_t l;
- int r;
-
- r = efi_get_variable(EFI_VENDOR_GLOBAL, "BootOrder", NULL, &buf, &l);
- if (r < 0)
- return r;
-
- if (l <= 0)
- return -ENOENT;
-
- if (l % sizeof(uint16_t) > 0 ||
- l / sizeof(uint16_t) > INT_MAX)
- return -EINVAL;
-
- *order = buf;
- buf = NULL;
- return (int) (l / sizeof(uint16_t));
-}
-
-int efi_set_boot_order(uint16_t *order, size_t n) {
- return efi_set_variable(EFI_VENDOR_GLOBAL, "BootOrder", order, n * sizeof(uint16_t));
-}
-
-static int boot_id_hex(const char s[4]) {
- int i;
- int id = 0;
-
- for (i = 0; i < 4; i++)
- if (s[i] >= '0' && s[i] <= '9')
- id |= (s[i] - '0') << (3 - i) * 4;
- else if (s[i] >= 'A' && s[i] <= 'F')
- id |= (s[i] - 'A' + 10) << (3 - i) * 4;
- else
- return -EINVAL;
-
- return id;
-}
-
-static int cmp_uint16(const void *_a, const void *_b) {
- const uint16_t *a = _a, *b = _b;
-
- return (int)*a - (int)*b;
-}
-
-int efi_get_boot_options(uint16_t **options) {
- _cleanup_closedir_ DIR *dir = NULL;
- struct dirent *de;
- _cleanup_free_ uint16_t *list = NULL;
- size_t alloc = 0;
- int count = 0;
-
- assert(options);
-
- dir = opendir("/sys/firmware/efi/efivars/");
- if (!dir)
- return -errno;
-
- FOREACH_DIRENT(de, dir, return -errno) {
- int id;
-
- if (strncmp(de->d_name, "Boot", 4) != 0)
- continue;
-
- if (strlen(de->d_name) != 45)
- continue;
-
- if (strcmp(de->d_name + 8, "-8be4df61-93ca-11d2-aa0d-00e098032b8c") != 0)
- continue;
-
- id = boot_id_hex(de->d_name + 4);
- if (id < 0)
- continue;
-
- if (!GREEDY_REALLOC(list, alloc, count + 1))
- return -ENOMEM;
-
- list[count++] = id;
- }
-
- qsort_safe(list, count, sizeof(uint16_t), cmp_uint16);
-
- *options = list;
- list = NULL;
- return count;
-}
-
-static int read_usec(sd_id128_t vendor, const char *name, usec_t *u) {
- _cleanup_free_ char *j = NULL;
- int r;
- uint64_t x = 0;
-
- assert(name);
- assert(u);
-
- r = efi_get_variable_string(EFI_VENDOR_LOADER, name, &j);
- if (r < 0)
- return r;
-
- r = safe_atou64(j, &x);
- if (r < 0)
- return r;
-
- *u = x;
- return 0;
-}
-
-int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader) {
- uint64_t x, y;
- int r;
-
- assert(firmware);
- assert(loader);
-
- r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeInitUSec", &x);
- if (r < 0)
- return r;
-
- r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeExecUSec", &y);
- if (r < 0)
- return r;
-
- if (y == 0 || y < x)
- return -EIO;
-
- if (y > USEC_PER_HOUR)
- return -EIO;
-
- *firmware = x;
- *loader = y;
-
- return 0;
-}
-
-int efi_loader_get_device_part_uuid(sd_id128_t *u) {
- _cleanup_free_ char *p = NULL;
- int r, parsed[16];
-
- r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderDevicePartUUID", &p);
- if (r < 0)
- return r;
-
- if (sscanf(p, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- &parsed[0], &parsed[1], &parsed[2], &parsed[3],
- &parsed[4], &parsed[5], &parsed[6], &parsed[7],
- &parsed[8], &parsed[9], &parsed[10], &parsed[11],
- &parsed[12], &parsed[13], &parsed[14], &parsed[15]) != 16)
- return -EIO;
-
- if (u) {
- unsigned i;
-
- for (i = 0; i < ELEMENTSOF(parsed); i++)
- u->bytes[i] = parsed[i];
- }
-
- return 0;
-}
-
-#endif
-
-char *efi_tilt_backslashes(char *s) {
- char *p;
-
- for (p = s; *p; p++)
- if (*p == '\\')
- *p = '/';
-
- return s;
-}
diff --git a/src/shared/efivars.h b/src/shared/efivars.h
deleted file mode 100644
index b61d14c4ec..0000000000
--- a/src/shared/efivars.h
+++ /dev/null
@@ -1,131 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "sd-id128.h"
-
-#include "time-util.h"
-
-#define EFI_VENDOR_LOADER SD_ID128_MAKE(4a,67,b0,82,0a,4c,41,cf,b6,c7,44,0b,29,bb,8c,4f)
-#define EFI_VENDOR_GLOBAL SD_ID128_MAKE(8b,e4,df,61,93,ca,11,d2,aa,0d,00,e0,98,03,2b,8c)
-#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001
-#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
-#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004
-
-#ifdef ENABLE_EFI
-
-bool is_efi_boot(void);
-bool is_efi_secure_boot(void);
-bool is_efi_secure_boot_setup_mode(void);
-int efi_reboot_to_firmware_supported(void);
-int efi_get_reboot_to_firmware(void);
-int efi_set_reboot_to_firmware(bool value);
-
-int efi_get_variable(sd_id128_t vendor, const char *name, uint32_t *attribute, void **value, size_t *size);
-int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size);
-int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p);
-
-int efi_get_boot_option(uint16_t nr, char **title, sd_id128_t *part_uuid, char **path, bool *active);
-int efi_add_boot_option(uint16_t id, const char *title, uint32_t part, uint64_t pstart, uint64_t psize, sd_id128_t part_uuid, const char *path);
-int efi_remove_boot_option(uint16_t id);
-int efi_get_boot_order(uint16_t **order);
-int efi_set_boot_order(uint16_t *order, size_t n);
-int efi_get_boot_options(uint16_t **options);
-
-int efi_loader_get_device_part_uuid(sd_id128_t *u);
-int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader);
-
-#else
-
-static inline bool is_efi_boot(void) {
- return false;
-}
-
-static inline bool is_efi_secure_boot(void) {
- return false;
-}
-
-static inline bool is_efi_secure_boot_setup_mode(void) {
- return false;
-}
-
-static inline int efi_reboot_to_firmware_supported(void) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_get_reboot_to_firmware(void) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_set_reboot_to_firmware(bool value) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_get_variable(sd_id128_t vendor, const char *name, uint32_t *attribute, void **value, size_t *size) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_get_boot_option(uint16_t nr, char **title, sd_id128_t *part_uuid, char **path, bool *active) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_add_boot_option(uint16_t id, const char *title, uint32_t part, uint64_t pstart, uint64_t psize, sd_id128_t part_uuid, const char *path) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_remove_boot_option(uint16_t id) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_get_boot_order(uint16_t **order) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_set_boot_order(uint16_t *order, size_t n) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_get_boot_options(uint16_t **options) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_loader_get_device_part_uuid(sd_id128_t *u) {
- return -EOPNOTSUPP;
-}
-
-static inline int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader) {
- return -EOPNOTSUPP;
-}
-
-#endif
-
-char *efi_tilt_backslashes(char *s);
diff --git a/src/shared/fdset.c b/src/shared/fdset.c
deleted file mode 100644
index 527f27bc67..0000000000
--- a/src/shared/fdset.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <alloca.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-
-#include "sd-daemon.h"
-
-#include "fd-util.h"
-#include "fdset.h"
-#include "log.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "set.h"
-
-#define MAKE_SET(s) ((Set*) s)
-#define MAKE_FDSET(s) ((FDSet*) s)
-
-FDSet *fdset_new(void) {
- return MAKE_FDSET(set_new(NULL));
-}
-
-int fdset_new_array(FDSet **ret, const int *fds, unsigned n_fds) {
- unsigned i;
- FDSet *s;
- int r;
-
- assert(ret);
-
- s = fdset_new();
- if (!s)
- return -ENOMEM;
-
- for (i = 0; i < n_fds; i++) {
-
- r = fdset_put(s, fds[i]);
- if (r < 0) {
- set_free(MAKE_SET(s));
- return r;
- }
- }
-
- *ret = s;
- return 0;
-}
-
-FDSet* fdset_free(FDSet *s) {
- void *p;
-
- while ((p = set_steal_first(MAKE_SET(s)))) {
- /* Valgrind's fd might have ended up in this set here,
- * due to fdset_new_fill(). We'll ignore all failures
- * here, so that the EBADFD that valgrind will return
- * us on close() doesn't influence us */
-
- /* When reloading duplicates of the private bus
- * connection fds and suchlike are closed here, which
- * has no effect at all, since they are only
- * duplicates. So don't be surprised about these log
- * messages. */
-
- log_debug("Closing left-over fd %i", PTR_TO_FD(p));
- close_nointr(PTR_TO_FD(p));
- }
-
- set_free(MAKE_SET(s));
- return NULL;
-}
-
-int fdset_put(FDSet *s, int fd) {
- assert(s);
- assert(fd >= 0);
-
- return set_put(MAKE_SET(s), FD_TO_PTR(fd));
-}
-
-int fdset_put_dup(FDSet *s, int fd) {
- int copy, r;
-
- assert(s);
- assert(fd >= 0);
-
- copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
- if (copy < 0)
- return -errno;
-
- r = fdset_put(s, copy);
- if (r < 0) {
- safe_close(copy);
- return r;
- }
-
- return copy;
-}
-
-bool fdset_contains(FDSet *s, int fd) {
- assert(s);
- assert(fd >= 0);
-
- return !!set_get(MAKE_SET(s), FD_TO_PTR(fd));
-}
-
-int fdset_remove(FDSet *s, int fd) {
- assert(s);
- assert(fd >= 0);
-
- return set_remove(MAKE_SET(s), FD_TO_PTR(fd)) ? fd : -ENOENT;
-}
-
-int fdset_new_fill(FDSet **_s) {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
- int r = 0;
- FDSet *s;
-
- assert(_s);
-
- /* Creates an fdset and fills in all currently open file
- * descriptors. */
-
- d = opendir("/proc/self/fd");
- if (!d)
- return -errno;
-
- s = fdset_new();
- if (!s) {
- r = -ENOMEM;
- goto finish;
- }
-
- while ((de = readdir(d))) {
- int fd = -1;
-
- if (hidden_or_backup_file(de->d_name))
- continue;
-
- r = safe_atoi(de->d_name, &fd);
- if (r < 0)
- goto finish;
-
- if (fd < 3)
- continue;
-
- if (fd == dirfd(d))
- continue;
-
- r = fdset_put(s, fd);
- if (r < 0)
- goto finish;
- }
-
- r = 0;
- *_s = s;
- s = NULL;
-
-finish:
- /* We won't close the fds here! */
- if (s)
- set_free(MAKE_SET(s));
-
- return r;
-}
-
-int fdset_cloexec(FDSet *fds, bool b) {
- Iterator i;
- void *p;
- int r;
-
- assert(fds);
-
- SET_FOREACH(p, MAKE_SET(fds), i) {
- r = fd_cloexec(PTR_TO_FD(p), b);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-int fdset_new_listen_fds(FDSet **_s, bool unset) {
- int n, fd, r;
- FDSet *s;
-
- assert(_s);
-
- /* Creates an fdset and fills in all passed file descriptors */
-
- s = fdset_new();
- if (!s) {
- r = -ENOMEM;
- goto fail;
- }
-
- n = sd_listen_fds(unset);
- for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
- r = fdset_put(s, fd);
- if (r < 0)
- goto fail;
- }
-
- *_s = s;
- return 0;
-
-
-fail:
- if (s)
- set_free(MAKE_SET(s));
-
- return r;
-}
-
-int fdset_close_others(FDSet *fds) {
- void *e;
- Iterator i;
- int *a;
- unsigned j, m;
-
- j = 0, m = fdset_size(fds);
- a = alloca(sizeof(int) * m);
- SET_FOREACH(e, MAKE_SET(fds), i)
- a[j++] = PTR_TO_FD(e);
-
- assert(j == m);
-
- return close_all_fds(a, j);
-}
-
-unsigned fdset_size(FDSet *fds) {
- return set_size(MAKE_SET(fds));
-}
-
-bool fdset_isempty(FDSet *fds) {
- return set_isempty(MAKE_SET(fds));
-}
-
-int fdset_iterate(FDSet *s, Iterator *i) {
- void *p;
-
- if (!set_iterate(MAKE_SET(s), i, &p))
- return -ENOENT;
-
- return PTR_TO_FD(p);
-}
-
-int fdset_steal_first(FDSet *fds) {
- void *p;
-
- p = set_steal_first(MAKE_SET(fds));
- if (!p)
- return -ENOENT;
-
- return PTR_TO_FD(p);
-}
diff --git a/src/shared/fdset.h b/src/shared/fdset.h
deleted file mode 100644
index 16efe5bdf2..0000000000
--- a/src/shared/fdset.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include "hashmap.h"
-#include "macro.h"
-#include "set.h"
-
-typedef struct FDSet FDSet;
-
-FDSet* fdset_new(void);
-FDSet* fdset_free(FDSet *s);
-
-int fdset_put(FDSet *s, int fd);
-int fdset_put_dup(FDSet *s, int fd);
-
-bool fdset_contains(FDSet *s, int fd);
-int fdset_remove(FDSet *s, int fd);
-
-int fdset_new_array(FDSet **ret, const int *fds, unsigned n_fds);
-int fdset_new_fill(FDSet **ret);
-int fdset_new_listen_fds(FDSet **ret, bool unset);
-
-int fdset_cloexec(FDSet *fds, bool b);
-
-int fdset_close_others(FDSet *fds);
-
-unsigned fdset_size(FDSet *fds);
-bool fdset_isempty(FDSet *fds);
-
-int fdset_iterate(FDSet *s, Iterator *i);
-
-int fdset_steal_first(FDSet *fds);
-
-#define FDSET_FOREACH(fd, fds, i) \
- for ((i) = ITERATOR_FIRST, (fd) = fdset_iterate((fds), &(i)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i)))
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(FDSet*, fdset_free);
-#define _cleanup_fdset_free_ _cleanup_(fdset_freep)
diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c
deleted file mode 100644
index f73108eaa3..0000000000
--- a/src/shared/firewall-util.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2015 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#warning "Temporary work-around for broken glibc vs. linux kernel header definitions"
-#warning "This really should be removed sooner rather than later, when this is fixed upstream"
-#define _NET_IF_H 1
-
-#include <alloca.h>
-#include <arpa/inet.h>
-#include <endian.h>
-#include <errno.h>
-#include <stddef.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#ifndef IFNAMSIZ
-#define IFNAMSIZ 16
-#endif
-#include <linux/if.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter/nf_nat.h>
-#include <linux/netfilter/xt_addrtype.h>
-#include <libiptc/libiptc.h>
-
-#include "alloc-util.h"
-#include "firewall-util.h"
-#include "in-addr-util.h"
-#include "macro.h"
-#include "socket-util.h"
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct xtc_handle*, iptc_free);
-
-static int entry_fill_basics(
- struct ipt_entry *entry,
- int protocol,
- const char *in_interface,
- const union in_addr_union *source,
- unsigned source_prefixlen,
- const char *out_interface,
- const union in_addr_union *destination,
- unsigned destination_prefixlen) {
-
- assert(entry);
-
- if (out_interface && !ifname_valid(out_interface))
- return -EINVAL;
- if (in_interface && !ifname_valid(in_interface))
- return -EINVAL;
-
- entry->ip.proto = protocol;
-
- if (in_interface) {
- strcpy(entry->ip.iniface, in_interface);
- memset(entry->ip.iniface_mask, 0xFF, strlen(in_interface)+1);
- }
- if (source) {
- entry->ip.src = source->in;
- in_addr_prefixlen_to_netmask(&entry->ip.smsk, source_prefixlen);
- }
-
- if (out_interface) {
- strcpy(entry->ip.outiface, out_interface);
- memset(entry->ip.outiface_mask, 0xFF, strlen(out_interface)+1);
- }
- if (destination) {
- entry->ip.dst = destination->in;
- in_addr_prefixlen_to_netmask(&entry->ip.dmsk, destination_prefixlen);
- }
-
- return 0;
-}
-
-int fw_add_masquerade(
- bool add,
- int af,
- int protocol,
- const union in_addr_union *source,
- unsigned source_prefixlen,
- const char *out_interface,
- const union in_addr_union *destination,
- unsigned destination_prefixlen) {
-
- _cleanup_(iptc_freep) struct xtc_handle *h = NULL;
- struct ipt_entry *entry, *mask;
- struct ipt_entry_target *t;
- size_t sz;
- struct nf_nat_ipv4_multi_range_compat *mr;
- int r;
-
- if (af != AF_INET)
- return -EOPNOTSUPP;
-
- if (protocol != 0 && protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
- return -EOPNOTSUPP;
-
- h = iptc_init("nat");
- if (!h)
- return -errno;
-
- sz = XT_ALIGN(sizeof(struct ipt_entry)) +
- XT_ALIGN(sizeof(struct ipt_entry_target)) +
- XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat));
-
- /* Put together the entry we want to add or remove */
- entry = alloca0(sz);
- entry->next_offset = sz;
- entry->target_offset = XT_ALIGN(sizeof(struct ipt_entry));
- r = entry_fill_basics(entry, protocol, NULL, source, source_prefixlen, out_interface, destination, destination_prefixlen);
- if (r < 0)
- return r;
-
- /* Fill in target part */
- t = ipt_get_target(entry);
- t->u.target_size =
- XT_ALIGN(sizeof(struct ipt_entry_target)) +
- XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat));
- strncpy(t->u.user.name, "MASQUERADE", sizeof(t->u.user.name));
- mr = (struct nf_nat_ipv4_multi_range_compat*) t->data;
- mr->rangesize = 1;
-
- /* Create a search mask entry */
- mask = alloca(sz);
- memset(mask, 0xFF, sz);
-
- if (add) {
- if (iptc_check_entry("POSTROUTING", entry, (unsigned char*) mask, h))
- return 0;
- if (errno != ENOENT) /* if other error than not existing yet, fail */
- return -errno;
-
- if (!iptc_insert_entry("POSTROUTING", entry, 0, h))
- return -errno;
- } else {
- if (!iptc_delete_entry("POSTROUTING", entry, (unsigned char*) mask, h)) {
- if (errno == ENOENT) /* if it's already gone, all is good! */
- return 0;
-
- return -errno;
- }
- }
-
- if (!iptc_commit(h))
- return -errno;
-
- return 0;
-}
-
-int fw_add_local_dnat(
- bool add,
- int af,
- int protocol,
- const char *in_interface,
- const union in_addr_union *source,
- unsigned source_prefixlen,
- const union in_addr_union *destination,
- unsigned destination_prefixlen,
- uint16_t local_port,
- const union in_addr_union *remote,
- uint16_t remote_port,
- const union in_addr_union *previous_remote) {
-
-
- _cleanup_(iptc_freep) struct xtc_handle *h = NULL;
- struct ipt_entry *entry, *mask;
- struct ipt_entry_target *t;
- struct ipt_entry_match *m;
- struct xt_addrtype_info_v1 *at;
- struct nf_nat_ipv4_multi_range_compat *mr;
- size_t sz, msz;
- int r;
-
- assert(add || !previous_remote);
-
- if (af != AF_INET)
- return -EOPNOTSUPP;
-
- if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
- return -EOPNOTSUPP;
-
- if (local_port <= 0)
- return -EINVAL;
-
- if (remote_port <= 0)
- return -EINVAL;
-
- h = iptc_init("nat");
- if (!h)
- return -errno;
-
- sz = XT_ALIGN(sizeof(struct ipt_entry)) +
- XT_ALIGN(sizeof(struct ipt_entry_match)) +
- XT_ALIGN(sizeof(struct xt_addrtype_info_v1)) +
- XT_ALIGN(sizeof(struct ipt_entry_target)) +
- XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat));
-
- if (protocol == IPPROTO_TCP)
- msz = XT_ALIGN(sizeof(struct ipt_entry_match)) +
- XT_ALIGN(sizeof(struct xt_tcp));
- else
- msz = XT_ALIGN(sizeof(struct ipt_entry_match)) +
- XT_ALIGN(sizeof(struct xt_udp));
-
- sz += msz;
-
- /* Fill in basic part */
- entry = alloca0(sz);
- entry->next_offset = sz;
- entry->target_offset =
- XT_ALIGN(sizeof(struct ipt_entry)) +
- XT_ALIGN(sizeof(struct ipt_entry_match)) +
- XT_ALIGN(sizeof(struct xt_addrtype_info_v1)) +
- msz;
- r = entry_fill_basics(entry, protocol, in_interface, source, source_prefixlen, NULL, destination, destination_prefixlen);
- if (r < 0)
- return r;
-
- /* Fill in first match */
- m = (struct ipt_entry_match*) ((uint8_t*) entry + XT_ALIGN(sizeof(struct ipt_entry)));
- m->u.match_size = msz;
- if (protocol == IPPROTO_TCP) {
- struct xt_tcp *tcp;
-
- strncpy(m->u.user.name, "tcp", sizeof(m->u.user.name));
- tcp = (struct xt_tcp*) m->data;
- tcp->dpts[0] = tcp->dpts[1] = local_port;
- tcp->spts[0] = 0;
- tcp->spts[1] = 0xFFFF;
-
- } else {
- struct xt_udp *udp;
-
- strncpy(m->u.user.name, "udp", sizeof(m->u.user.name));
- udp = (struct xt_udp*) m->data;
- udp->dpts[0] = udp->dpts[1] = local_port;
- udp->spts[0] = 0;
- udp->spts[1] = 0xFFFF;
- }
-
- /* Fill in second match */
- m = (struct ipt_entry_match*) ((uint8_t*) entry + XT_ALIGN(sizeof(struct ipt_entry)) + msz);
- m->u.match_size =
- XT_ALIGN(sizeof(struct ipt_entry_match)) +
- XT_ALIGN(sizeof(struct xt_addrtype_info_v1));
- strncpy(m->u.user.name, "addrtype", sizeof(m->u.user.name));
- m->u.user.revision = 1;
- at = (struct xt_addrtype_info_v1*) m->data;
- at->dest = XT_ADDRTYPE_LOCAL;
-
- /* Fill in target part */
- t = ipt_get_target(entry);
- t->u.target_size =
- XT_ALIGN(sizeof(struct ipt_entry_target)) +
- XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat));
- strncpy(t->u.user.name, "DNAT", sizeof(t->u.user.name));
- mr = (struct nf_nat_ipv4_multi_range_compat*) t->data;
- mr->rangesize = 1;
- mr->range[0].flags = NF_NAT_RANGE_PROTO_SPECIFIED|NF_NAT_RANGE_MAP_IPS;
- mr->range[0].min_ip = mr->range[0].max_ip = remote->in.s_addr;
- if (protocol == IPPROTO_TCP)
- mr->range[0].min.tcp.port = mr->range[0].max.tcp.port = htons(remote_port);
- else
- mr->range[0].min.udp.port = mr->range[0].max.udp.port = htons(remote_port);
-
- mask = alloca0(sz);
- memset(mask, 0xFF, sz);
-
- if (add) {
- /* Add the PREROUTING rule, if it is missing so far */
- if (!iptc_check_entry("PREROUTING", entry, (unsigned char*) mask, h)) {
- if (errno != ENOENT)
- return -EINVAL;
-
- if (!iptc_insert_entry("PREROUTING", entry, 0, h))
- return -errno;
- }
-
- /* If a previous remote is set, remove its entry */
- if (previous_remote && previous_remote->in.s_addr != remote->in.s_addr) {
- mr->range[0].min_ip = mr->range[0].max_ip = previous_remote->in.s_addr;
-
- if (!iptc_delete_entry("PREROUTING", entry, (unsigned char*) mask, h)) {
- if (errno != ENOENT)
- return -errno;
- }
-
- mr->range[0].min_ip = mr->range[0].max_ip = remote->in.s_addr;
- }
-
- /* Add the OUTPUT rule, if it is missing so far */
- if (!in_interface) {
-
- /* Don't apply onto loopback addresses */
- if (!destination) {
- entry->ip.dst.s_addr = htobe32(0x7F000000);
- entry->ip.dmsk.s_addr = htobe32(0xFF000000);
- entry->ip.invflags = IPT_INV_DSTIP;
- }
-
- if (!iptc_check_entry("OUTPUT", entry, (unsigned char*) mask, h)) {
- if (errno != ENOENT)
- return -errno;
-
- if (!iptc_insert_entry("OUTPUT", entry, 0, h))
- return -errno;
- }
-
- /* If a previous remote is set, remove its entry */
- if (previous_remote && previous_remote->in.s_addr != remote->in.s_addr) {
- mr->range[0].min_ip = mr->range[0].max_ip = previous_remote->in.s_addr;
-
- if (!iptc_delete_entry("OUTPUT", entry, (unsigned char*) mask, h)) {
- if (errno != ENOENT)
- return -errno;
- }
- }
- }
- } else {
- if (!iptc_delete_entry("PREROUTING", entry, (unsigned char*) mask, h)) {
- if (errno != ENOENT)
- return -errno;
- }
-
- if (!in_interface) {
- if (!destination) {
- entry->ip.dst.s_addr = htobe32(0x7F000000);
- entry->ip.dmsk.s_addr = htobe32(0xFF000000);
- entry->ip.invflags = IPT_INV_DSTIP;
- }
-
- if (!iptc_delete_entry("OUTPUT", entry, (unsigned char*) mask, h)) {
- if (errno != ENOENT)
- return -errno;
- }
- }
- }
-
- if (!iptc_commit(h))
- return -errno;
-
- return 0;
-}
diff --git a/src/shared/firewall-util.h b/src/shared/firewall-util.h
deleted file mode 100644
index c39b34cf8f..0000000000
--- a/src/shared/firewall-util.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2015 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "in-addr-util.h"
-
-#ifdef HAVE_LIBIPTC
-
-int fw_add_masquerade(
- bool add,
- int af,
- int protocol,
- const union in_addr_union *source,
- unsigned source_prefixlen,
- const char *out_interface,
- const union in_addr_union *destination,
- unsigned destination_prefixlen);
-
-int fw_add_local_dnat(
- bool add,
- int af,
- int protocol,
- const char *in_interface,
- const union in_addr_union *source,
- unsigned source_prefixlen,
- const union in_addr_union *destination,
- unsigned destination_prefixlen,
- uint16_t local_port,
- const union in_addr_union *remote,
- uint16_t remote_port,
- const union in_addr_union *previous_remote);
-
-#else
-
-static inline int fw_add_masquerade(
- bool add,
- int af,
- int protocol,
- const union in_addr_union *source,
- unsigned source_prefixlen,
- const char *out_interface,
- const union in_addr_union *destination,
- unsigned destination_prefixlen) {
- return -EOPNOTSUPP;
-}
-
-static inline int fw_add_local_dnat(
- bool add,
- int af,
- int protocol,
- const char *in_interface,
- const union in_addr_union *source,
- unsigned source_prefixlen,
- const union in_addr_union *destination,
- unsigned destination_prefixlen,
- uint16_t local_port,
- const union in_addr_union *remote,
- uint16_t remote_port,
- const union in_addr_union *previous_remote) {
- return -EOPNOTSUPP;
-}
-
-#endif
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
deleted file mode 100644
index a4e0cd3267..0000000000
--- a/src/shared/fstab-util.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2015 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <mntent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "device-nodes.h"
-#include "fstab-util.h"
-#include "macro.h"
-#include "mount-util.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "util.h"
-
-bool fstab_is_mount_point(const char *mount) {
- _cleanup_endmntent_ FILE *f = NULL;
- struct mntent *m;
-
- f = setmntent("/etc/fstab", "r");
- if (!f)
- return false;
-
- while ((m = getmntent(f)))
- if (path_equal(m->mnt_dir, mount))
- return true;
-
- return false;
-}
-
-int fstab_filter_options(const char *opts, const char *names,
- const char **namefound, char **value, char **filtered) {
- const char *name, *n = NULL, *x;
- _cleanup_strv_free_ char **stor = NULL;
- _cleanup_free_ char *v = NULL, **strv = NULL;
-
- assert(names && *names);
-
- if (!opts)
- goto answer;
-
- /* If !value and !filtered, this function is not allowed to fail. */
-
- if (!filtered) {
- const char *word, *state;
- size_t l;
-
- FOREACH_WORD_SEPARATOR(word, l, opts, ",", state)
- NULSTR_FOREACH(name, names) {
- if (l < strlen(name))
- continue;
- if (!strneq(word, name, strlen(name)))
- continue;
-
- /* we know that the string is NUL
- * terminated, so *x is valid */
- x = word + strlen(name);
- if (IN_SET(*x, '\0', '=', ',')) {
- n = name;
- if (value) {
- free(v);
- if (IN_SET(*x, '\0', ','))
- v = NULL;
- else {
- assert(*x == '=');
- x++;
- v = strndup(x, l - strlen(name) - 1);
- if (!v)
- return -ENOMEM;
- }
- }
- }
- }
- } else {
- char **t, **s;
-
- stor = strv_split(opts, ",");
- if (!stor)
- return -ENOMEM;
- strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
- if (!strv)
- return -ENOMEM;
-
- for (s = t = strv; *s; s++) {
- NULSTR_FOREACH(name, names) {
- x = startswith(*s, name);
- if (x && IN_SET(*x, '\0', '='))
- goto found;
- }
-
- *t = *s;
- t++;
- continue;
- found:
- /* Keep the last occurence found */
- n = name;
- if (value) {
- free(v);
- if (*x == '\0')
- v = NULL;
- else {
- assert(*x == '=');
- x++;
- v = strdup(x);
- if (!v)
- return -ENOMEM;
- }
- }
- }
- *t = NULL;
- }
-
-answer:
- if (namefound)
- *namefound = n;
- if (filtered) {
- char *f;
-
- f = strv_join(strv, ",");
- if (!f)
- return -ENOMEM;
-
- *filtered = f;
- }
- if (value) {
- *value = v;
- v = NULL;
- }
-
- return !!n;
-}
-
-int fstab_extract_values(const char *opts, const char *name, char ***values) {
- _cleanup_strv_free_ char **optsv = NULL, **res = NULL;
- char **s;
-
- assert(opts);
- assert(name);
- assert(values);
-
- optsv = strv_split(opts, ",");
- if (!optsv)
- return -ENOMEM;
-
- STRV_FOREACH(s, optsv) {
- char *arg;
- int r;
-
- arg = startswith(*s, name);
- if (!arg || *arg != '=')
- continue;
- r = strv_extend(&res, arg + 1);
- if (r < 0)
- return r;
- }
-
- *values = res;
- res = NULL;
-
- return !!*values;
-}
-
-int fstab_find_pri(const char *options, int *ret) {
- _cleanup_free_ char *opt = NULL;
- int r;
- unsigned pri;
-
- assert(ret);
-
- r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL);
- if (r < 0)
- return r;
- if (r == 0 || !opt)
- return 0;
-
- r = safe_atou(opt, &pri);
- if (r < 0)
- return r;
-
- if ((int) pri < 0)
- return -ERANGE;
-
- *ret = (int) pri;
- return 1;
-}
-
-static char *unquote(const char *s, const char* quotes) {
- size_t l;
- assert(s);
-
- /* This is rather stupid, simply removes the heading and
- * trailing quotes if there is one. Doesn't care about
- * escaping or anything.
- *
- * DON'T USE THIS FOR NEW CODE ANYMORE!*/
-
- l = strlen(s);
- if (l < 2)
- return strdup(s);
-
- if (strchr(quotes, s[0]) && s[l-1] == s[0])
- return strndup(s+1, l-2);
-
- return strdup(s);
-}
-
-static char *tag_to_udev_node(const char *tagvalue, const char *by) {
- _cleanup_free_ char *t = NULL, *u = NULL;
- size_t enc_len;
-
- u = unquote(tagvalue, QUOTES);
- if (!u)
- return NULL;
-
- enc_len = strlen(u) * 4 + 1;
- t = new(char, enc_len);
- if (!t)
- return NULL;
-
- if (encode_devnode_name(u, t, enc_len) < 0)
- return NULL;
-
- return strjoin("/dev/disk/by-", by, "/", t, NULL);
-}
-
-char *fstab_node_to_udev_node(const char *p) {
- assert(p);
-
- if (startswith(p, "LABEL="))
- return tag_to_udev_node(p+6, "label");
-
- if (startswith(p, "UUID="))
- return tag_to_udev_node(p+5, "uuid");
-
- if (startswith(p, "PARTUUID="))
- return tag_to_udev_node(p+9, "partuuid");
-
- if (startswith(p, "PARTLABEL="))
- return tag_to_udev_node(p+10, "partlabel");
-
- return strdup(p);
-}
diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h
deleted file mode 100644
index 679f6902f7..0000000000
--- a/src/shared/fstab-util.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2015 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stddef.h>
-
-#include "macro.h"
-
-bool fstab_is_mount_point(const char *mount);
-
-int fstab_filter_options(const char *opts, const char *names, const char **namefound, char **value, char **filtered);
-
-int fstab_extract_values(const char *opts, const char *name, char ***values);
-
-static inline bool fstab_test_option(const char *opts, const char *names) {
- return !!fstab_filter_options(opts, names, NULL, NULL, NULL);
-}
-
-int fstab_find_pri(const char *options, int *ret);
-
-static inline bool fstab_test_yes_no_option(const char *opts, const char *yes_no) {
- int r;
- const char *opt;
-
- /* If first name given is last, return 1.
- * If second name given is last or neither is found, return 0. */
-
- r = fstab_filter_options(opts, yes_no, &opt, NULL, NULL);
- assert(r >= 0);
-
- return opt == yes_no;
-}
-
-char *fstab_node_to_udev_node(const char *p);
diff --git a/src/shared/gcrypt-util.c b/src/shared/gcrypt-util.c
deleted file mode 100644
index 39b544b6f0..0000000000
--- a/src/shared/gcrypt-util.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#ifdef HAVE_GCRYPT
-#include <gcrypt.h>
-
-#include "gcrypt-util.h"
-#include "hexdecoct.h"
-
-void initialize_libgcrypt(bool secmem) {
- const char *p;
- if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
- return;
-
- p = gcry_check_version("1.4.5");
- assert(p);
-
- /* Turn off "secmem". Clients which wish to make use of this
- * feature should initialize the library manually */
- if (!secmem)
- gcry_control(GCRYCTL_DISABLE_SECMEM);
- gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
-}
-
-int string_hashsum(const char *s, size_t len, int md_algorithm, char **out) {
- gcry_md_hd_t md = NULL;
- size_t hash_size;
- void *hash;
- char *enc;
-
- initialize_libgcrypt(false);
-
- hash_size = gcry_md_get_algo_dlen(md_algorithm);
- assert(hash_size > 0);
-
- gcry_md_open(&md, md_algorithm, 0);
- if (!md)
- return -EIO;
-
- gcry_md_write(md, s, len);
-
- hash = gcry_md_read(md, 0);
- if (!hash)
- return -EIO;
-
- enc = hexmem(hash, hash_size);
- if (!enc)
- return -ENOMEM;
-
- *out = enc;
- return 0;
-}
-#endif
diff --git a/src/shared/gcrypt-util.h b/src/shared/gcrypt-util.h
deleted file mode 100644
index 1da12a32be..0000000000
--- a/src/shared/gcrypt-util.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2016 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-#ifdef HAVE_GCRYPT
-#include <gcrypt.h>
-
-void initialize_libgcrypt(bool secmem);
-int string_hashsum(const char *s, size_t len, int md_algorithm, char **out);
-#endif
-
-static inline int string_hashsum_sha224(const char *s, size_t len, char **out) {
-#ifdef HAVE_GCRYPT
- return string_hashsum(s, len, GCRY_MD_SHA224, out);
-#else
- return -EOPNOTSUPP;
-#endif
-}
-
-static inline int string_hashsum_sha256(const char *s, size_t len, char **out) {
-#ifdef HAVE_GCRYPT
- return string_hashsum(s, len, GCRY_MD_SHA256, out);
-#else
- return -EOPNOTSUPP;
-#endif
-}
diff --git a/src/shared/generator.c b/src/shared/generator.c
deleted file mode 100644
index 70afc6a285..0000000000
--- a/src/shared/generator.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "dropin.h"
-#include "escape.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fstab-util.h"
-#include "generator.h"
-#include "log.h"
-#include "macro.h"
-#include "mkdir.h"
-#include "path-util.h"
-#include "special.h"
-#include "string-util.h"
-#include "time-util.h"
-#include "unit-name.h"
-#include "util.h"
-
-static int write_fsck_sysroot_service(const char *dir, const char *what) {
- _cleanup_free_ char *device = NULL, *escaped = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- const char *unit;
- int r;
-
- escaped = cescape(what);
- if (!escaped)
- return log_oom();
-
- unit = strjoina(dir, "/systemd-fsck-root.service");
- log_debug("Creating %s", unit);
-
- r = unit_name_from_path(what, ".device", &device);
- if (r < 0)
- return log_error_errno(r, "Failed to convert device \"%s\" to unit name: %m", what);
-
- f = fopen(unit, "wxe");
- if (!f)
- return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
-
- fprintf(f,
- "# Automatically generated by %1$s\n\n"
- "[Unit]\n"
- "Documentation=man:systemd-fsck-root.service(8)\n"
- "Description=File System Check on %2$s\n"
- "DefaultDependencies=no\n"
- "BindsTo=%3$s\n"
- "After=initrd-root-device.target local-fs-pre.target\n"
- "Before=shutdown.target\n"
- "\n"
- "[Service]\n"
- "Type=oneshot\n"
- "RemainAfterExit=yes\n"
- "ExecStart=" SYSTEMD_FSCK_PATH " %4$s\n"
- "TimeoutSec=0\n",
- program_invocation_short_name,
- what,
- device,
- escaped);
-
- r = fflush_and_check(f);
- if (r < 0)
- return log_error_errno(r, "Failed to write unit file %s: %m", unit);
-
- return 0;
-}
-
-int generator_write_fsck_deps(
- FILE *f,
- const char *dir,
- const char *what,
- const char *where,
- const char *fstype) {
-
- int r;
-
- assert(f);
- assert(dir);
- assert(what);
- assert(where);
-
- if (!is_device_path(what)) {
- log_warning("Checking was requested for \"%s\", but it is not a device.", what);
- return 0;
- }
-
- if (!isempty(fstype) && !streq(fstype, "auto")) {
- r = fsck_exists(fstype);
- if (r < 0)
- log_warning_errno(r, "Checking was requested for %s, but couldn't detect if fsck.%s may be used, proceeding: %m", what, fstype);
- else if (r == 0) {
- /* treat missing check as essentially OK */
- log_debug("Checking was requested for %s, but fsck.%s does not exist.", what, fstype);
- return 0;
- }
- }
-
- if (path_equal(where, "/")) {
- const char *lnk;
-
- lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");
-
- mkdir_parents(lnk, 0755);
- if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-fsck-root.service", lnk) < 0)
- return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
-
- } else {
- _cleanup_free_ char *_fsck = NULL;
- const char *fsck;
-
- if (in_initrd() && path_equal(where, "/sysroot")) {
- r = write_fsck_sysroot_service(dir, what);
- if (r < 0)
- return r;
-
- fsck = "systemd-fsck-root.service";
- } else {
- r = unit_name_from_path_instance("systemd-fsck", what, ".service", &_fsck);
- if (r < 0)
- return log_error_errno(r, "Failed to create fsck service name: %m");
-
- fsck = _fsck;
- }
-
- fprintf(f,
- "Requires=%1$s\n"
- "After=%1$s\n",
- fsck);
- }
-
- return 0;
-}
-
-int generator_write_timeouts(
- const char *dir,
- const char *what,
- const char *where,
- const char *opts,
- char **filtered) {
-
- /* Allow configuration how long we wait for a device that
- * backs a mount point to show up. This is useful to support
- * endless device timeouts for devices that show up only after
- * user input, like crypto devices. */
-
- _cleanup_free_ char *node = NULL, *unit = NULL, *timeout = NULL;
- usec_t u;
- int r;
-
- r = fstab_filter_options(opts, "comment=systemd.device-timeout\0" "x-systemd.device-timeout\0",
- NULL, &timeout, filtered);
- if (r <= 0)
- return r;
-
- r = parse_sec(timeout, &u);
- if (r < 0) {
- log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
- return 0;
- }
-
- node = fstab_node_to_udev_node(what);
- if (!node)
- return log_oom();
-
- r = unit_name_from_path(node, ".device", &unit);
- if (r < 0)
- return log_error_errno(r, "Failed to make unit name from path: %m");
-
- return write_drop_in_format(dir, unit, 50, "device-timeout",
- "# Automatically generated by %s\n\n"
- "[Unit]\nJobTimeoutSec=%s",
- program_invocation_short_name, timeout);
-}
-
-int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
- _cleanup_free_ char *unit = NULL;
- int r;
-
- r = unit_name_from_path(what, ".device", &unit);
- if (r < 0)
- return log_error_errno(r, "Failed to make unit name from path: %m");
-
- return write_drop_in_format(dir, SPECIAL_INITRD_ROOT_DEVICE_TARGET, 50, "root-device",
- "# Automatically generated by %s\n\n"
- "[Unit]\nRequires=%s\nAfter=%s",
- program_invocation_short_name, unit, unit);
-}
diff --git a/src/shared/generator.h b/src/shared/generator.h
deleted file mode 100644
index a6017c1b76..0000000000
--- a/src/shared/generator.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdio.h>
-
-int generator_write_fsck_deps(
- FILE *f,
- const char *dir,
- const char *what,
- const char *where,
- const char *type);
-
-int generator_write_timeouts(
- const char *dir,
- const char *what,
- const char *where,
- const char *opts,
- char **filtered);
-
-int generator_write_initrd_root_device_deps(
- const char *dir,
- const char *what);
diff --git a/src/shared/gpt.h b/src/shared/gpt.h
deleted file mode 100644
index 55b41bbcd8..0000000000
--- a/src/shared/gpt.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <endian.h>
-
-#include "sd-id128.h"
-
-/* We only support root disk discovery for x86, x86-64, Itanium and ARM for
- * now, since EFI for anything else doesn't really exist, and we only
- * care for root partitions on the same disk as the EFI ESP. */
-
-#define GPT_ROOT_X86 SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a)
-#define GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
-#define GPT_ROOT_ARM SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3)
-#define GPT_ROOT_ARM_64 SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae)
-#define GPT_ROOT_IA64 SD_ID128_MAKE(99,3d,8d,3d,f8,0e,42,25,85,5a,9d,af,8e,d7,ea,97)
-
-#define GPT_ESP SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b)
-#define GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)
-#define GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15)
-#define GPT_SRV SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8)
-
-#if defined(__x86_64__)
-# define GPT_ROOT_NATIVE GPT_ROOT_X86_64
-# define GPT_ROOT_SECONDARY GPT_ROOT_X86
-#elif defined(__i386__)
-# define GPT_ROOT_NATIVE GPT_ROOT_X86
-#endif
-
-#if defined(__ia64__)
-# define GPT_ROOT_NATIVE GPT_ROOT_IA64
-#endif
-
-#if defined(__aarch64__) && (__BYTE_ORDER != __BIG_ENDIAN)
-# define GPT_ROOT_NATIVE GPT_ROOT_ARM_64
-# define GPT_ROOT_SECONDARY GPT_ROOT_ARM
-#elif defined(__arm__) && (__BYTE_ORDER != __BIG_ENDIAN)
-# define GPT_ROOT_NATIVE GPT_ROOT_ARM
-#endif
-
-/* Flags we recognize on the root, swap, home and srv partitions when
- * doing auto-discovery. These happen to be identical to what
- * Microsoft defines for its own Basic Data Partitions, but that's
- * just because we saw no point in defining any other values here. */
-#define GPT_FLAG_READ_ONLY (1ULL << 60)
-#define GPT_FLAG_NO_AUTO (1ULL << 63)
-
-#define GPT_LINUX_GENERIC SD_ID128_MAKE(0f,c6,3d,af,84,83,47,72,8e,79,3d,69,d8,47,7d,e4)
diff --git a/src/shared/ima-util.c b/src/shared/ima-util.c
deleted file mode 100644
index 789064d653..0000000000
--- a/src/shared/ima-util.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <unistd.h>
-
-#include "ima-util.h"
-
-static int use_ima_cached = -1;
-
-bool use_ima(void) {
-
- if (use_ima_cached < 0)
- use_ima_cached = access("/sys/kernel/security/ima/", F_OK) >= 0;
-
- return use_ima_cached;
-}
diff --git a/src/shared/ima-util.h b/src/shared/ima-util.h
deleted file mode 100644
index 5be94761fd..0000000000
--- a/src/shared/ima-util.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-bool use_ima(void);
diff --git a/src/shared/import-util.c b/src/shared/import-util.c
deleted file mode 100644
index ab701ad8b2..0000000000
--- a/src/shared/import-util.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2015 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "btrfs-util.h"
-#include "import-util.h"
-#include "log.h"
-#include "macro.h"
-#include "path-util.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "util.h"
-
-int import_url_last_component(const char *url, char **ret) {
- const char *e, *p;
- char *s;
-
- e = strchrnul(url, '?');
-
- while (e > url && e[-1] == '/')
- e--;
-
- p = e;
- while (p > url && p[-1] != '/')
- p--;
-
- if (e <= p)
- return -EINVAL;
-
- s = strndup(p, e - p);
- if (!s)
- return -ENOMEM;
-
- *ret = s;
- return 0;
-}
-
-
-int import_url_change_last_component(const char *url, const char *suffix, char **ret) {
- const char *e;
- char *s;
-
- assert(url);
- assert(ret);
-
- e = strchrnul(url, '?');
-
- while (e > url && e[-1] == '/')
- e--;
-
- while (e > url && e[-1] != '/')
- e--;
-
- if (e <= url)
- return -EINVAL;
-
- s = new(char, (e - url) + strlen(suffix) + 1);
- if (!s)
- return -ENOMEM;
-
- strcpy(mempcpy(s, url, e - url), suffix);
- *ret = s;
- return 0;
-}
-
-static const char* const import_verify_table[_IMPORT_VERIFY_MAX] = {
- [IMPORT_VERIFY_NO] = "no",
- [IMPORT_VERIFY_CHECKSUM] = "checksum",
- [IMPORT_VERIFY_SIGNATURE] = "signature",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(import_verify, ImportVerify);
-
-int tar_strip_suffixes(const char *name, char **ret) {
- const char *e;
- char *s;
-
- e = endswith(name, ".tar");
- if (!e)
- e = endswith(name, ".tar.xz");
- if (!e)
- e = endswith(name, ".tar.gz");
- if (!e)
- e = endswith(name, ".tar.bz2");
- if (!e)
- e = endswith(name, ".tgz");
- if (!e)
- e = strchr(name, 0);
-
- if (e <= name)
- return -EINVAL;
-
- s = strndup(name, e - name);
- if (!s)
- return -ENOMEM;
-
- *ret = s;
- return 0;
-}
-
-int raw_strip_suffixes(const char *p, char **ret) {
-
- static const char suffixes[] =
- ".xz\0"
- ".gz\0"
- ".bz2\0"
- ".raw\0"
- ".qcow2\0"
- ".img\0"
- ".bin\0";
-
- _cleanup_free_ char *q = NULL;
-
- q = strdup(p);
- if (!q)
- return -ENOMEM;
-
- for (;;) {
- const char *sfx;
- bool changed = false;
-
- NULSTR_FOREACH(sfx, suffixes) {
- char *e;
-
- e = endswith(q, sfx);
- if (e) {
- *e = 0;
- changed = true;
- }
- }
-
- if (!changed)
- break;
- }
-
- *ret = q;
- q = NULL;
-
- return 0;
-}
-
-int import_assign_pool_quota_and_warn(const char *path) {
- int r;
-
- r = btrfs_subvol_auto_qgroup("/var/lib/machines", 0, true);
- if (r == -ENOTTY) {
- log_debug_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines, as directory is not on btrfs or not a subvolume. Ignoring.");
- return 0;
- }
- if (r < 0)
- return log_error_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines: %m");
- if (r > 0)
- log_info("Set up default quota hierarchy for /var/lib/machines.");
-
- r = btrfs_subvol_auto_qgroup(path, 0, true);
- if (r == -ENOTTY) {
- log_debug_errno(r, "Failed to set up quota hierarchy for %s, as directory is not on btrfs or not a subvolume. Ignoring.", path);
- return 0;
- }
- if (r < 0)
- return log_error_errno(r, "Failed to set up default quota hierarchy for %s: %m", path);
- if (r > 0)
- log_info("Set up default quota hierarchy for %s.", path);
-
- return 0;
-}
diff --git a/src/shared/import-util.h b/src/shared/import-util.h
deleted file mode 100644
index 77b17d91f3..0000000000
--- a/src/shared/import-util.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2015 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include "macro.h"
-
-typedef enum ImportVerify {
- IMPORT_VERIFY_NO,
- IMPORT_VERIFY_CHECKSUM,
- IMPORT_VERIFY_SIGNATURE,
- _IMPORT_VERIFY_MAX,
- _IMPORT_VERIFY_INVALID = -1,
-} ImportVerify;
-
-int import_url_last_component(const char *url, char **ret);
-int import_url_change_last_component(const char *url, const char *suffix, char **ret);
-
-const char* import_verify_to_string(ImportVerify v) _const_;
-ImportVerify import_verify_from_string(const char *s) _pure_;
-
-int tar_strip_suffixes(const char *name, char **ret);
-int raw_strip_suffixes(const char *name, char **ret);
-
-int import_assign_pool_quota_and_warn(const char *path);
diff --git a/src/shared/initreq.h b/src/shared/initreq.h
deleted file mode 100644
index 710037d84b..0000000000
--- a/src/shared/initreq.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * initreq.h Interface to talk to init through /dev/initctl.
- *
- * Copyright (C) 1995-2004 Miquel van Smoorenburg
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * Version: @(#)initreq.h 1.28 31-Mar-2004 MvS
- *
- */
-#ifndef _INITREQ_H
-#define _INITREQ_H
-
-#include <sys/param.h>
-
-#if defined(__FreeBSD_kernel__)
-# define INIT_FIFO "/etc/.initctl"
-#else
-# define INIT_FIFO "/dev/initctl"
-#endif
-
-#define INIT_MAGIC 0x03091969
-#define INIT_CMD_START 0
-#define INIT_CMD_RUNLVL 1
-#define INIT_CMD_POWERFAIL 2
-#define INIT_CMD_POWERFAILNOW 3
-#define INIT_CMD_POWEROK 4
-#define INIT_CMD_BSD 5
-#define INIT_CMD_SETENV 6
-#define INIT_CMD_UNSETENV 7
-
-#define INIT_CMD_CHANGECONS 12345
-
-#ifdef MAXHOSTNAMELEN
-# define INITRQ_HLEN MAXHOSTNAMELEN
-#else
-# define INITRQ_HLEN 64
-#endif
-
-/*
- * This is what BSD 4.4 uses when talking to init.
- * Linux doesn't use this right now.
- */
-struct init_request_bsd {
- char gen_id[8]; /* Beats me.. telnetd uses "fe" */
- char tty_id[16]; /* Tty name minus /dev/tty */
- char host[INITRQ_HLEN]; /* Hostname */
- char term_type[16]; /* Terminal type */
- int signal; /* Signal to send */
- int pid; /* Process to send to */
- char exec_name[128]; /* Program to execute */
- char reserved[128]; /* For future expansion. */
-};
-
-
-/*
- * Because of legacy interfaces, "runlevel" and "sleeptime"
- * aren't in a separate struct in the union.
- *
- * The weird sizes are because init expects the whole
- * struct to be 384 bytes.
- */
-struct init_request {
- int magic; /* Magic number */
- int cmd; /* What kind of request */
- int runlevel; /* Runlevel to change to */
- int sleeptime; /* Time between TERM and KILL */
- union {
- struct init_request_bsd bsd;
- char data[368];
- } i;
-};
-
-#endif
diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c
deleted file mode 100644
index cbdf66827f..0000000000
--- a/src/shared/install-printf.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "formats-util.h"
-#include "install-printf.h"
-#include "install.h"
-#include "macro.h"
-#include "specifier.h"
-#include "string-util.h"
-#include "unit-name.h"
-#include "user-util.h"
-
-static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
- const UnitFileInstallInfo *i = userdata;
- _cleanup_free_ char *prefix = NULL;
- int r;
-
- assert(i);
-
- r = unit_name_to_prefix_and_instance(i->name, &prefix);
- if (r < 0)
- return r;
-
- if (endswith(prefix, "@") && i->default_instance) {
- char *ans;
-
- ans = strjoin(prefix, i->default_instance, NULL);
- if (!ans)
- return -ENOMEM;
- *ret = ans;
- } else {
- *ret = prefix;
- prefix = NULL;
- }
-
- return 0;
-}
-
-static int specifier_name(char specifier, void *data, void *userdata, char **ret) {
- const UnitFileInstallInfo *i = userdata;
- char *ans;
-
- assert(i);
-
- if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && i->default_instance)
- return unit_name_replace_instance(i->name, i->default_instance, ret);
-
- ans = strdup(i->name);
- if (!ans)
- return -ENOMEM;
- *ret = ans;
- return 0;
-}
-
-static int specifier_prefix(char specifier, void *data, void *userdata, char **ret) {
- const UnitFileInstallInfo *i = userdata;
-
- assert(i);
-
- return unit_name_to_prefix(i->name, ret);
-}
-
-static int specifier_instance(char specifier, void *data, void *userdata, char **ret) {
- const UnitFileInstallInfo *i = userdata;
- char *instance;
- int r;
-
- assert(i);
-
- r = unit_name_to_instance(i->name, &instance);
- if (r < 0)
- return r;
-
- if (isempty(instance)) {
- instance = strdup(i->default_instance ?: "");
- if (!instance)
- return -ENOMEM;
- }
-
- *ret = instance;
- return 0;
-}
-
-static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
- char *t;
-
- /* If we are UID 0 (root), this will not result in NSS,
- * otherwise it might. This is good, as we want to be able to
- * run this in PID 1, where our user ID is 0, but where NSS
- * lookups are not allowed.
-
- * We don't user getusername_malloc() here, because we don't want to look
- * at $USER, to remain consistent with specifer_user_id() below.
- */
-
- t = uid_to_name(getuid());
- if (!t)
- return -ENOMEM;
-
- *ret = t;
- return 0;
-}
-
-static int specifier_user_id(char specifier, void *data, void *userdata, char **ret) {
-
- if (asprintf(ret, UID_FMT, getuid()) < 0)
- return -ENOMEM;
-
- return 0;
-}
-
-int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret) {
-
- /* This is similar to unit_full_printf() but does not support
- * anything path-related.
- *
- * %n: the full id of the unit (foo@bar.waldo)
- * %N: the id of the unit without the suffix (foo@bar)
- * %p: the prefix (foo)
- * %i: the instance (bar)
-
- * %U the UID of the running user
- * %u the username of running user
- * %m the machine ID of the running system
- * %H the host name of the running system
- * %b the boot ID of the running system
- * %v `uname -r` of the running system
- */
-
- const Specifier table[] = {
- { 'n', specifier_name, NULL },
- { 'N', specifier_prefix_and_instance, NULL },
- { 'p', specifier_prefix, NULL },
- { 'i', specifier_instance, NULL },
-
- { 'U', specifier_user_id, NULL },
- { 'u', specifier_user_name, NULL },
-
- { 'm', specifier_machine_id, NULL },
- { 'H', specifier_host_name, NULL },
- { 'b', specifier_boot_id, NULL },
- { 'v', specifier_kernel_release, NULL },
- {}
- };
-
- assert(i);
- assert(format);
- assert(ret);
-
- return specifier_printf(format, table, i, ret);
-}
diff --git a/src/shared/install-printf.h b/src/shared/install-printf.h
deleted file mode 100644
index 8a570fc265..0000000000
--- a/src/shared/install-printf.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "install.h"
-
-int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret);
diff --git a/src/shared/install.c b/src/shared/install.c
deleted file mode 100644
index 96fba6e25b..0000000000
--- a/src/shared/install.c
+++ /dev/null
@@ -1,3041 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty <of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fnmatch.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "conf-files.h"
-#include "conf-parser.h"
-#include "dirent-util.h"
-#include "extract-word.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "hashmap.h"
-#include "install-printf.h"
-#include "install.h"
-#include "locale-util.h"
-#include "log.h"
-#include "macro.h"
-#include "mkdir.h"
-#include "path-lookup.h"
-#include "path-util.h"
-#include "rm-rf.h"
-#include "set.h"
-#include "special.h"
-#include "stat-util.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "strv.h"
-#include "unit-name.h"
-
-#define UNIT_FILE_FOLLOW_SYMLINK_MAX 64
-
-typedef enum SearchFlags {
- SEARCH_LOAD = 1,
- SEARCH_FOLLOW_CONFIG_SYMLINKS = 2,
-} SearchFlags;
-
-typedef struct {
- OrderedHashmap *will_process;
- OrderedHashmap *have_processed;
-} InstallContext;
-
-typedef enum {
- PRESET_UNKNOWN,
- PRESET_ENABLE,
- PRESET_DISABLE,
-} PresetAction;
-
-typedef struct {
- char *pattern;
- PresetAction action;
-} PresetRule;
-
-typedef struct {
- PresetRule *rules;
- size_t n_rules;
-} Presets;
-
-static inline void presets_freep(Presets *p) {
- size_t i;
-
- if (!p)
- return;
-
- for (i = 0; i < p->n_rules; i++)
- free(p->rules[i].pattern);
-
- free(p->rules);
- p->n_rules = 0;
-}
-
-static int unit_file_lookup_state(UnitFileScope scope, const LookupPaths *paths, const char *name, UnitFileState *ret);
-
-bool unit_type_may_alias(UnitType type) {
- return IN_SET(type,
- UNIT_SERVICE,
- UNIT_SOCKET,
- UNIT_TARGET,
- UNIT_DEVICE,
- UNIT_TIMER,
- UNIT_PATH);
-}
-
-bool unit_type_may_template(UnitType type) {
- return IN_SET(type,
- UNIT_SERVICE,
- UNIT_SOCKET,
- UNIT_TARGET,
- UNIT_TIMER,
- UNIT_PATH);
-}
-
-static const char *unit_file_type_table[_UNIT_FILE_TYPE_MAX] = {
- [UNIT_FILE_TYPE_REGULAR] = "regular",
- [UNIT_FILE_TYPE_SYMLINK] = "symlink",
- [UNIT_FILE_TYPE_MASKED] = "masked",
-};
-
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(unit_file_type, UnitFileType);
-
-static int in_search_path(const LookupPaths *p, const char *path) {
- _cleanup_free_ char *parent = NULL;
- char **i;
-
- assert(path);
-
- parent = dirname_malloc(path);
- if (!parent)
- return -ENOMEM;
-
- STRV_FOREACH(i, p->search_path)
- if (path_equal(parent, *i))
- return true;
-
- return false;
-}
-
-static const char* skip_root(const LookupPaths *p, const char *path) {
- char *e;
-
- assert(p);
- assert(path);
-
- if (!p->root_dir)
- return path;
-
- e = path_startswith(path, p->root_dir);
- if (!e)
- return NULL;
-
- /* Make sure the returned path starts with a slash */
- if (e[0] != '/') {
- if (e == path || e[-1] != '/')
- return NULL;
-
- e--;
- }
-
- return e;
-}
-
-static int path_is_generator(const LookupPaths *p, const char *path) {
- _cleanup_free_ char *parent = NULL;
-
- assert(p);
- assert(path);
-
- parent = dirname_malloc(path);
- if (!parent)
- return -ENOMEM;
-
- return path_equal_ptr(parent, p->generator) ||
- path_equal_ptr(parent, p->generator_early) ||
- path_equal_ptr(parent, p->generator_late);
-}
-
-static int path_is_transient(const LookupPaths *p, const char *path) {
- _cleanup_free_ char *parent = NULL;
-
- assert(p);
- assert(path);
-
- parent = dirname_malloc(path);
- if (!parent)
- return -ENOMEM;
-
- return path_equal_ptr(parent, p->transient);
-}
-
-static int path_is_control(const LookupPaths *p, const char *path) {
- _cleanup_free_ char *parent = NULL;
-
- assert(p);
- assert(path);
-
- parent = dirname_malloc(path);
- if (!parent)
- return -ENOMEM;
-
- return path_equal_ptr(parent, p->persistent_control) ||
- path_equal_ptr(parent, p->runtime_control);
-}
-
-static int path_is_config(const LookupPaths *p, const char *path) {
- _cleanup_free_ char *parent = NULL;
-
- assert(p);
- assert(path);
-
- /* Note that we do *not* have generic checks for /etc or /run in place, since with
- * them we couldn't discern configuration from transient or generated units */
-
- parent = dirname_malloc(path);
- if (!parent)
- return -ENOMEM;
-
- return path_equal_ptr(parent, p->persistent_config) ||
- path_equal_ptr(parent, p->runtime_config);
-}
-
-static int path_is_runtime(const LookupPaths *p, const char *path) {
- _cleanup_free_ char *parent = NULL;
- const char *rpath;
-
- assert(p);
- assert(path);
-
- /* Everything in /run is considered runtime. On top of that we also add
- * explicit checks for the various runtime directories, as safety net. */
-
- rpath = skip_root(p, path);
- if (rpath && path_startswith(rpath, "/run"))
- return true;
-
- parent = dirname_malloc(path);
- if (!parent)
- return -ENOMEM;
-
- return path_equal_ptr(parent, p->runtime_config) ||
- path_equal_ptr(parent, p->generator) ||
- path_equal_ptr(parent, p->generator_early) ||
- path_equal_ptr(parent, p->generator_late) ||
- path_equal_ptr(parent, p->transient) ||
- path_equal_ptr(parent, p->runtime_control);
-}
-
-static int path_is_vendor(const LookupPaths *p, const char *path) {
- const char *rpath;
-
- assert(p);
- assert(path);
-
- rpath = skip_root(p, path);
- if (!rpath)
- return 0;
-
- if (path_startswith(rpath, "/usr"))
- return true;
-
-#ifdef HAVE_SPLIT_USR
- if (path_startswith(rpath, "/lib"))
- return true;
-#endif
-
- return path_equal(rpath, SYSTEM_DATA_UNIT_PATH);
-}
-
-int unit_file_changes_add(
- UnitFileChange **changes,
- unsigned *n_changes,
- UnitFileChangeType type,
- const char *path,
- const char *source) {
-
- _cleanup_free_ char *p = NULL, *s = NULL;
- UnitFileChange *c;
-
- assert(path);
- assert(!changes == !n_changes);
-
- if (!changes)
- return 0;
-
- c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
- if (!c)
- return -ENOMEM;
- *changes = c;
-
- p = strdup(path);
- if (source)
- s = strdup(source);
-
- if (!p || (source && !s))
- return -ENOMEM;
-
- path_kill_slashes(p);
- if (s)
- path_kill_slashes(s);
-
- c[*n_changes] = (UnitFileChange) { type, p, s };
- p = s = NULL;
- (*n_changes) ++;
- return 0;
-}
-
-void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
- unsigned i;
-
- assert(changes || n_changes == 0);
-
- for (i = 0; i < n_changes; i++) {
- free(changes[i].path);
- free(changes[i].source);
- }
-
- free(changes);
-}
-
-void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *changes, unsigned n_changes, bool quiet) {
- unsigned i;
- bool logged = false;
-
- assert(changes || n_changes == 0);
- /* If verb is not specified, errors are not allowed! */
- assert(verb || r >= 0);
-
- for (i = 0; i < n_changes; i++) {
- assert(verb || changes[i].type >= 0);
-
- switch(changes[i].type) {
- case UNIT_FILE_SYMLINK:
- if (!quiet)
- log_info("Created symlink %s %s %s.",
- changes[i].path,
- special_glyph(ARROW),
- changes[i].source);
- break;
- case UNIT_FILE_UNLINK:
- if (!quiet)
- log_info("Removed %s.", changes[i].path);
- break;
- case UNIT_FILE_IS_MASKED:
- if (!quiet)
- log_info("Unit %s is masked, ignoring.", changes[i].path);
- break;
- case UNIT_FILE_IS_DANGLING:
- if (!quiet)
- log_info("Unit %s is an alias to a unit that is not present, ignoring.",
- changes[i].path);
- break;
- case -EEXIST:
- if (changes[i].source)
- log_error_errno(changes[i].type,
- "Failed to %s unit, file %s already exists and is a symlink to %s.",
- verb, changes[i].path, changes[i].source);
- else
- log_error_errno(changes[i].type,
- "Failed to %s unit, file %s already exists.",
- verb, changes[i].path);
- logged = true;
- break;
- case -ERFKILL:
- log_error_errno(changes[i].type, "Failed to %s unit, unit %s is masked.",
- verb, changes[i].path);
- logged = true;
- break;
- case -EADDRNOTAVAIL:
- log_error_errno(changes[i].type, "Failed to %s unit, unit %s is transient or generated.",
- verb, changes[i].path);
- logged = true;
- break;
- case -ELOOP:
- log_error_errno(changes[i].type, "Failed to %s unit, refusing to operate on linked unit file %s",
- verb, changes[i].path);
- logged = true;
- break;
- default:
- assert(changes[i].type < 0);
- log_error_errno(changes[i].type, "Failed to %s unit, file %s: %m.",
- verb, changes[i].path);
- logged = true;
- }
- }
-
- if (r < 0 && !logged)
- log_error_errno(r, "Failed to %s: %m.", verb);
-}
-
-/**
- * Checks if two paths or symlinks from wd are the same, when root is the root of the filesystem.
- * wc should be the full path in the host file system.
- */
-static bool chroot_symlinks_same(const char *root, const char *wd, const char *a, const char *b) {
- assert(path_is_absolute(wd));
-
- /* This will give incorrect results if the paths are relative and go outside
- * of the chroot. False negatives are possible. */
-
- if (!root)
- root = "/";
-
- a = strjoina(path_is_absolute(a) ? root : wd, "/", a);
- b = strjoina(path_is_absolute(b) ? root : wd, "/", b);
- return path_equal_or_files_same(a, b);
-}
-
-static int create_symlink(
- const LookupPaths *paths,
- const char *old_path,
- const char *new_path,
- bool force,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_free_ char *dest = NULL, *dirname = NULL;
- const char *rp;
- int r;
-
- assert(old_path);
- assert(new_path);
-
- rp = skip_root(paths, old_path);
- if (rp)
- old_path = rp;
-
- /* Actually create a symlink, and remember that we did. Is
- * smart enough to check if there's already a valid symlink in
- * place.
- *
- * Returns 1 if a symlink was created or already exists and points to
- * the right place, or negative on error.
- */
-
- mkdir_parents_label(new_path, 0755);
-
- if (symlink(old_path, new_path) >= 0) {
- unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
- return 1;
- }
-
- if (errno != EEXIST) {
- unit_file_changes_add(changes, n_changes, -errno, new_path, NULL);
- return -errno;
- }
-
- r = readlink_malloc(new_path, &dest);
- if (r < 0) {
- /* translate EINVAL (non-symlink exists) to EEXIST */
- if (r == -EINVAL)
- r = -EEXIST;
-
- unit_file_changes_add(changes, n_changes, r, new_path, NULL);
- return r;
- }
-
- dirname = dirname_malloc(new_path);
- if (!dirname)
- return -ENOMEM;
-
- if (chroot_symlinks_same(paths->root_dir, dirname, dest, old_path))
- return 1;
-
- if (!force) {
- unit_file_changes_add(changes, n_changes, -EEXIST, new_path, dest);
- return -EEXIST;
- }
-
- r = symlink_atomic(old_path, new_path);
- if (r < 0) {
- unit_file_changes_add(changes, n_changes, r, new_path, NULL);
- return r;
- }
-
- unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
- unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
-
- return 1;
-}
-
-static int mark_symlink_for_removal(
- Set **remove_symlinks_to,
- const char *p) {
-
- char *n;
- int r;
-
- assert(p);
-
- r = set_ensure_allocated(remove_symlinks_to, &string_hash_ops);
- if (r < 0)
- return r;
-
- n = strdup(p);
- if (!n)
- return -ENOMEM;
-
- path_kill_slashes(n);
-
- r = set_consume(*remove_symlinks_to, n);
- if (r == -EEXIST)
- return 0;
- if (r < 0)
- return r;
-
- return 1;
-}
-
-static int remove_marked_symlinks_fd(
- Set *remove_symlinks_to,
- int fd,
- const char *path,
- const char *config_path,
- const LookupPaths *lp,
- bool dry_run,
- bool *restart,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
- int r = 0;
-
- assert(remove_symlinks_to);
- assert(fd >= 0);
- assert(path);
- assert(config_path);
- assert(lp);
- assert(restart);
-
- d = fdopendir(fd);
- if (!d) {
- safe_close(fd);
- return -errno;
- }
-
- rewinddir(d);
-
- FOREACH_DIRENT(de, d, return -errno) {
-
- dirent_ensure_type(d, de);
-
- if (de->d_type == DT_DIR) {
- _cleanup_free_ char *p = NULL;
- int nfd, q;
-
- nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
- if (nfd < 0) {
- if (errno == ENOENT)
- continue;
-
- if (r == 0)
- r = -errno;
- continue;
- }
-
- p = path_make_absolute(de->d_name, path);
- if (!p) {
- safe_close(nfd);
- return -ENOMEM;
- }
-
- /* This will close nfd, regardless whether it succeeds or not */
- q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, lp, dry_run, restart, changes, n_changes);
- if (q < 0 && r == 0)
- r = q;
-
- } else if (de->d_type == DT_LNK) {
- _cleanup_free_ char *p = NULL, *dest = NULL;
- const char *rp;
- bool found;
- int q;
-
- if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
- continue;
-
- p = path_make_absolute(de->d_name, path);
- if (!p)
- return -ENOMEM;
- path_kill_slashes(p);
-
- q = readlink_malloc(p, &dest);
- if (q == -ENOENT)
- continue;
- if (q < 0) {
- if (r == 0)
- r = q;
- continue;
- }
-
- /* We remove all links pointing to a file or path that is marked, as well as all files sharing
- * the same name as a file that is marked. */
-
- found = set_contains(remove_symlinks_to, dest) ||
- set_contains(remove_symlinks_to, basename(dest)) ||
- set_contains(remove_symlinks_to, de->d_name);
-
- if (!found)
- continue;
-
- if (!dry_run) {
- if (unlinkat(fd, de->d_name, 0) < 0 && errno != ENOENT) {
- if (r == 0)
- r = -errno;
- unit_file_changes_add(changes, n_changes, -errno, p, NULL);
- continue;
- }
-
- (void) rmdir_parents(p, config_path);
- }
-
- unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
-
- /* Now, remember the full path (but with the root prefix removed) of
- * the symlink we just removed, and remove any symlinks to it, too. */
-
- rp = skip_root(lp, p);
- q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: p);
- if (q < 0)
- return q;
- if (q > 0 && !dry_run)
- *restart = true;
- }
- }
-
- return r;
-}
-
-static int remove_marked_symlinks(
- Set *remove_symlinks_to,
- const char *config_path,
- const LookupPaths *lp,
- bool dry_run,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_close_ int fd = -1;
- bool restart;
- int r = 0;
-
- assert(config_path);
- assert(lp);
-
- if (set_size(remove_symlinks_to) <= 0)
- return 0;
-
- fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC);
- if (fd < 0)
- return errno == ENOENT ? 0 : -errno;
-
- do {
- int q, cfd;
- restart = false;
-
- cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
- if (cfd < 0)
- return -errno;
-
- /* This takes possession of cfd and closes it */
- q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, lp, dry_run, &restart, changes, n_changes);
- if (r == 0)
- r = q;
- } while (restart);
-
- return r;
-}
-
-static int find_symlinks_fd(
- const char *root_dir,
- const char *name,
- int fd,
- const char *path,
- const char *config_path,
- const LookupPaths *lp,
- bool *same_name_link) {
-
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
- int r = 0;
-
- assert(name);
- assert(fd >= 0);
- assert(path);
- assert(config_path);
- assert(lp);
- assert(same_name_link);
-
- d = fdopendir(fd);
- if (!d) {
- safe_close(fd);
- return -errno;
- }
-
- FOREACH_DIRENT(de, d, return -errno) {
-
- dirent_ensure_type(d, de);
-
- if (de->d_type == DT_DIR) {
- _cleanup_free_ char *p = NULL;
- int nfd, q;
-
- nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
- if (nfd < 0) {
- if (errno == ENOENT)
- continue;
-
- if (r == 0)
- r = -errno;
- continue;
- }
-
- p = path_make_absolute(de->d_name, path);
- if (!p) {
- safe_close(nfd);
- return -ENOMEM;
- }
-
- /* This will close nfd, regardless whether it succeeds or not */
- q = find_symlinks_fd(root_dir, name, nfd, p, config_path, lp, same_name_link);
- if (q > 0)
- return 1;
- if (r == 0)
- r = q;
-
- } else if (de->d_type == DT_LNK) {
- _cleanup_free_ char *p = NULL, *dest = NULL;
- bool found_path, found_dest, b = false;
- int q;
-
- /* Acquire symlink name */
- p = path_make_absolute(de->d_name, path);
- if (!p)
- return -ENOMEM;
-
- /* Acquire symlink destination */
- q = readlink_malloc(p, &dest);
- if (q == -ENOENT)
- continue;
- if (q < 0) {
- if (r == 0)
- r = q;
- continue;
- }
-
- /* Make absolute */
- if (!path_is_absolute(dest)) {
- char *x;
-
- x = prefix_root(root_dir, dest);
- if (!x)
- return -ENOMEM;
-
- free(dest);
- dest = x;
- }
-
- /* Check if the symlink itself matches what we
- * are looking for */
- if (path_is_absolute(name))
- found_path = path_equal(p, name);
- else
- found_path = streq(de->d_name, name);
-
- /* Check if what the symlink points to
- * matches what we are looking for */
- if (path_is_absolute(name))
- found_dest = path_equal(dest, name);
- else
- found_dest = streq(basename(dest), name);
-
- if (found_path && found_dest) {
- _cleanup_free_ char *t = NULL;
-
- /* Filter out same name links in the main
- * config path */
- t = path_make_absolute(name, config_path);
- if (!t)
- return -ENOMEM;
-
- b = path_equal(t, p);
- }
-
- if (b)
- *same_name_link = true;
- else if (found_path || found_dest)
- return 1;
- }
- }
-
- return r;
-}
-
-static int find_symlinks(
- const char *root_dir,
- const char *name,
- const char *config_path,
- const LookupPaths *lp,
- bool *same_name_link) {
-
- int fd;
-
- assert(name);
- assert(config_path);
- assert(same_name_link);
-
- fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC);
- if (fd < 0) {
- if (IN_SET(errno, ENOENT, ENOTDIR, EACCES))
- return 0;
- return -errno;
- }
-
- /* This takes possession of fd and closes it */
- return find_symlinks_fd(root_dir, name, fd, config_path, config_path, lp, same_name_link);
-}
-
-static int find_symlinks_in_scope(
- UnitFileScope scope,
- const LookupPaths *paths,
- const char *name,
- UnitFileState *state) {
-
- bool same_name_link_runtime = false, same_name_link = false;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(paths);
- assert(name);
-
- /* First look in the persistent config path */
- r = find_symlinks(paths->root_dir, name, paths->persistent_config, paths, &same_name_link);
- if (r < 0)
- return r;
- if (r > 0) {
- *state = UNIT_FILE_ENABLED;
- return r;
- }
-
- /* Then look in runtime config path */
- r = find_symlinks(paths->root_dir, name, paths->runtime_config, paths, &same_name_link_runtime);
- if (r < 0)
- return r;
- if (r > 0) {
- *state = UNIT_FILE_ENABLED_RUNTIME;
- return r;
- }
-
- /* Hmm, we didn't find it, but maybe we found the same name
- * link? */
- if (same_name_link) {
- *state = UNIT_FILE_LINKED;
- return 1;
- }
- if (same_name_link_runtime) {
- *state = UNIT_FILE_LINKED_RUNTIME;
- return 1;
- }
-
- return 0;
-}
-
-static void install_info_free(UnitFileInstallInfo *i) {
-
- if (!i)
- return;
-
- free(i->name);
- free(i->path);
- strv_free(i->aliases);
- strv_free(i->wanted_by);
- strv_free(i->required_by);
- strv_free(i->also);
- free(i->default_instance);
- free(i->symlink_target);
- free(i);
-}
-
-static OrderedHashmap* install_info_hashmap_free(OrderedHashmap *m) {
- UnitFileInstallInfo *i;
-
- if (!m)
- return NULL;
-
- while ((i = ordered_hashmap_steal_first(m)))
- install_info_free(i);
-
- return ordered_hashmap_free(m);
-}
-
-static void install_context_done(InstallContext *c) {
- assert(c);
-
- c->will_process = install_info_hashmap_free(c->will_process);
- c->have_processed = install_info_hashmap_free(c->have_processed);
-}
-
-static UnitFileInstallInfo *install_info_find(InstallContext *c, const char *name) {
- UnitFileInstallInfo *i;
-
- i = ordered_hashmap_get(c->have_processed, name);
- if (i)
- return i;
-
- return ordered_hashmap_get(c->will_process, name);
-}
-
-static int install_info_may_process(
- UnitFileInstallInfo *i,
- const LookupPaths *paths,
- UnitFileChange **changes,
- unsigned *n_changes) {
- assert(i);
- assert(paths);
-
- /* Checks whether the loaded unit file is one we should process, or is masked,
- * transient or generated and thus not subject to enable/disable operations. */
-
- if (i->type == UNIT_FILE_TYPE_MASKED) {
- unit_file_changes_add(changes, n_changes, -ERFKILL, i->path, NULL);
- return -ERFKILL;
- }
- if (path_is_generator(paths, i->path) ||
- path_is_transient(paths, i->path)) {
- unit_file_changes_add(changes, n_changes, -EADDRNOTAVAIL, i->path, NULL);
- return -EADDRNOTAVAIL;
- }
-
- return 0;
-}
-
-/**
- * Adds a new UnitFileInstallInfo entry under name in the InstallContext.will_process
- * hashmap, or retrieves the existing one if already present.
- *
- * Returns negative on error, 0 if the unit was already known, 1 otherwise.
- */
-static int install_info_add(
- InstallContext *c,
- const char *name,
- const char *path,
- bool auxiliary,
- UnitFileInstallInfo **ret) {
-
- UnitFileInstallInfo *i = NULL;
- int r;
-
- assert(c);
- assert(name || path);
-
- if (!name)
- name = basename(path);
-
- if (!unit_name_is_valid(name, UNIT_NAME_ANY))
- return -EINVAL;
-
- i = install_info_find(c, name);
- if (i) {
- i->auxiliary = i->auxiliary && auxiliary;
-
- if (ret)
- *ret = i;
- return 0;
- }
-
- r = ordered_hashmap_ensure_allocated(&c->will_process, &string_hash_ops);
- if (r < 0)
- return r;
-
- i = new0(UnitFileInstallInfo, 1);
- if (!i)
- return -ENOMEM;
- i->type = _UNIT_FILE_TYPE_INVALID;
- i->auxiliary = auxiliary;
-
- i->name = strdup(name);
- if (!i->name) {
- r = -ENOMEM;
- goto fail;
- }
-
- if (path) {
- i->path = strdup(path);
- if (!i->path) {
- r = -ENOMEM;
- goto fail;
- }
- }
-
- r = ordered_hashmap_put(c->will_process, i->name, i);
- if (r < 0)
- goto fail;
-
- if (ret)
- *ret = i;
-
- return 1;
-
-fail:
- install_info_free(i);
- return r;
-}
-
-static int config_parse_alias(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- const char *name;
- UnitType type;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
-
- name = basename(filename);
- type = unit_name_to_type(name);
- if (!unit_type_may_alias(type))
- return log_syntax(unit, LOG_WARNING, filename, line, 0,
- "Alias= is not allowed for %s units, ignoring.",
- unit_type_to_string(type));
-
- return config_parse_strv(unit, filename, line, section, section_line,
- lvalue, ltype, rvalue, data, userdata);
-}
-
-static int config_parse_also(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- UnitFileInstallInfo *info = userdata, *alsoinfo = NULL;
- InstallContext *c = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
-
- for (;;) {
- _cleanup_free_ char *word = NULL, *printed = NULL;
-
- r = extract_first_word(&rvalue, &word, NULL, 0);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- r = install_full_printf(info, word, &printed);
- if (r < 0)
- return r;
-
- if (!unit_name_is_valid(printed, UNIT_NAME_ANY))
- return -EINVAL;
-
- r = install_info_add(c, printed, NULL, true, &alsoinfo);
- if (r < 0)
- return r;
-
- r = strv_push(&info->also, printed);
- if (r < 0)
- return r;
-
- printed = NULL;
- }
-
- return 0;
-}
-
-static int config_parse_default_instance(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- UnitFileInstallInfo *i = data;
- const char *name;
- _cleanup_free_ char *printed = NULL;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
-
- name = basename(filename);
- if (unit_name_is_valid(name, UNIT_NAME_INSTANCE))
- /* When enabling an instance, we might be using a template unit file,
- * but we should ignore DefaultInstance silently. */
- return 0;
- if (!unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
- return log_syntax(unit, LOG_WARNING, filename, line, 0,
- "DefaultInstance= only makes sense for template units, ignoring.");
-
- r = install_full_printf(i, rvalue, &printed);
- if (r < 0)
- return r;
-
- if (!unit_instance_is_valid(printed))
- return -EINVAL;
-
- return free_and_replace(i->default_instance, printed);
-}
-
-static int unit_file_load(
- InstallContext *c,
- UnitFileInstallInfo *info,
- const char *path,
- SearchFlags flags) {
-
- const ConfigTableItem items[] = {
- { "Install", "Alias", config_parse_alias, 0, &info->aliases },
- { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
- { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
- { "Install", "DefaultInstance", config_parse_default_instance, 0, info },
- { "Install", "Also", config_parse_also, 0, c },
- {}
- };
-
- const char *name;
- UnitType type;
- _cleanup_fclose_ FILE *f = NULL;
- _cleanup_close_ int fd = -1;
- struct stat st;
- int r;
-
- assert(info);
- assert(path);
-
- name = basename(path);
- type = unit_name_to_type(name);
- if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) &&
- !unit_type_may_template(type))
- return log_error_errno(EINVAL, "Unit type %s cannot be templated.", unit_type_to_string(type));
-
- if (!(flags & SEARCH_LOAD)) {
- r = lstat(path, &st);
- if (r < 0)
- return -errno;
-
- if (null_or_empty(&st))
- info->type = UNIT_FILE_TYPE_MASKED;
- else if (S_ISREG(st.st_mode))
- info->type = UNIT_FILE_TYPE_REGULAR;
- else if (S_ISLNK(st.st_mode))
- return -ELOOP;
- else if (S_ISDIR(st.st_mode))
- return -EISDIR;
- else
- return -ENOTTY;
-
- return 0;
- }
-
- /* c is only needed if we actually load the file */
- assert(c);
-
- fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
- if (fd < 0)
- return -errno;
- if (fstat(fd, &st) < 0)
- return -errno;
- if (null_or_empty(&st)) {
- info->type = UNIT_FILE_TYPE_MASKED;
- return 0;
- }
- if (S_ISDIR(st.st_mode))
- return -EISDIR;
- if (!S_ISREG(st.st_mode))
- return -ENOTTY;
-
- f = fdopen(fd, "re");
- if (!f)
- return -errno;
- fd = -1;
-
- r = config_parse(NULL, path, f,
- NULL,
- config_item_table_lookup, items,
- true, true, false, info);
- if (r < 0)
- return log_debug_errno(r, "Failed to parse %s: %m", info->name);
-
- info->type = UNIT_FILE_TYPE_REGULAR;
-
- return
- (int) strv_length(info->aliases) +
- (int) strv_length(info->wanted_by) +
- (int) strv_length(info->required_by);
-}
-
-static int unit_file_load_or_readlink(
- InstallContext *c,
- UnitFileInstallInfo *info,
- const char *path,
- const char *root_dir,
- SearchFlags flags) {
-
- _cleanup_free_ char *target = NULL;
- int r;
-
- r = unit_file_load(c, info, path, flags);
- if (r != -ELOOP)
- return r;
-
- /* This is a symlink, let's read it. */
-
- r = readlink_malloc(path, &target);
- if (r < 0)
- return r;
-
- if (path_equal(target, "/dev/null"))
- info->type = UNIT_FILE_TYPE_MASKED;
- else {
- const char *bn;
- UnitType a, b;
-
- bn = basename(target);
-
- if (unit_name_is_valid(info->name, UNIT_NAME_PLAIN)) {
-
- if (!unit_name_is_valid(bn, UNIT_NAME_PLAIN))
- return -EINVAL;
-
- } else if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
-
- if (!unit_name_is_valid(bn, UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE))
- return -EINVAL;
-
- } else if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE)) {
-
- if (!unit_name_is_valid(bn, UNIT_NAME_TEMPLATE))
- return -EINVAL;
- } else
- return -EINVAL;
-
- /* Enforce that the symlink destination does not
- * change the unit file type. */
-
- a = unit_name_to_type(info->name);
- b = unit_name_to_type(bn);
- if (a < 0 || b < 0 || a != b)
- return -EINVAL;
-
- if (path_is_absolute(target))
- /* This is an absolute path, prefix the root so that we always deal with fully qualified paths */
- info->symlink_target = prefix_root(root_dir, target);
- else
- /* This is a relative path, take it relative to the dir the symlink is located in. */
- info->symlink_target = file_in_same_dir(path, target);
- if (!info->symlink_target)
- return -ENOMEM;
-
- info->type = UNIT_FILE_TYPE_SYMLINK;
- }
-
- return 0;
-}
-
-static int unit_file_search(
- InstallContext *c,
- UnitFileInstallInfo *info,
- const LookupPaths *paths,
- SearchFlags flags) {
-
- _cleanup_free_ char *template = NULL;
- char **p;
- int r;
-
- assert(info);
- assert(paths);
-
- /* Was this unit already loaded? */
- if (info->type != _UNIT_FILE_TYPE_INVALID)
- return 0;
-
- if (info->path)
- return unit_file_load_or_readlink(c, info, info->path, paths->root_dir, flags);
-
- assert(info->name);
-
- STRV_FOREACH(p, paths->search_path) {
- _cleanup_free_ char *path = NULL;
-
- path = strjoin(*p, "/", info->name, NULL);
- if (!path)
- return -ENOMEM;
-
- r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
- if (r >= 0) {
- info->path = path;
- path = NULL;
- return r;
- } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
- return r;
- }
-
- if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
- /* Unit file doesn't exist, however instance
- * enablement was requested. We will check if it is
- * possible to load template unit file. */
-
- r = unit_name_template(info->name, &template);
- if (r < 0)
- return r;
-
- STRV_FOREACH(p, paths->search_path) {
- _cleanup_free_ char *path = NULL;
-
- path = strjoin(*p, "/", template, NULL);
- if (!path)
- return -ENOMEM;
-
- r = unit_file_load_or_readlink(c, info, path, paths->root_dir, flags);
- if (r >= 0) {
- info->path = path;
- path = NULL;
- return r;
- } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
- return r;
- }
- }
-
- log_debug("Cannot find unit %s%s%s.", info->name, template ? " or " : "", strempty(template));
- return -ENOENT;
-}
-
-static int install_info_follow(
- InstallContext *c,
- UnitFileInstallInfo *i,
- const char *root_dir,
- SearchFlags flags) {
-
- assert(c);
- assert(i);
-
- if (i->type != UNIT_FILE_TYPE_SYMLINK)
- return -EINVAL;
- if (!i->symlink_target)
- return -EINVAL;
-
- /* If the basename doesn't match, the caller should add a
- * complete new entry for this. */
-
- if (!streq(basename(i->symlink_target), i->name))
- return -EXDEV;
-
- free_and_replace(i->path, i->symlink_target);
- i->type = _UNIT_FILE_TYPE_INVALID;
-
- return unit_file_load_or_readlink(c, i, i->path, root_dir, flags);
-}
-
-/**
- * Search for the unit file. If the unit name is a symlink, follow the symlink to the
- * target, maybe more than once. Propagate the instance name if present.
- */
-static int install_info_traverse(
- UnitFileScope scope,
- InstallContext *c,
- const LookupPaths *paths,
- UnitFileInstallInfo *start,
- SearchFlags flags,
- UnitFileInstallInfo **ret) {
-
- UnitFileInstallInfo *i;
- unsigned k = 0;
- int r;
-
- assert(paths);
- assert(start);
- assert(c);
-
- r = unit_file_search(c, start, paths, flags);
- if (r < 0)
- return r;
-
- i = start;
- while (i->type == UNIT_FILE_TYPE_SYMLINK) {
- /* Follow the symlink */
-
- if (++k > UNIT_FILE_FOLLOW_SYMLINK_MAX)
- return -ELOOP;
-
- if (!(flags & SEARCH_FOLLOW_CONFIG_SYMLINKS)) {
- r = path_is_config(paths, i->path);
- if (r < 0)
- return r;
- if (r > 0)
- return -ELOOP;
- }
-
- r = install_info_follow(c, i, paths->root_dir, flags);
- if (r == -EXDEV) {
- _cleanup_free_ char *buffer = NULL;
- const char *bn;
-
- /* Target has a different name, create a new
- * install info object for that, and continue
- * with that. */
-
- bn = basename(i->symlink_target);
-
- if (unit_name_is_valid(i->name, UNIT_NAME_INSTANCE) &&
- unit_name_is_valid(bn, UNIT_NAME_TEMPLATE)) {
-
- _cleanup_free_ char *instance = NULL;
-
- r = unit_name_to_instance(i->name, &instance);
- if (r < 0)
- return r;
-
- r = unit_name_replace_instance(bn, instance, &buffer);
- if (r < 0)
- return r;
-
- bn = buffer;
- }
-
- r = install_info_add(c, bn, NULL, false, &i);
- if (r < 0)
- return r;
-
- /* Try again, with the new target we found. */
- r = unit_file_search(c, i, paths, flags);
- if (r == -ENOENT)
- /* Translate error code to highlight this specific case */
- return -ENOLINK;
- }
-
- if (r < 0)
- return r;
- }
-
- if (ret)
- *ret = i;
-
- return 0;
-}
-
-/**
- * Call install_info_add() with name_or_path as the path (if name_or_path starts with "/")
- * or the name (otherwise). root_dir is prepended to the path.
- */
-static int install_info_add_auto(
- InstallContext *c,
- const LookupPaths *paths,
- const char *name_or_path,
- UnitFileInstallInfo **ret) {
-
- assert(c);
- assert(name_or_path);
-
- if (path_is_absolute(name_or_path)) {
- const char *pp;
-
- pp = prefix_roota(paths->root_dir, name_or_path);
-
- return install_info_add(c, NULL, pp, false, ret);
- } else
- return install_info_add(c, name_or_path, NULL, false, ret);
-}
-
-static int install_info_discover(
- UnitFileScope scope,
- InstallContext *c,
- const LookupPaths *paths,
- const char *name,
- SearchFlags flags,
- UnitFileInstallInfo **ret,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- UnitFileInstallInfo *i;
- int r;
-
- assert(c);
- assert(paths);
- assert(name);
-
- r = install_info_add_auto(c, paths, name, &i);
- if (r >= 0)
- r = install_info_traverse(scope, c, paths, i, flags, ret);
-
- if (r < 0)
- unit_file_changes_add(changes, n_changes, r, name, NULL);
- return r;
-}
-
-static int install_info_symlink_alias(
- UnitFileInstallInfo *i,
- const LookupPaths *paths,
- const char *config_path,
- bool force,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- char **s;
- int r = 0, q;
-
- assert(i);
- assert(paths);
- assert(config_path);
-
- STRV_FOREACH(s, i->aliases) {
- _cleanup_free_ char *alias_path = NULL, *dst = NULL;
-
- q = install_full_printf(i, *s, &dst);
- if (q < 0)
- return q;
-
- alias_path = path_make_absolute(dst, config_path);
- if (!alias_path)
- return -ENOMEM;
-
- q = create_symlink(paths, i->path, alias_path, force, changes, n_changes);
- if (r == 0)
- r = q;
- }
-
- return r;
-}
-
-static int install_info_symlink_wants(
- UnitFileInstallInfo *i,
- const LookupPaths *paths,
- const char *config_path,
- char **list,
- const char *suffix,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_free_ char *buf = NULL;
- const char *n;
- char **s;
- int r = 0, q;
-
- assert(i);
- assert(paths);
- assert(config_path);
-
- if (strv_isempty(list))
- return 0;
-
- if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE)) {
- UnitFileInstallInfo instance = {
- .type = _UNIT_FILE_TYPE_INVALID,
- };
- _cleanup_free_ char *path = NULL;
-
- /* Don't install any symlink if there's no default
- * instance configured */
-
- if (!i->default_instance)
- return 0;
-
- r = unit_name_replace_instance(i->name, i->default_instance, &buf);
- if (r < 0)
- return r;
-
- instance.name = buf;
- r = unit_file_search(NULL, &instance, paths, SEARCH_FOLLOW_CONFIG_SYMLINKS);
- if (r < 0)
- return r;
-
- path = instance.path;
- instance.path = NULL;
-
- if (instance.type == UNIT_FILE_TYPE_MASKED) {
- unit_file_changes_add(changes, n_changes, -ERFKILL, path, NULL);
- return -ERFKILL;
- }
-
- n = buf;
- } else
- n = i->name;
-
- STRV_FOREACH(s, list) {
- _cleanup_free_ char *path = NULL, *dst = NULL;
-
- q = install_full_printf(i, *s, &dst);
- if (q < 0)
- return q;
-
- if (!unit_name_is_valid(dst, UNIT_NAME_ANY)) {
- r = -EINVAL;
- continue;
- }
-
- path = strjoin(config_path, "/", dst, suffix, n, NULL);
- if (!path)
- return -ENOMEM;
-
- q = create_symlink(paths, i->path, path, true, changes, n_changes);
- if (r == 0)
- r = q;
- }
-
- return r;
-}
-
-static int install_info_symlink_link(
- UnitFileInstallInfo *i,
- const LookupPaths *paths,
- const char *config_path,
- bool force,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_free_ char *path = NULL;
- int r;
-
- assert(i);
- assert(paths);
- assert(config_path);
- assert(i->path);
-
- r = in_search_path(paths, i->path);
- if (r < 0)
- return r;
- if (r > 0)
- return 0;
-
- path = strjoin(config_path, "/", i->name, NULL);
- if (!path)
- return -ENOMEM;
-
- return create_symlink(paths, i->path, path, force, changes, n_changes);
-}
-
-static int install_info_apply(
- UnitFileInstallInfo *i,
- const LookupPaths *paths,
- const char *config_path,
- bool force,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- int r, q;
-
- assert(i);
- assert(paths);
- assert(config_path);
-
- if (i->type != UNIT_FILE_TYPE_REGULAR)
- return 0;
-
- r = install_info_symlink_alias(i, paths, config_path, force, changes, n_changes);
-
- q = install_info_symlink_wants(i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
- if (r == 0)
- r = q;
-
- q = install_info_symlink_wants(i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
- if (r == 0)
- r = q;
-
- q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes);
- /* Do not count links to the unit file towards the "carries_install_info" count */
- if (r == 0 && q < 0)
- r = q;
-
- return r;
-}
-
-static int install_context_apply(
- UnitFileScope scope,
- InstallContext *c,
- const LookupPaths *paths,
- const char *config_path,
- bool force,
- SearchFlags flags,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- UnitFileInstallInfo *i;
- int r;
-
- assert(c);
- assert(paths);
- assert(config_path);
-
- if (ordered_hashmap_isempty(c->will_process))
- return 0;
-
- r = ordered_hashmap_ensure_allocated(&c->have_processed, &string_hash_ops);
- if (r < 0)
- return r;
-
- r = 0;
- while ((i = ordered_hashmap_first(c->will_process))) {
- int q;
-
- q = ordered_hashmap_move_one(c->have_processed, c->will_process, i->name);
- if (q < 0)
- return q;
-
- r = install_info_traverse(scope, c, paths, i, flags, NULL);
- if (r < 0) {
- unit_file_changes_add(changes, n_changes, r, i->name, NULL);
- return r;
- }
-
- /* We can attempt to process a masked unit when a different unit
- * that we were processing specifies it in Also=. */
- if (i->type == UNIT_FILE_TYPE_MASKED) {
- unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_MASKED, i->path, NULL);
- if (r >= 0)
- /* Assume that something *could* have been enabled here,
- * avoid "empty [Install] section" warning. */
- r += 1;
- continue;
- }
-
- if (i->type != UNIT_FILE_TYPE_REGULAR)
- continue;
-
- q = install_info_apply(i, paths, config_path, force, changes, n_changes);
- if (r >= 0) {
- if (q < 0)
- r = q;
- else
- r += q;
- }
- }
-
- return r;
-}
-
-static int install_context_mark_for_removal(
- UnitFileScope scope,
- InstallContext *c,
- const LookupPaths *paths,
- Set **remove_symlinks_to,
- const char *config_path) {
-
- UnitFileInstallInfo *i;
- int r;
-
- assert(c);
- assert(paths);
- assert(config_path);
-
- /* Marks all items for removal */
-
- if (ordered_hashmap_isempty(c->will_process))
- return 0;
-
- r = ordered_hashmap_ensure_allocated(&c->have_processed, &string_hash_ops);
- if (r < 0)
- return r;
-
- while ((i = ordered_hashmap_first(c->will_process))) {
-
- r = ordered_hashmap_move_one(c->have_processed, c->will_process, i->name);
- if (r < 0)
- return r;
-
- r = install_info_traverse(scope, c, paths, i, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL);
- if (r == -ENOLINK) {
- log_debug_errno(r, "Name %s leads to a dangling symlink, ignoring.", i->name);
- continue;
- } else if (r == -ENOENT && i->auxiliary) {
- /* some unit specified in Also= or similar is missing */
- log_debug_errno(r, "Auxiliary unit %s not found, ignoring.", i->name);
- continue;
- } else if (r < 0)
- return log_debug_errno(r, "Failed to find unit %s: %m", i->name);
-
- if (i->type != UNIT_FILE_TYPE_REGULAR) {
- log_debug("Unit %s has type %s, ignoring.",
- i->name,
- unit_file_type_to_string(i->type) ?: "invalid");
- continue;
- }
-
- r = mark_symlink_for_removal(remove_symlinks_to, i->name);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-int unit_file_mask(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- const char *config_path;
- char **i;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
-
- STRV_FOREACH(i, files) {
- _cleanup_free_ char *path = NULL;
- int q;
-
- if (!unit_name_is_valid(*i, UNIT_NAME_ANY)) {
- if (r == 0)
- r = -EINVAL;
- continue;
- }
-
- path = path_make_absolute(*i, config_path);
- if (!path)
- return -ENOMEM;
-
- q = create_symlink(&paths, "/dev/null", path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
- if (q < 0 && r >= 0)
- r = q;
- }
-
- return r;
-}
-
-int unit_file_unmask(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- _cleanup_free_ char **todo = NULL;
- size_t n_todo = 0, n_allocated = 0;
- const char *config_path;
- char **i;
- bool dry_run;
- int r, q;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
- dry_run = !!(flags & UNIT_FILE_DRY_RUN);
-
- STRV_FOREACH(i, files) {
- _cleanup_free_ char *path = NULL;
-
- if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
- return -EINVAL;
-
- path = path_make_absolute(*i, config_path);
- if (!path)
- return -ENOMEM;
-
- r = null_or_empty_path(path);
- if (r == -ENOENT)
- continue;
- if (r < 0)
- return r;
- if (r == 0)
- continue;
-
- if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
- return -ENOMEM;
-
- todo[n_todo++] = *i;
- }
-
- strv_uniq(todo);
-
- r = 0;
- STRV_FOREACH(i, todo) {
- _cleanup_free_ char *path = NULL;
- const char *rp;
-
- path = path_make_absolute(*i, config_path);
- if (!path)
- return -ENOMEM;
-
- if (!dry_run && unlink(path) < 0) {
- if (errno != ENOENT) {
- if (r >= 0)
- r = -errno;
- unit_file_changes_add(changes, n_changes, -errno, path, NULL);
- }
-
- continue;
- }
-
- unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
-
- rp = skip_root(&paths, path);
- q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
- if (q < 0)
- return q;
- }
-
- q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
- if (r >= 0)
- r = q;
-
- return r;
-}
-
-int unit_file_link(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_free_ char **todo = NULL;
- size_t n_todo = 0, n_allocated = 0;
- const char *config_path;
- char **i;
- int r, q;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
-
- STRV_FOREACH(i, files) {
- _cleanup_free_ char *full = NULL;
- struct stat st;
- char *fn;
-
- if (!path_is_absolute(*i))
- return -EINVAL;
-
- fn = basename(*i);
- if (!unit_name_is_valid(fn, UNIT_NAME_ANY))
- return -EINVAL;
-
- full = prefix_root(paths.root_dir, *i);
- if (!full)
- return -ENOMEM;
-
- if (lstat(full, &st) < 0)
- return -errno;
- if (S_ISLNK(st.st_mode))
- return -ELOOP;
- if (S_ISDIR(st.st_mode))
- return -EISDIR;
- if (!S_ISREG(st.st_mode))
- return -ENOTTY;
-
- q = in_search_path(&paths, *i);
- if (q < 0)
- return q;
- if (q > 0)
- continue;
-
- if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
- return -ENOMEM;
-
- todo[n_todo++] = *i;
- }
-
- strv_uniq(todo);
-
- r = 0;
- STRV_FOREACH(i, todo) {
- _cleanup_free_ char *new_path = NULL;
-
- new_path = path_make_absolute(basename(*i), config_path);
- if (!new_path)
- return -ENOMEM;
-
- q = create_symlink(&paths, *i, new_path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
- if (q < 0 && r >= 0)
- r = q;
- }
-
- return r;
-}
-
-static int path_shall_revert(const LookupPaths *paths, const char *path) {
- int r;
-
- assert(paths);
- assert(path);
-
- /* Checks whether the path is one where the drop-in directories shall be removed. */
-
- r = path_is_config(paths, path);
- if (r != 0)
- return r;
-
- r = path_is_control(paths, path);
- if (r != 0)
- return r;
-
- return path_is_transient(paths, path);
-}
-
-int unit_file_revert(
- UnitFileScope scope,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_strv_free_ char **todo = NULL;
- size_t n_todo = 0, n_allocated = 0;
- char **i;
- int r, q;
-
- /* Puts a unit file back into vendor state. This means:
- *
- * a) we remove all drop-in snippets added by the user ("config"), add to transient units ("transient"), and
- * added via "systemctl set-property" ("control"), but not if the drop-in is generated ("generated").
- *
- * c) if there's a vendor unit file (i.e. one in /usr) we remove any configured overriding unit files (i.e. in
- * "config", but not in "transient" or "control" or even "generated").
- *
- * We remove all that in both the runtime and the persistent directories, if that applies.
- */
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- STRV_FOREACH(i, files) {
- bool has_vendor = false;
- char **p;
-
- if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
- return -EINVAL;
-
- STRV_FOREACH(p, paths.search_path) {
- _cleanup_free_ char *path = NULL, *dropin = NULL;
- struct stat st;
-
- path = path_make_absolute(*i, *p);
- if (!path)
- return -ENOMEM;
-
- r = lstat(path, &st);
- if (r < 0) {
- if (errno != ENOENT)
- return -errno;
- } else if (S_ISREG(st.st_mode)) {
- /* Check if there's a vendor version */
- r = path_is_vendor(&paths, path);
- if (r < 0)
- return r;
- if (r > 0)
- has_vendor = true;
- }
-
- dropin = strappend(path, ".d");
- if (!dropin)
- return -ENOMEM;
-
- r = lstat(dropin, &st);
- if (r < 0) {
- if (errno != ENOENT)
- return -errno;
- } else if (S_ISDIR(st.st_mode)) {
- /* Remove the drop-ins */
- r = path_shall_revert(&paths, dropin);
- if (r < 0)
- return r;
- if (r > 0) {
- if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
- return -ENOMEM;
-
- todo[n_todo++] = dropin;
- dropin = NULL;
- }
- }
- }
-
- if (!has_vendor)
- continue;
-
- /* OK, there's a vendor version, hence drop all configuration versions */
- STRV_FOREACH(p, paths.search_path) {
- _cleanup_free_ char *path = NULL;
- struct stat st;
-
- path = path_make_absolute(*i, *p);
- if (!path)
- return -ENOMEM;
-
- r = lstat(path, &st);
- if (r < 0) {
- if (errno != ENOENT)
- return -errno;
- } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
- r = path_is_config(&paths, path);
- if (r < 0)
- return r;
- if (r > 0) {
- if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
- return -ENOMEM;
-
- todo[n_todo++] = path;
- path = NULL;
- }
- }
- }
- }
-
- strv_uniq(todo);
-
- r = 0;
- STRV_FOREACH(i, todo) {
- _cleanup_strv_free_ char **fs = NULL;
- const char *rp;
- char **j;
-
- (void) get_files_in_directory(*i, &fs);
-
- q = rm_rf(*i, REMOVE_ROOT|REMOVE_PHYSICAL);
- if (q < 0 && q != -ENOENT && r >= 0) {
- r = q;
- continue;
- }
-
- STRV_FOREACH(j, fs) {
- _cleanup_free_ char *t = NULL;
-
- t = strjoin(*i, "/", *j, NULL);
- if (!t)
- return -ENOMEM;
-
- unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, t, NULL);
- }
-
- unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, *i, NULL);
-
- rp = skip_root(&paths, *i);
- q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: *i);
- if (q < 0)
- return q;
- }
-
- q = remove_marked_symlinks(remove_symlinks_to, paths.runtime_config, &paths, false, changes, n_changes);
- if (r >= 0)
- r = q;
-
- q = remove_marked_symlinks(remove_symlinks_to, paths.persistent_config, &paths, false, changes, n_changes);
- if (r >= 0)
- r = q;
-
- return r;
-}
-
-int unit_file_add_dependency(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- const char *target,
- UnitDependency dep,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_(install_context_done) InstallContext c = {};
- UnitFileInstallInfo *i, *target_info;
- const char *config_path;
- char **f;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(target);
-
- if (!IN_SET(dep, UNIT_WANTS, UNIT_REQUIRES))
- return -EINVAL;
-
- if (!unit_name_is_valid(target, UNIT_NAME_ANY))
- return -EINVAL;
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
-
- r = install_info_discover(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS,
- &target_info, changes, n_changes);
- if (r < 0)
- return r;
- r = install_info_may_process(target_info, &paths, changes, n_changes);
- if (r < 0)
- return r;
-
- assert(target_info->type == UNIT_FILE_TYPE_REGULAR);
-
- STRV_FOREACH(f, files) {
- char ***l;
-
- r = install_info_discover(scope, &c, &paths, *f, SEARCH_FOLLOW_CONFIG_SYMLINKS,
- &i, changes, n_changes);
- if (r < 0)
- return r;
- r = install_info_may_process(i, &paths, changes, n_changes);
- if (r < 0)
- return r;
-
- assert(i->type == UNIT_FILE_TYPE_REGULAR);
-
- /* We didn't actually load anything from the unit
- * file, but instead just add in our new symlink to
- * create. */
-
- if (dep == UNIT_WANTS)
- l = &i->wanted_by;
- else
- l = &i->required_by;
-
- strv_free(*l);
- *l = strv_new(target_info->name, NULL);
- if (!*l)
- return -ENOMEM;
- }
-
- return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
-}
-
-int unit_file_enable(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_(install_context_done) InstallContext c = {};
- const char *config_path;
- UnitFileInstallInfo *i;
- char **f;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
-
- STRV_FOREACH(f, files) {
- r = install_info_discover(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
- &i, changes, n_changes);
- if (r < 0)
- return r;
- r = install_info_may_process(i, &paths, changes, n_changes);
- if (r < 0)
- return r;
-
- assert(i->type == UNIT_FILE_TYPE_REGULAR);
- }
-
- /* This will return the number of symlink rules that were
- supposed to be created, not the ones actually created. This
- is useful to determine whether the passed files had any
- installation data at all. */
-
- return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_LOAD, changes, n_changes);
-}
-
-int unit_file_disable(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_(install_context_done) InstallContext c = {};
- _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- const char *config_path;
- char **i;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
-
- STRV_FOREACH(i, files) {
- if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
- return -EINVAL;
-
- r = install_info_add(&c, *i, NULL, false, NULL);
- if (r < 0)
- return r;
- }
-
- r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path);
- if (r < 0)
- return r;
-
- return remove_marked_symlinks(remove_symlinks_to, config_path, &paths, !!(flags & UNIT_FILE_DRY_RUN), changes, n_changes);
-}
-
-int unit_file_reenable(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- char **n;
- int r;
- size_t l, i;
-
- /* First, we invoke the disable command with only the basename... */
- l = strv_length(files);
- n = newa(char*, l+1);
- for (i = 0; i < l; i++)
- n[i] = basename(files[i]);
- n[i] = NULL;
-
- r = unit_file_disable(scope, flags, root_dir, n, changes, n_changes);
- if (r < 0)
- return r;
-
- /* But the enable command with the full name */
- return unit_file_enable(scope, flags, root_dir, files, changes, n_changes);
-}
-
-int unit_file_set_default(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- const char *name,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_(install_context_done) InstallContext c = {};
- UnitFileInstallInfo *i;
- const char *new_path;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(name);
-
- if (unit_name_to_type(name) != UNIT_TARGET) /* this also validates the name */
- return -EINVAL;
- if (streq(name, SPECIAL_DEFAULT_TARGET))
- return -EINVAL;
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- r = install_info_discover(scope, &c, &paths, name, 0, &i, changes, n_changes);
- if (r < 0)
- return r;
- r = install_info_may_process(i, &paths, changes, n_changes);
- if (r < 0)
- return r;
-
- new_path = strjoina(paths.persistent_config, "/" SPECIAL_DEFAULT_TARGET);
- return create_symlink(&paths, i->path, new_path, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
-}
-
-int unit_file_get_default(
- UnitFileScope scope,
- const char *root_dir,
- char **name) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_(install_context_done) InstallContext c = {};
- UnitFileInstallInfo *i;
- char *n;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(name);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- r = install_info_discover(scope, &c, &paths, SPECIAL_DEFAULT_TARGET, SEARCH_FOLLOW_CONFIG_SYMLINKS,
- &i, NULL, NULL);
- if (r < 0)
- return r;
- r = install_info_may_process(i, &paths, NULL, 0);
- if (r < 0)
- return r;
-
- n = strdup(i->name);
- if (!n)
- return -ENOMEM;
-
- *name = n;
- return 0;
-}
-
-static int unit_file_lookup_state(
- UnitFileScope scope,
- const LookupPaths *paths,
- const char *name,
- UnitFileState *ret) {
-
- _cleanup_(install_context_done) InstallContext c = {};
- UnitFileInstallInfo *i;
- UnitFileState state;
- int r;
-
- assert(paths);
- assert(name);
-
- if (!unit_name_is_valid(name, UNIT_NAME_ANY))
- return -EINVAL;
-
- r = install_info_discover(scope, &c, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
- &i, NULL, NULL);
- if (r < 0)
- return r;
-
- /* Shortcut things, if the caller just wants to know if this unit exists. */
- if (!ret)
- return 0;
-
- switch (i->type) {
-
- case UNIT_FILE_TYPE_MASKED:
- r = path_is_runtime(paths, i->path);
- if (r < 0)
- return r;
-
- state = r > 0 ? UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
- break;
-
- case UNIT_FILE_TYPE_REGULAR:
- r = path_is_generator(paths, i->path);
- if (r < 0)
- return r;
- if (r > 0) {
- state = UNIT_FILE_GENERATED;
- break;
- }
-
- r = path_is_transient(paths, i->path);
- if (r < 0)
- return r;
- if (r > 0) {
- state = UNIT_FILE_TRANSIENT;
- break;
- }
-
- r = find_symlinks_in_scope(scope, paths, i->name, &state);
- if (r < 0)
- return r;
- if (r == 0) {
- if (UNIT_FILE_INSTALL_INFO_HAS_RULES(i))
- state = UNIT_FILE_DISABLED;
- else if (UNIT_FILE_INSTALL_INFO_HAS_ALSO(i))
- state = UNIT_FILE_INDIRECT;
- else
- state = UNIT_FILE_STATIC;
- }
-
- break;
-
- default:
- assert_not_reached("Unexpect unit file type.");
- }
-
- *ret = state;
- return 0;
-}
-
-int unit_file_get_state(
- UnitFileScope scope,
- const char *root_dir,
- const char *name,
- UnitFileState *ret) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(name);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- return unit_file_lookup_state(scope, &paths, name, ret);
-}
-
-int unit_file_exists(UnitFileScope scope, const LookupPaths *paths, const char *name) {
- _cleanup_(install_context_done) InstallContext c = {};
- int r;
-
- assert(paths);
- assert(name);
-
- if (!unit_name_is_valid(name, UNIT_NAME_ANY))
- return -EINVAL;
-
- r = install_info_discover(scope, &c, paths, name, 0, NULL, NULL, NULL);
- if (r == -ENOENT)
- return 0;
- if (r < 0)
- return r;
-
- return 1;
-}
-
-static int read_presets(UnitFileScope scope, const char *root_dir, Presets *presets) {
- _cleanup_(presets_freep) Presets ps = {};
- size_t n_allocated = 0;
- _cleanup_strv_free_ char **files = NULL;
- char **p;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(presets);
-
- if (scope == UNIT_FILE_SYSTEM)
- r = conf_files_list(&files, ".preset", root_dir,
- "/etc/systemd/system-preset",
- "/usr/local/lib/systemd/system-preset",
- "/usr/lib/systemd/system-preset",
-#ifdef HAVE_SPLIT_USR
- "/lib/systemd/system-preset",
-#endif
- NULL);
- else if (scope == UNIT_FILE_GLOBAL)
- r = conf_files_list(&files, ".preset", root_dir,
- "/etc/systemd/user-preset",
- "/usr/local/lib/systemd/user-preset",
- "/usr/lib/systemd/user-preset",
- NULL);
- else {
- *presets = (Presets){};
-
- return 0;
- }
-
- if (r < 0)
- return r;
-
- STRV_FOREACH(p, files) {
- _cleanup_fclose_ FILE *f;
- char line[LINE_MAX];
- int n = 0;
-
- f = fopen(*p, "re");
- if (!f) {
- if (errno == ENOENT)
- continue;
-
- return -errno;
- }
-
- FOREACH_LINE(line, f, return -errno) {
- PresetRule rule = {};
- const char *parameter;
- char *l;
-
- l = strstrip(line);
- n++;
-
- if (isempty(l))
- continue;
- if (strchr(COMMENTS, *l))
- continue;
-
- parameter = first_word(l, "enable");
- if (parameter) {
- char *pattern;
-
- pattern = strdup(parameter);
- if (!pattern)
- return -ENOMEM;
-
- rule = (PresetRule) {
- .pattern = pattern,
- .action = PRESET_ENABLE,
- };
- }
-
- parameter = first_word(l, "disable");
- if (parameter) {
- char *pattern;
-
- pattern = strdup(parameter);
- if (!pattern)
- return -ENOMEM;
-
- rule = (PresetRule) {
- .pattern = pattern,
- .action = PRESET_DISABLE,
- };
- }
-
- if (rule.action) {
- if (!GREEDY_REALLOC(ps.rules, n_allocated, ps.n_rules + 1))
- return -ENOMEM;
-
- ps.rules[ps.n_rules++] = rule;
- continue;
- }
-
- log_syntax(NULL, LOG_WARNING, *p, n, 0, "Couldn't parse line '%s'. Ignoring.", line);
- }
- }
-
- *presets = ps;
- ps = (Presets){};
-
- return 0;
-}
-
-static int query_presets(const char *name, const Presets presets) {
- PresetAction action = PRESET_UNKNOWN;
- size_t i;
-
- if (!unit_name_is_valid(name, UNIT_NAME_ANY))
- return -EINVAL;
-
- for (i = 0; i < presets.n_rules; i++)
- if (fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) {
- action = presets.rules[i].action;
- break;
- }
-
- switch (action) {
- case PRESET_UNKNOWN:
- log_debug("Preset files don't specify rule for %s. Enabling.", name);
- return 1;
- case PRESET_ENABLE:
- log_debug("Preset files say enable %s.", name);
- return 1;
- case PRESET_DISABLE:
- log_debug("Preset files say disable %s.", name);
- return 0;
- default:
- assert_not_reached("invalid preset action");
- }
-}
-
-int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
- _cleanup_(presets_freep) Presets presets = {};
- int r;
-
- r = read_presets(scope, root_dir, &presets);
- if (r < 0)
- return r;
-
- return query_presets(name, presets);
-}
-
-static int execute_preset(
- UnitFileScope scope,
- InstallContext *plus,
- InstallContext *minus,
- const LookupPaths *paths,
- const char *config_path,
- char **files,
- UnitFilePresetMode mode,
- bool force,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- int r;
-
- assert(plus);
- assert(minus);
- assert(paths);
- assert(config_path);
-
- if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
- _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
-
- r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path);
- if (r < 0)
- return r;
-
- r = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
- } else
- r = 0;
-
- if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
- int q;
-
- /* Returns number of symlinks that where supposed to be installed. */
- q = install_context_apply(scope, plus, paths, config_path, force, SEARCH_LOAD, changes, n_changes);
- if (r >= 0) {
- if (q < 0)
- r = q;
- else
- r += q;
- }
- }
-
- return r;
-}
-
-static int preset_prepare_one(
- UnitFileScope scope,
- InstallContext *plus,
- InstallContext *minus,
- LookupPaths *paths,
- const char *name,
- Presets presets,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_(install_context_done) InstallContext tmp = {};
- UnitFileInstallInfo *i;
- int r;
-
- if (install_info_find(plus, name) || install_info_find(minus, name))
- return 0;
-
- r = install_info_discover(scope, &tmp, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS,
- &i, changes, n_changes);
- if (r < 0)
- return r;
- if (!streq(name, i->name)) {
- log_debug("Skipping %s because is an alias for %s", name, i->name);
- return 0;
- }
-
- r = query_presets(name, presets);
- if (r < 0)
- return r;
-
- if (r > 0) {
- r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS,
- &i, changes, n_changes);
- if (r < 0)
- return r;
-
- r = install_info_may_process(i, paths, changes, n_changes);
- if (r < 0)
- return r;
- } else
- r = install_info_discover(scope, minus, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS,
- &i, changes, n_changes);
-
- return r;
-}
-
-int unit_file_preset(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFilePresetMode mode,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_(presets_freep) Presets presets = {};
- const char *config_path;
- char **i;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(mode < _UNIT_FILE_PRESET_MAX);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
-
- r = read_presets(scope, root_dir, &presets);
- if (r < 0)
- return r;
-
- STRV_FOREACH(i, files) {
- r = preset_prepare_one(scope, &plus, &minus, &paths, *i, presets, changes, n_changes);
- if (r < 0)
- return r;
- }
-
- return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
-}
-
-int unit_file_preset_all(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- UnitFilePresetMode mode,
- UnitFileChange **changes,
- unsigned *n_changes) {
-
- _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- _cleanup_(presets_freep) Presets presets = {};
- const char *config_path = NULL;
- char **i;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(mode < _UNIT_FILE_PRESET_MAX);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
-
- r = read_presets(scope, root_dir, &presets);
- if (r < 0)
- return r;
-
- STRV_FOREACH(i, paths.search_path) {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
-
- d = opendir(*i);
- if (!d) {
- if (errno == ENOENT)
- continue;
-
- return -errno;
- }
-
- FOREACH_DIRENT(de, d, return -errno) {
-
- if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
- continue;
-
- dirent_ensure_type(d, de);
-
- if (!IN_SET(de->d_type, DT_LNK, DT_REG))
- continue;
-
- /* we don't pass changes[] in, because we want to handle errors on our own */
- r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, presets, NULL, 0);
- if (r == -ERFKILL)
- r = unit_file_changes_add(changes, n_changes,
- UNIT_FILE_IS_MASKED, de->d_name, NULL);
- else if (r == -ENOLINK)
- r = unit_file_changes_add(changes, n_changes,
- UNIT_FILE_IS_DANGLING, de->d_name, NULL);
- if (r < 0)
- return r;
- }
- }
-
- return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
-}
-
-static void unit_file_list_free_one(UnitFileList *f) {
- if (!f)
- return;
-
- free(f->path);
- free(f);
-}
-
-Hashmap* unit_file_list_free(Hashmap *h) {
- UnitFileList *i;
-
- while ((i = hashmap_steal_first(h)))
- unit_file_list_free_one(i);
-
- return hashmap_free(h);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
-
-int unit_file_get_list(
- UnitFileScope scope,
- const char *root_dir,
- Hashmap *h,
- char **states,
- char **patterns) {
-
- _cleanup_lookup_paths_free_ LookupPaths paths = {};
- char **i;
- int r;
-
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
- assert(h);
-
- r = lookup_paths_init(&paths, scope, 0, root_dir);
- if (r < 0)
- return r;
-
- STRV_FOREACH(i, paths.search_path) {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
-
- d = opendir(*i);
- if (!d) {
- if (errno == ENOENT)
- continue;
- if (IN_SET(errno, ENOTDIR, EACCES)) {
- log_debug("Failed to open \"%s\": %m", *i);
- continue;
- }
-
- return -errno;
- }
-
- FOREACH_DIRENT(de, d, return -errno) {
- _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
-
- if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
- continue;
-
- if (!strv_fnmatch_or_empty(patterns, de->d_name, FNM_NOESCAPE))
- continue;
-
- if (hashmap_get(h, de->d_name))
- continue;
-
- dirent_ensure_type(d, de);
-
- if (!IN_SET(de->d_type, DT_LNK, DT_REG))
- continue;
-
- f = new0(UnitFileList, 1);
- if (!f)
- return -ENOMEM;
-
- f->path = path_make_absolute(de->d_name, *i);
- if (!f->path)
- return -ENOMEM;
-
- r = unit_file_lookup_state(scope, &paths, de->d_name, &f->state);
- if (r < 0)
- f->state = UNIT_FILE_BAD;
-
- if (!strv_isempty(states) &&
- !strv_contains(states, unit_file_state_to_string(f->state)))
- continue;
-
- r = hashmap_put(h, basename(f->path), f);
- if (r < 0)
- return r;
-
- f = NULL; /* prevent cleanup */
- }
- }
-
- return 0;
-}
-
-static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
- [UNIT_FILE_ENABLED] = "enabled",
- [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
- [UNIT_FILE_LINKED] = "linked",
- [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
- [UNIT_FILE_MASKED] = "masked",
- [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
- [UNIT_FILE_STATIC] = "static",
- [UNIT_FILE_DISABLED] = "disabled",
- [UNIT_FILE_INDIRECT] = "indirect",
- [UNIT_FILE_GENERATED] = "generated",
- [UNIT_FILE_TRANSIENT] = "transient",
- [UNIT_FILE_BAD] = "bad",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
-
-static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
- [UNIT_FILE_SYMLINK] = "symlink",
- [UNIT_FILE_UNLINK] = "unlink",
- [UNIT_FILE_IS_MASKED] = "masked",
- [UNIT_FILE_IS_DANGLING] = "dangling",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
-
-static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
- [UNIT_FILE_PRESET_FULL] = "full",
- [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
- [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);
diff --git a/src/shared/install.h b/src/shared/install.h
deleted file mode 100644
index 7a5859e729..0000000000
--- a/src/shared/install.h
+++ /dev/null
@@ -1,256 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-typedef enum UnitFileScope UnitFileScope;
-typedef enum UnitFileState UnitFileState;
-typedef enum UnitFilePresetMode UnitFilePresetMode;
-typedef enum UnitFileChangeType UnitFileChangeType;
-typedef enum UnitFileFlags UnitFileFlags;
-typedef enum UnitFileType UnitFileType;
-typedef struct UnitFileChange UnitFileChange;
-typedef struct UnitFileList UnitFileList;
-typedef struct UnitFileInstallInfo UnitFileInstallInfo;
-
-#include <stdbool.h>
-
-#include "hashmap.h"
-#include "macro.h"
-#include "path-lookup.h"
-#include "strv.h"
-#include "unit-name.h"
-
-enum UnitFileScope {
- UNIT_FILE_SYSTEM,
- UNIT_FILE_GLOBAL,
- UNIT_FILE_USER,
- _UNIT_FILE_SCOPE_MAX,
- _UNIT_FILE_SCOPE_INVALID = -1
-};
-
-enum UnitFileState {
- UNIT_FILE_ENABLED,
- UNIT_FILE_ENABLED_RUNTIME,
- UNIT_FILE_LINKED,
- UNIT_FILE_LINKED_RUNTIME,
- UNIT_FILE_MASKED,
- UNIT_FILE_MASKED_RUNTIME,
- UNIT_FILE_STATIC,
- UNIT_FILE_DISABLED,
- UNIT_FILE_INDIRECT,
- UNIT_FILE_GENERATED,
- UNIT_FILE_TRANSIENT,
- UNIT_FILE_BAD,
- _UNIT_FILE_STATE_MAX,
- _UNIT_FILE_STATE_INVALID = -1
-};
-
-enum UnitFilePresetMode {
- UNIT_FILE_PRESET_FULL,
- UNIT_FILE_PRESET_ENABLE_ONLY,
- UNIT_FILE_PRESET_DISABLE_ONLY,
- _UNIT_FILE_PRESET_MAX,
- _UNIT_FILE_PRESET_INVALID = -1
-};
-
-enum UnitFileChangeType {
- UNIT_FILE_SYMLINK,
- UNIT_FILE_UNLINK,
- UNIT_FILE_IS_MASKED,
- UNIT_FILE_IS_DANGLING,
- _UNIT_FILE_CHANGE_TYPE_MAX,
- _UNIT_FILE_CHANGE_INVALID = INT_MIN
-};
-
-enum UnitFileFlags {
- UNIT_FILE_RUNTIME = 1,
- UNIT_FILE_FORCE = 1 << 1,
- UNIT_FILE_DRY_RUN = 1 << 2,
-};
-
-/* type can either one of the UnitFileChangeTypes listed above, or a negative error.
- * If source is specified, it should be the contents of the path symlink.
- * In case of an error, source should be the existing symlink contents or NULL
- */
-struct UnitFileChange {
- int type; /* UnitFileChangeType or bust */
- char *path;
- char *source;
-};
-
-static inline bool unit_file_changes_have_modification(const UnitFileChange* changes, unsigned n_changes) {
- unsigned i;
- for (i = 0; i < n_changes; i++)
- if (IN_SET(changes[i].type, UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK))
- return true;
- return false;
-}
-
-struct UnitFileList {
- char *path;
- UnitFileState state;
-};
-
-enum UnitFileType {
- UNIT_FILE_TYPE_REGULAR,
- UNIT_FILE_TYPE_SYMLINK,
- UNIT_FILE_TYPE_MASKED,
- _UNIT_FILE_TYPE_MAX,
- _UNIT_FILE_TYPE_INVALID = -1,
-};
-
-struct UnitFileInstallInfo {
- char *name;
- char *path;
-
- char **aliases;
- char **wanted_by;
- char **required_by;
- char **also;
-
- char *default_instance;
- char *symlink_target;
-
- UnitFileType type;
- bool auxiliary;
-};
-
-static inline bool UNIT_FILE_INSTALL_INFO_HAS_RULES(UnitFileInstallInfo *i) {
- assert(i);
-
- return !strv_isempty(i->aliases) ||
- !strv_isempty(i->wanted_by) ||
- !strv_isempty(i->required_by);
-}
-
-static inline bool UNIT_FILE_INSTALL_INFO_HAS_ALSO(UnitFileInstallInfo *i) {
- assert(i);
-
- return !strv_isempty(i->also);
-}
-
-bool unit_type_may_alias(UnitType type) _const_;
-bool unit_type_may_template(UnitType type) _const_;
-
-int unit_file_enable(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_disable(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_reenable(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_preset(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFilePresetMode mode,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_preset_all(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- UnitFilePresetMode mode,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_mask(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_unmask(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_link(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_revert(
- UnitFileScope scope,
- const char *root_dir,
- char **files,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_set_default(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- const char *file,
- UnitFileChange **changes,
- unsigned *n_changes);
-int unit_file_get_default(
- UnitFileScope scope,
- const char *root_dir,
- char **name);
-int unit_file_add_dependency(
- UnitFileScope scope,
- UnitFileFlags flags,
- const char *root_dir,
- char **files,
- const char *target,
- UnitDependency dep,
- UnitFileChange **changes,
- unsigned *n_changes);
-
-int unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename, UnitFileState *ret);
-int unit_file_exists(UnitFileScope scope, const LookupPaths *paths, const char *name);
-
-int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h, char **states, char **patterns);
-Hashmap* unit_file_list_free(Hashmap *h);
-
-int unit_file_changes_add(UnitFileChange **changes, unsigned *n_changes, UnitFileChangeType type, const char *path, const char *source);
-void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes);
-void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *changes, unsigned n_changes, bool quiet);
-
-int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name);
-
-const char *unit_file_state_to_string(UnitFileState s) _const_;
-UnitFileState unit_file_state_from_string(const char *s) _pure_;
-/* from_string conversion is unreliable because of the overlap between -EPERM and -1 for error. */
-
-const char *unit_file_change_type_to_string(UnitFileChangeType s) _const_;
-UnitFileChangeType unit_file_change_type_from_string(const char *s) _pure_;
-
-const char *unit_file_preset_mode_to_string(UnitFilePresetMode m) _const_;
-UnitFilePresetMode unit_file_preset_mode_from_string(const char *s) _pure_;
diff --git a/src/shared/linux/auto_dev-ioctl.h b/src/shared/linux/auto_dev-ioctl.h
deleted file mode 100644
index aeaeb3ea7a..0000000000
--- a/src/shared/linux/auto_dev-ioctl.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright 2008 Red Hat, Inc. All rights reserved.
- * Copyright 2008 Ian Kent <raven@themaw.net>
- *
- * This file is part of the Linux kernel and is made available under
- * the terms of the GNU General Public License, version 2, or at your
- * option, any later version, incorporated herein by reference.
- */
-
-#ifndef _LINUX_AUTO_DEV_IOCTL_H
-#define _LINUX_AUTO_DEV_IOCTL_H
-
-#include <linux/auto_fs.h>
-
-#ifdef __KERNEL__
-#include <linux/string.h>
-#else
-#include <string.h>
-#endif /* __KERNEL__ */
-
-#define AUTOFS_DEVICE_NAME "autofs"
-
-#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
-#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
-
-#define AUTOFS_DEVID_LEN 16
-
-#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl)
-
-/*
- * An ioctl interface for autofs mount point control.
- */
-
-struct args_protover {
- __u32 version;
-};
-
-struct args_protosubver {
- __u32 sub_version;
-};
-
-struct args_openmount {
- __u32 devid;
-};
-
-struct args_ready {
- __u32 token;
-};
-
-struct args_fail {
- __u32 token;
- __s32 status;
-};
-
-struct args_setpipefd {
- __s32 pipefd;
-};
-
-struct args_timeout {
- __u64 timeout;
-};
-
-struct args_requester {
- __u32 uid;
- __u32 gid;
-};
-
-struct args_expire {
- __u32 how;
-};
-
-struct args_askumount {
- __u32 may_umount;
-};
-
-struct args_ismountpoint {
- union {
- struct args_in {
- __u32 type;
- } in;
- struct args_out {
- __u32 devid;
- __u32 magic;
- } out;
- };
-};
-
-/*
- * All the ioctls use this structure.
- * When sending a path size must account for the total length
- * of the chunk of memory otherwise is is the size of the
- * structure.
- */
-
-struct autofs_dev_ioctl {
- __u32 ver_major;
- __u32 ver_minor;
- __u32 size; /* total size of data passed in
- * including this struct */
- __s32 ioctlfd; /* automount command fd */
-
- /* Command parameters */
-
- union {
- struct args_protover protover;
- struct args_protosubver protosubver;
- struct args_openmount openmount;
- struct args_ready ready;
- struct args_fail fail;
- struct args_setpipefd setpipefd;
- struct args_timeout timeout;
- struct args_requester requester;
- struct args_expire expire;
- struct args_askumount askumount;
- struct args_ismountpoint ismountpoint;
- };
-
- char path[0];
-};
-
-static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) {
- memset(in, 0, sizeof(struct autofs_dev_ioctl));
- in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
- in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
- in->size = sizeof(struct autofs_dev_ioctl);
- in->ioctlfd = -1;
- return;
-}
-
-/*
- * If you change this make sure you make the corresponding change
- * to autofs-dev-ioctl.c:lookup_ioctl()
- */
-enum {
- /* Get various version info */
- AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
- AUTOFS_DEV_IOCTL_PROTOVER_CMD,
- AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD,
-
- /* Open mount ioctl fd */
- AUTOFS_DEV_IOCTL_OPENMOUNT_CMD,
-
- /* Close mount ioctl fd */
- AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD,
-
- /* Mount/expire status returns */
- AUTOFS_DEV_IOCTL_READY_CMD,
- AUTOFS_DEV_IOCTL_FAIL_CMD,
-
- /* Activate/deactivate autofs mount */
- AUTOFS_DEV_IOCTL_SETPIPEFD_CMD,
- AUTOFS_DEV_IOCTL_CATATONIC_CMD,
-
- /* Expiry timeout */
- AUTOFS_DEV_IOCTL_TIMEOUT_CMD,
-
- /* Get mount last requesting uid and gid */
- AUTOFS_DEV_IOCTL_REQUESTER_CMD,
-
- /* Check for eligible expire candidates */
- AUTOFS_DEV_IOCTL_EXPIRE_CMD,
-
- /* Request busy status */
- AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD,
-
- /* Check if path is a mountpoint */
- AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
-};
-
-#define AUTOFS_IOCTL 0x93
-
-#define AUTOFS_DEV_IOCTL_VERSION \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_PROTOVER \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_PROTOSUBVER \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_OPENMOUNT \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_READY \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_FAIL \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_SETPIPEFD \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_CATATONIC \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_TIMEOUT \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_REQUESTER \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_EXPIRE \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_ASKUMOUNT \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl)
-
-#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \
- _IOWR(AUTOFS_IOCTL, \
- AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
-
-#endif /* _LINUX_AUTO_DEV_IOCTL_H */
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
deleted file mode 100644
index f9d9c4ed62..0000000000
--- a/src/shared/logs-show.c
+++ /dev/null
@@ -1,1351 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <syslog.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "sd-id128.h"
-#include "sd-journal.h"
-
-#include "alloc-util.h"
-#include "fd-util.h"
-#include "formats-util.h"
-#include "hashmap.h"
-#include "hostname-util.h"
-#include "io-util.h"
-#include "journal-internal.h"
-#include "log.h"
-#include "logs-show.h"
-#include "macro.h"
-#include "output-mode.h"
-#include "parse-util.h"
-#include "process-util.h"
-#include "sparse-endian.h"
-#include "stdio-util.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "terminal-util.h"
-#include "time-util.h"
-#include "utf8.h"
-#include "util.h"
-
-/* up to three lines (each up to 100 characters) or 300 characters, whichever is less */
-#define PRINT_LINE_THRESHOLD 3
-#define PRINT_CHAR_THRESHOLD 300
-
-#define JSON_THRESHOLD 4096
-
-static int print_catalog(FILE *f, sd_journal *j) {
- int r;
- _cleanup_free_ char *t = NULL, *z = NULL;
-
-
- r = sd_journal_get_catalog(j, &t);
- if (r < 0)
- return r;
-
- z = strreplace(strstrip(t), "\n", "\n-- ");
- if (!z)
- return log_oom();
-
- fputs("-- ", f);
- fputs(z, f);
- fputc('\n', f);
-
- return 0;
-}
-
-static int parse_field(const void *data, size_t length, const char *field, char **target, size_t *target_size) {
- size_t fl, nl;
- char *buf;
-
- assert(data);
- assert(field);
- assert(target);
-
- fl = strlen(field);
- if (length < fl)
- return 0;
-
- if (memcmp(data, field, fl))
- return 0;
-
- nl = length - fl;
- buf = new(char, nl+1);
- if (!buf)
- return log_oom();
-
- memcpy(buf, (const char*) data + fl, nl);
- buf[nl] = 0;
-
- free(*target);
- *target = buf;
-
- if (target_size)
- *target_size = nl;
-
- return 1;
-}
-
-static bool shall_print(const char *p, size_t l, OutputFlags flags) {
- assert(p);
-
- if (flags & OUTPUT_SHOW_ALL)
- return true;
-
- if (l >= PRINT_CHAR_THRESHOLD)
- return false;
-
- if (!utf8_is_printable(p, l))
- return false;
-
- return true;
-}
-
-static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, OutputFlags flags, int priority, const char* message, size_t message_len) {
- const char *color_on = "", *color_off = "";
- const char *pos, *end;
- bool ellipsized = false;
- int line = 0;
-
- if (flags & OUTPUT_COLOR) {
- if (priority <= LOG_ERR) {
- color_on = ANSI_HIGHLIGHT_RED;
- color_off = ANSI_NORMAL;
- } else if (priority <= LOG_NOTICE) {
- color_on = ANSI_HIGHLIGHT;
- color_off = ANSI_NORMAL;
- }
- }
-
- /* A special case: make sure that we print a newline when
- the message is empty. */
- if (message_len == 0)
- fputs("\n", f);
-
- for (pos = message;
- pos < message + message_len;
- pos = end + 1, line++) {
- bool continuation = line > 0;
- bool tail_line;
- int len;
- for (end = pos; end < message + message_len && *end != '\n'; end++)
- ;
- len = end - pos;
- assert(len >= 0);
-
- /* We need to figure out when we are showing not-last line, *and*
- * will skip subsequent lines. In that case, we will put the dots
- * at the end of the line, instead of putting dots in the middle
- * or not at all.
- */
- tail_line =
- line + 1 == PRINT_LINE_THRESHOLD ||
- end + 1 >= message + PRINT_CHAR_THRESHOLD;
-
- if (flags & (OUTPUT_FULL_WIDTH | OUTPUT_SHOW_ALL) ||
- (prefix + len + 1 < n_columns && !tail_line)) {
- fprintf(f, "%*s%s%.*s%s\n",
- continuation * prefix, "",
- color_on, len, pos, color_off);
- continue;
- }
-
- /* Beyond this point, ellipsization will happen. */
- ellipsized = true;
-
- if (prefix < n_columns && n_columns - prefix >= 3) {
- if (n_columns - prefix > (unsigned) len + 3)
- fprintf(f, "%*s%s%.*s...%s\n",
- continuation * prefix, "",
- color_on, len, pos, color_off);
- else {
- _cleanup_free_ char *e;
-
- e = ellipsize_mem(pos, len, n_columns - prefix,
- tail_line ? 100 : 90);
- if (!e)
- fprintf(f, "%*s%s%.*s%s\n",
- continuation * prefix, "",
- color_on, len, pos, color_off);
- else
- fprintf(f, "%*s%s%s%s\n",
- continuation * prefix, "",
- color_on, e, color_off);
- }
- } else
- fputs("...\n", f);
-
- if (tail_line)
- break;
- }
-
- return ellipsized;
-}
-
-static int output_timestamp_monotonic(FILE *f, sd_journal *j, const char *monotonic) {
- sd_id128_t boot_id;
- uint64_t t;
- int r;
-
- assert(f);
- assert(j);
-
- r = -ENXIO;
- if (monotonic)
- r = safe_atou64(monotonic, &t);
- if (r < 0)
- r = sd_journal_get_monotonic_usec(j, &t, &boot_id);
- if (r < 0)
- return log_error_errno(r, "Failed to get monotonic timestamp: %m");
-
- fprintf(f, "[%5llu.%06llu]",
- (unsigned long long) (t / USEC_PER_SEC),
- (unsigned long long) (t % USEC_PER_SEC));
-
- return 1 + 5 + 1 + 6 + 1;
-}
-
-static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, OutputFlags flags, const char *realtime) {
- char buf[MAX(FORMAT_TIMESTAMP_MAX, 64)];
- struct tm *(*gettime_r)(const time_t *, struct tm *);
- struct tm tm;
- uint64_t x;
- time_t t;
- int r;
-
- assert(f);
- assert(j);
-
- r = -ENXIO;
- if (realtime)
- r = safe_atou64(realtime, &x);
- if (r < 0)
- r = sd_journal_get_realtime_usec(j, &x);
- if (r < 0)
- return log_error_errno(r, "Failed to get realtime timestamp: %m");
-
- if (mode == OUTPUT_SHORT_FULL) {
- const char *k;
-
- if (flags & OUTPUT_UTC)
- k = format_timestamp_utc(buf, sizeof(buf), x);
- else
- k = format_timestamp(buf, sizeof(buf), x);
- if (!k) {
- log_error("Failed to format timestamp.");
- return -EINVAL;
- }
-
- } else {
- gettime_r = (flags & OUTPUT_UTC) ? gmtime_r : localtime_r;
- t = (time_t) (x / USEC_PER_SEC);
-
- switch (mode) {
-
- case OUTPUT_SHORT_UNIX:
- xsprintf(buf, "%10llu.%06llu", (unsigned long long) t, (unsigned long long) (x % USEC_PER_SEC));
- break;
-
- case OUTPUT_SHORT_ISO:
- if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", gettime_r(&t, &tm)) <= 0) {
- log_error("Failed for format ISO time");
- return -EINVAL;
- }
- break;
-
- case OUTPUT_SHORT:
- case OUTPUT_SHORT_PRECISE:
-
- if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", gettime_r(&t, &tm)) <= 0) {
- log_error("Failed to format syslog time");
- return -EINVAL;
- }
-
- if (mode == OUTPUT_SHORT_PRECISE) {
- size_t k;
-
- assert(sizeof(buf) > strlen(buf));
- k = sizeof(buf) - strlen(buf);
-
- r = snprintf(buf + strlen(buf), k, ".%06llu", (unsigned long long) (x % USEC_PER_SEC));
- if (r <= 0 || (size_t) r >= k) { /* too long? */
- log_error("Failed to format precise time");
- return -EINVAL;
- }
- }
- break;
-
- default:
- assert_not_reached("Unknown time format");
- }
- }
-
- fputs(buf, f);
- return (int) strlen(buf);
-}
-
-static int output_short(
- FILE *f,
- sd_journal *j,
- OutputMode mode,
- unsigned n_columns,
- OutputFlags flags) {
-
- int r;
- const void *data;
- size_t length;
- size_t n = 0;
- _cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL;
- size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0;
- int p = LOG_INFO;
- bool ellipsized = false;
-
- assert(f);
- assert(j);
-
- /* Set the threshold to one bigger than the actual print
- * threshold, so that if the line is actually longer than what
- * we're willing to print, ellipsization will occur. This way
- * we won't output a misleading line without any indication of
- * truncation.
- */
- sd_journal_set_data_threshold(j, flags & (OUTPUT_SHOW_ALL|OUTPUT_FULL_WIDTH) ? 0 : PRINT_CHAR_THRESHOLD + 1);
-
- JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
-
- r = parse_field(data, length, "PRIORITY=", &priority, &priority_len);
- if (r < 0)
- return r;
- else if (r > 0)
- continue;
-
- r = parse_field(data, length, "_HOSTNAME=", &hostname, &hostname_len);
- if (r < 0)
- return r;
- else if (r > 0)
- continue;
-
- r = parse_field(data, length, "SYSLOG_IDENTIFIER=", &identifier, &identifier_len);
- if (r < 0)
- return r;
- else if (r > 0)
- continue;
-
- r = parse_field(data, length, "_COMM=", &comm, &comm_len);
- if (r < 0)
- return r;
- else if (r > 0)
- continue;
-
- r = parse_field(data, length, "_PID=", &pid, &pid_len);
- if (r < 0)
- return r;
- else if (r > 0)
- continue;
-
- r = parse_field(data, length, "SYSLOG_PID=", &fake_pid, &fake_pid_len);
- if (r < 0)
- return r;
- else if (r > 0)
- continue;
-
- r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len);
- if (r < 0)
- return r;
- else if (r > 0)
- continue;
-
- r = parse_field(data, length, "_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len);
- if (r < 0)
- return r;
- else if (r > 0)
- continue;
-
- r = parse_field(data, length, "MESSAGE=", &message, &message_len);
- if (r < 0)
- return r;
- }
- if (r == -EBADMSG) {
- log_debug_errno(r, "Skipping message we can't read: %m");
- return 0;
- }
- if (r < 0)
- return log_error_errno(r, "Failed to get journal fields: %m");
-
- if (!message) {
- log_debug("Skipping message without MESSAGE= field.");
- return 0;
- }
-
- if (!(flags & OUTPUT_SHOW_ALL))
- strip_tab_ansi(&message, &message_len);
-
- if (priority_len == 1 && *priority >= '0' && *priority <= '7')
- p = *priority - '0';
-
- if (mode == OUTPUT_SHORT_MONOTONIC)
- r = output_timestamp_monotonic(f, j, monotonic);
- else
- r = output_timestamp_realtime(f, j, mode, flags, realtime);
- if (r < 0)
- return r;
- n += r;
-
- if (flags & OUTPUT_NO_HOSTNAME) {
- /* Suppress display of the hostname if this is requested. */
- hostname = NULL;
- hostname_len = 0;
- }
-
- if (hostname && shall_print(hostname, hostname_len, flags)) {
- fprintf(f, " %.*s", (int) hostname_len, hostname);
- n += hostname_len + 1;
- }
-
- if (identifier && shall_print(identifier, identifier_len, flags)) {
- fprintf(f, " %.*s", (int) identifier_len, identifier);
- n += identifier_len + 1;
- } else if (comm && shall_print(comm, comm_len, flags)) {
- fprintf(f, " %.*s", (int) comm_len, comm);
- n += comm_len + 1;
- } else
- fputs(" unknown", f);
-
- if (pid && shall_print(pid, pid_len, flags)) {
- fprintf(f, "[%.*s]", (int) pid_len, pid);
- n += pid_len + 2;
- } else if (fake_pid && shall_print(fake_pid, fake_pid_len, flags)) {
- fprintf(f, "[%.*s]", (int) fake_pid_len, fake_pid);
- n += fake_pid_len + 2;
- }
-
- if (!(flags & OUTPUT_SHOW_ALL) && !utf8_is_printable(message, message_len)) {
- char bytes[FORMAT_BYTES_MAX];
- fprintf(f, ": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
- } else {
- fputs(": ", f);
- ellipsized |=
- print_multiline(f, n + 2, n_columns, flags, p, message, message_len);
- }
-
- if (flags & OUTPUT_CATALOG)
- print_catalog(f, j);
-
- return ellipsized;
-}
-
-static int output_verbose(
- FILE *f,
- sd_journal *j,
- OutputMode mode,
- unsigned n_columns,
- OutputFlags flags) {
-
- const void *data;
- size_t length;
- _cleanup_free_ char *cursor = NULL;
- uint64_t realtime = 0;
- char ts[FORMAT_TIMESTAMP_MAX + 7];
- int r;
-
- assert(f);
- assert(j);
-
- sd_journal_set_data_threshold(j, 0);
-
- r = sd_journal_get_data(j, "_SOURCE_REALTIME_TIMESTAMP", &data, &length);
- if (r == -ENOENT)
- log_debug("Source realtime timestamp not found");
- else if (r < 0)
- return log_full_errno(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_ERR, r, "Failed to get source realtime timestamp: %m");
- else {
- _cleanup_free_ char *value = NULL;
-
- r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=", &value, NULL);
- if (r < 0)
- return r;
- assert(r > 0);
-
- r = safe_atou64(value, &realtime);
- if (r < 0)
- log_debug_errno(r, "Failed to parse realtime timestamp: %m");
- }
-
- if (r < 0) {
- r = sd_journal_get_realtime_usec(j, &realtime);
- if (r < 0)
- return log_full_errno(r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_ERR, r, "Failed to get realtime timestamp: %m");
- }
-
- r = sd_journal_get_cursor(j, &cursor);
- if (r < 0)
- return log_error_errno(r, "Failed to get cursor: %m");
-
- fprintf(f, "%s [%s]\n",
- flags & OUTPUT_UTC ?
- format_timestamp_us_utc(ts, sizeof(ts), realtime) :
- format_timestamp_us(ts, sizeof(ts), realtime),
- cursor);
-
- JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
- const char *c;
- int fieldlen;
- const char *on = "", *off = "";
-
- c = memchr(data, '=', length);
- if (!c) {
- log_error("Invalid field.");
- return -EINVAL;
- }
- fieldlen = c - (const char*) data;
-
- if (flags & OUTPUT_COLOR && startswith(data, "MESSAGE=")) {
- on = ANSI_HIGHLIGHT;
- off = ANSI_NORMAL;
- }
-
- if ((flags & OUTPUT_SHOW_ALL) ||
- (((length < PRINT_CHAR_THRESHOLD) || flags & OUTPUT_FULL_WIDTH)
- && utf8_is_printable(data, length))) {
- fprintf(f, " %s%.*s=", on, fieldlen, (const char*)data);
- print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, c + 1, length - fieldlen - 1);
- fputs(off, f);
- } else {
- char bytes[FORMAT_BYTES_MAX];
-
- fprintf(f, " %s%.*s=[%s blob data]%s\n",
- on,
- (int) (c - (const char*) data),
- (const char*) data,
- format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1),
- off);
- }
- }
-
- if (r < 0)
- return r;
-
- if (flags & OUTPUT_CATALOG)
- print_catalog(f, j);
-
- return 0;
-}
-
-static int output_export(
- FILE *f,
- sd_journal *j,
- OutputMode mode,
- unsigned n_columns,
- OutputFlags flags) {
-
- sd_id128_t boot_id;
- char sid[33];
- int r;
- usec_t realtime, monotonic;
- _cleanup_free_ char *cursor = NULL;
- const void *data;
- size_t length;
-
- assert(j);
-
- sd_journal_set_data_threshold(j, 0);
-
- r = sd_journal_get_realtime_usec(j, &realtime);
- if (r < 0)
- return log_error_errno(r, "Failed to get realtime timestamp: %m");
-
- r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
- if (r < 0)
- return log_error_errno(r, "Failed to get monotonic timestamp: %m");
-
- r = sd_journal_get_cursor(j, &cursor);
- if (r < 0)
- return log_error_errno(r, "Failed to get cursor: %m");
-
- fprintf(f,
- "__CURSOR=%s\n"
- "__REALTIME_TIMESTAMP="USEC_FMT"\n"
- "__MONOTONIC_TIMESTAMP="USEC_FMT"\n"
- "_BOOT_ID=%s\n",
- cursor,
- realtime,
- monotonic,
- sd_id128_to_string(boot_id, sid));
-
- JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
-
- /* We already printed the boot id, from the data in
- * the header, hence let's suppress it here */
- if (length >= 9 &&
- startswith(data, "_BOOT_ID="))
- continue;
-
- if (utf8_is_printable_newline(data, length, false))
- fwrite(data, length, 1, f);
- else {
- const char *c;
- uint64_t le64;
-
- c = memchr(data, '=', length);
- if (!c) {
- log_error("Invalid field.");
- return -EINVAL;
- }
-
- fwrite(data, c - (const char*) data, 1, f);
- fputc('\n', f);
- le64 = htole64(length - (c - (const char*) data) - 1);
- fwrite(&le64, sizeof(le64), 1, f);
- fwrite(c + 1, length - (c - (const char*) data) - 1, 1, f);
- }
-
- fputc('\n', f);
- }
-
- if (r < 0)
- return r;
-
- fputc('\n', f);
-
- return 0;
-}
-
-void json_escape(
- FILE *f,
- const char* p,
- size_t l,
- OutputFlags flags) {
-
- assert(f);
- assert(p);
-
- if (!(flags & OUTPUT_SHOW_ALL) && l >= JSON_THRESHOLD)
- fputs("null", f);
-
- else if (!(flags & OUTPUT_SHOW_ALL) && !utf8_is_printable(p, l)) {
- bool not_first = false;
-
- fputs("[ ", f);
-
- while (l > 0) {
- if (not_first)
- fprintf(f, ", %u", (uint8_t) *p);
- else {
- not_first = true;
- fprintf(f, "%u", (uint8_t) *p);
- }
-
- p++;
- l--;
- }
-
- fputs(" ]", f);
- } else {
- fputc('\"', f);
-
- while (l > 0) {
- if (*p == '"' || *p == '\\') {
- fputc('\\', f);
- fputc(*p, f);
- } else if (*p == '\n')
- fputs("\\n", f);
- else if ((uint8_t) *p < ' ')
- fprintf(f, "\\u%04x", (uint8_t) *p);
- else
- fputc(*p, f);
-
- p++;
- l--;
- }
-
- fputc('\"', f);
- }
-}
-
-static int output_json(
- FILE *f,
- sd_journal *j,
- OutputMode mode,
- unsigned n_columns,
- OutputFlags flags) {
-
- uint64_t realtime, monotonic;
- _cleanup_free_ char *cursor = NULL;
- const void *data;
- size_t length;
- sd_id128_t boot_id;
- char sid[33], *k;
- int r;
- Hashmap *h = NULL;
- bool done, separator;
-
- assert(j);
-
- sd_journal_set_data_threshold(j, flags & OUTPUT_SHOW_ALL ? 0 : JSON_THRESHOLD);
-
- r = sd_journal_get_realtime_usec(j, &realtime);
- if (r < 0)
- return log_error_errno(r, "Failed to get realtime timestamp: %m");
-
- r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
- if (r < 0)
- return log_error_errno(r, "Failed to get monotonic timestamp: %m");
-
- r = sd_journal_get_cursor(j, &cursor);
- if (r < 0)
- return log_error_errno(r, "Failed to get cursor: %m");
-
- if (mode == OUTPUT_JSON_PRETTY)
- fprintf(f,
- "{\n"
- "\t\"__CURSOR\" : \"%s\",\n"
- "\t\"__REALTIME_TIMESTAMP\" : \""USEC_FMT"\",\n"
- "\t\"__MONOTONIC_TIMESTAMP\" : \""USEC_FMT"\",\n"
- "\t\"_BOOT_ID\" : \"%s\"",
- cursor,
- realtime,
- monotonic,
- sd_id128_to_string(boot_id, sid));
- else {
- if (mode == OUTPUT_JSON_SSE)
- fputs("data: ", f);
-
- fprintf(f,
- "{ \"__CURSOR\" : \"%s\", "
- "\"__REALTIME_TIMESTAMP\" : \""USEC_FMT"\", "
- "\"__MONOTONIC_TIMESTAMP\" : \""USEC_FMT"\", "
- "\"_BOOT_ID\" : \"%s\"",
- cursor,
- realtime,
- monotonic,
- sd_id128_to_string(boot_id, sid));
- }
-
- h = hashmap_new(&string_hash_ops);
- if (!h)
- return log_oom();
-
- /* First round, iterate through the entry and count how often each field appears */
- JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
- const char *eq;
- char *n;
- unsigned u;
-
- if (length >= 9 &&
- memcmp(data, "_BOOT_ID=", 9) == 0)
- continue;
-
- eq = memchr(data, '=', length);
- if (!eq)
- continue;
-
- n = strndup(data, eq - (const char*) data);
- if (!n) {
- r = log_oom();
- goto finish;
- }
-
- u = PTR_TO_UINT(hashmap_get(h, n));
- if (u == 0) {
- r = hashmap_put(h, n, UINT_TO_PTR(1));
- if (r < 0) {
- free(n);
- log_oom();
- goto finish;
- }
- } else {
- r = hashmap_update(h, n, UINT_TO_PTR(u + 1));
- free(n);
- if (r < 0) {
- log_oom();
- goto finish;
- }
- }
- }
-
- if (r < 0)
- return r;
-
- separator = true;
- do {
- done = true;
-
- SD_JOURNAL_FOREACH_DATA(j, data, length) {
- const char *eq;
- char *kk, *n;
- size_t m;
- unsigned u;
-
- /* We already printed the boot id, from the data in
- * the header, hence let's suppress it here */
- if (length >= 9 &&
- memcmp(data, "_BOOT_ID=", 9) == 0)
- continue;
-
- eq = memchr(data, '=', length);
- if (!eq)
- continue;
-
- if (separator) {
- if (mode == OUTPUT_JSON_PRETTY)
- fputs(",\n\t", f);
- else
- fputs(", ", f);
- }
-
- m = eq - (const char*) data;
-
- n = strndup(data, m);
- if (!n) {
- r = log_oom();
- goto finish;
- }
-
- u = PTR_TO_UINT(hashmap_get2(h, n, (void**) &kk));
- if (u == 0) {
- /* We already printed this, let's jump to the next */
- free(n);
- separator = false;
-
- continue;
- } else if (u == 1) {
- /* Field only appears once, output it directly */
-
- json_escape(f, data, m, flags);
- fputs(" : ", f);
-
- json_escape(f, eq + 1, length - m - 1, flags);
-
- hashmap_remove(h, n);
- free(kk);
- free(n);
-
- separator = true;
-
- continue;
-
- } else {
- /* Field appears multiple times, output it as array */
- json_escape(f, data, m, flags);
- fputs(" : [ ", f);
- json_escape(f, eq + 1, length - m - 1, flags);
-
- /* Iterate through the end of the list */
-
- while (sd_journal_enumerate_data(j, &data, &length) > 0) {
- if (length < m + 1)
- continue;
-
- if (memcmp(data, n, m) != 0)
- continue;
-
- if (((const char*) data)[m] != '=')
- continue;
-
- fputs(", ", f);
- json_escape(f, (const char*) data + m + 1, length - m - 1, flags);
- }
-
- fputs(" ]", f);
-
- hashmap_remove(h, n);
- free(kk);
- free(n);
-
- /* Iterate data fields form the beginning */
- done = false;
- separator = true;
-
- break;
- }
- }
-
- } while (!done);
-
- if (mode == OUTPUT_JSON_PRETTY)
- fputs("\n}\n", f);
- else if (mode == OUTPUT_JSON_SSE)
- fputs("}\n\n", f);
- else
- fputs(" }\n", f);
-
- r = 0;
-
-finish:
- while ((k = hashmap_steal_first_key(h)))
- free(k);
-
- hashmap_free(h);
-
- return r;
-}
-
-static int output_cat(
- FILE *f,
- sd_journal *j,
- OutputMode mode,
- unsigned n_columns,
- OutputFlags flags) {
-
- const void *data;
- size_t l;
- int r;
-
- assert(j);
- assert(f);
-
- sd_journal_set_data_threshold(j, 0);
-
- r = sd_journal_get_data(j, "MESSAGE", &data, &l);
- if (r < 0) {
- /* An entry without MESSAGE=? */
- if (r == -ENOENT)
- return 0;
-
- return log_error_errno(r, "Failed to get data: %m");
- }
-
- assert(l >= 8);
-
- fwrite((const char*) data + 8, 1, l - 8, f);
- fputc('\n', f);
-
- return 0;
-}
-
-static int (*output_funcs[_OUTPUT_MODE_MAX])(
- FILE *f,
- sd_journal*j,
- OutputMode mode,
- unsigned n_columns,
- OutputFlags flags) = {
-
- [OUTPUT_SHORT] = output_short,
- [OUTPUT_SHORT_ISO] = output_short,
- [OUTPUT_SHORT_PRECISE] = output_short,
- [OUTPUT_SHORT_MONOTONIC] = output_short,
- [OUTPUT_SHORT_UNIX] = output_short,
- [OUTPUT_SHORT_FULL] = output_short,
- [OUTPUT_VERBOSE] = output_verbose,
- [OUTPUT_EXPORT] = output_export,
- [OUTPUT_JSON] = output_json,
- [OUTPUT_JSON_PRETTY] = output_json,
- [OUTPUT_JSON_SSE] = output_json,
- [OUTPUT_CAT] = output_cat
-};
-
-int output_journal(
- FILE *f,
- sd_journal *j,
- OutputMode mode,
- unsigned n_columns,
- OutputFlags flags,
- bool *ellipsized) {
-
- int ret;
- assert(mode >= 0);
- assert(mode < _OUTPUT_MODE_MAX);
-
- if (n_columns <= 0)
- n_columns = columns();
-
- ret = output_funcs[mode](f, j, mode, n_columns, flags);
- fflush(stdout);
-
- if (ellipsized && ret > 0)
- *ellipsized = true;
-
- return ret;
-}
-
-static int maybe_print_begin_newline(FILE *f, OutputFlags *flags) {
- assert(f);
- assert(flags);
-
- if (!(*flags & OUTPUT_BEGIN_NEWLINE))
- return 0;
-
- /* Print a beginning new line if that's request, but only once
- * on the first line we print. */
-
- fputc('\n', f);
- *flags &= ~OUTPUT_BEGIN_NEWLINE;
- return 0;
-}
-
-static int show_journal(FILE *f,
- sd_journal *j,
- OutputMode mode,
- unsigned n_columns,
- usec_t not_before,
- unsigned how_many,
- OutputFlags flags,
- bool *ellipsized) {
-
- int r;
- unsigned line = 0;
- bool need_seek = false;
- int warn_cutoff = flags & OUTPUT_WARN_CUTOFF;
-
- assert(j);
- assert(mode >= 0);
- assert(mode < _OUTPUT_MODE_MAX);
-
- /* Seek to end */
- r = sd_journal_seek_tail(j);
- if (r < 0)
- return log_error_errno(r, "Failed to seek to tail: %m");
-
- r = sd_journal_previous_skip(j, how_many);
- if (r < 0)
- return log_error_errno(r, "Failed to skip previous: %m");
-
- for (;;) {
- for (;;) {
- usec_t usec;
-
- if (need_seek) {
- r = sd_journal_next(j);
- if (r < 0)
- return log_error_errno(r, "Failed to iterate through journal: %m");
- }
-
- if (r == 0)
- break;
-
- need_seek = true;
-
- if (not_before > 0) {
- r = sd_journal_get_monotonic_usec(j, &usec, NULL);
-
- /* -ESTALE is returned if the
- timestamp is not from this boot */
- if (r == -ESTALE)
- continue;
- else if (r < 0)
- return log_error_errno(r, "Failed to get journal time: %m");
-
- if (usec < not_before)
- continue;
- }
-
- line++;
- maybe_print_begin_newline(f, &flags);
-
- r = output_journal(f, j, mode, n_columns, flags, ellipsized);
- if (r < 0)
- return r;
- }
-
- if (warn_cutoff && line < how_many && not_before > 0) {
- sd_id128_t boot_id;
- usec_t cutoff = 0;
-
- /* Check whether the cutoff line is too early */
-
- r = sd_id128_get_boot(&boot_id);
- if (r < 0)
- return log_error_errno(r, "Failed to get boot id: %m");
-
- r = sd_journal_get_cutoff_monotonic_usec(j, boot_id, &cutoff, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to get journal cutoff time: %m");
-
- if (r > 0 && not_before < cutoff) {
- maybe_print_begin_newline(f, &flags);
- fprintf(f, "Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.\n");
- }
-
- warn_cutoff = false;
- }
-
- if (!(flags & OUTPUT_FOLLOW))
- break;
-
- r = sd_journal_wait(j, USEC_INFINITY);
- if (r < 0)
- return log_error_errno(r, "Failed to wait for journal: %m");
-
- }
-
- return 0;
-}
-
-int add_matches_for_unit(sd_journal *j, const char *unit) {
- const char *m1, *m2, *m3, *m4;
- int r;
-
- assert(j);
- assert(unit);
-
- m1 = strjoina("_SYSTEMD_UNIT=", unit);
- m2 = strjoina("COREDUMP_UNIT=", unit);
- m3 = strjoina("UNIT=", unit);
- m4 = strjoina("OBJECT_SYSTEMD_UNIT=", unit);
-
- (void)(
- /* Look for messages from the service itself */
- (r = sd_journal_add_match(j, m1, 0)) ||
-
- /* Look for coredumps of the service */
- (r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1", 0)) ||
- (r = sd_journal_add_match(j, "_UID=0", 0)) ||
- (r = sd_journal_add_match(j, m2, 0)) ||
-
- /* Look for messages from PID 1 about this service */
- (r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, "_PID=1", 0)) ||
- (r = sd_journal_add_match(j, m3, 0)) ||
-
- /* Look for messages from authorized daemons about this service */
- (r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, "_UID=0", 0)) ||
- (r = sd_journal_add_match(j, m4, 0))
- );
-
- if (r == 0 && endswith(unit, ".slice")) {
- const char *m5;
-
- m5 = strjoina("_SYSTEMD_SLICE=", unit);
-
- /* Show all messages belonging to a slice */
- (void)(
- (r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, m5, 0))
- );
- }
-
- return r;
-}
-
-int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) {
- int r;
- char *m1, *m2, *m3, *m4;
- char muid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)];
-
- assert(j);
- assert(unit);
-
- m1 = strjoina("_SYSTEMD_USER_UNIT=", unit);
- m2 = strjoina("USER_UNIT=", unit);
- m3 = strjoina("COREDUMP_USER_UNIT=", unit);
- m4 = strjoina("OBJECT_SYSTEMD_USER_UNIT=", unit);
- sprintf(muid, "_UID="UID_FMT, uid);
-
- (void) (
- /* Look for messages from the user service itself */
- (r = sd_journal_add_match(j, m1, 0)) ||
- (r = sd_journal_add_match(j, muid, 0)) ||
-
- /* Look for messages from systemd about this service */
- (r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, m2, 0)) ||
- (r = sd_journal_add_match(j, muid, 0)) ||
-
- /* Look for coredumps of the service */
- (r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, m3, 0)) ||
- (r = sd_journal_add_match(j, muid, 0)) ||
- (r = sd_journal_add_match(j, "_UID=0", 0)) ||
-
- /* Look for messages from authorized daemons about this service */
- (r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, m4, 0)) ||
- (r = sd_journal_add_match(j, muid, 0)) ||
- (r = sd_journal_add_match(j, "_UID=0", 0))
- );
-
- if (r == 0 && endswith(unit, ".slice")) {
- const char *m5;
-
- m5 = strjoina("_SYSTEMD_SLICE=", unit);
-
- /* Show all messages belonging to a slice */
- (void)(
- (r = sd_journal_add_disjunction(j)) ||
- (r = sd_journal_add_match(j, m5, 0)) ||
- (r = sd_journal_add_match(j, muid, 0))
- );
- }
-
- return r;
-}
-
-static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
- _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
- pid_t pid, child;
- siginfo_t si;
- char buf[37];
- ssize_t k;
- int r;
-
- assert(machine);
- assert(boot_id);
-
- if (!machine_name_is_valid(machine))
- return -EINVAL;
-
- r = container_get_leader(machine, &pid);
- if (r < 0)
- return r;
-
- r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, NULL, &rootfd);
- if (r < 0)
- return r;
-
- if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
- return -errno;
-
- child = fork();
- if (child < 0)
- return -errno;
-
- if (child == 0) {
- int fd;
-
- pair[0] = safe_close(pair[0]);
-
- r = namespace_enter(pidnsfd, mntnsfd, -1, -1, rootfd);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
- fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
- if (fd < 0)
- _exit(EXIT_FAILURE);
-
- r = loop_read_exact(fd, buf, 36, false);
- safe_close(fd);
- if (r < 0)
- _exit(EXIT_FAILURE);
-
- k = send(pair[1], buf, 36, MSG_NOSIGNAL);
- if (k != 36)
- _exit(EXIT_FAILURE);
-
- _exit(EXIT_SUCCESS);
- }
-
- pair[1] = safe_close(pair[1]);
-
- r = wait_for_terminate(child, &si);
- if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
- return r < 0 ? r : -EIO;
-
- k = recv(pair[0], buf, 36, 0);
- if (k != 36)
- return -EIO;
-
- buf[36] = 0;
- r = sd_id128_from_string(buf, boot_id);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-int add_match_this_boot(sd_journal *j, const char *machine) {
- char match[9+32+1] = "_BOOT_ID=";
- sd_id128_t boot_id;
- int r;
-
- assert(j);
-
- if (machine) {
- r = get_boot_id_for_machine(machine, &boot_id);
- if (r < 0)
- return log_error_errno(r, "Failed to get boot id of container %s: %m", machine);
- } else {
- r = sd_id128_get_boot(&boot_id);
- if (r < 0)
- return log_error_errno(r, "Failed to get boot id: %m");
- }
-
- sd_id128_to_string(boot_id, match + 9);
- r = sd_journal_add_match(j, match, strlen(match));
- if (r < 0)
- return log_error_errno(r, "Failed to add match: %m");
-
- r = sd_journal_add_conjunction(j);
- if (r < 0)
- return log_error_errno(r, "Failed to add conjunction: %m");
-
- return 0;
-}
-
-int show_journal_by_unit(
- FILE *f,
- const char *unit,
- OutputMode mode,
- unsigned n_columns,
- usec_t not_before,
- unsigned how_many,
- uid_t uid,
- OutputFlags flags,
- int journal_open_flags,
- bool system_unit,
- bool *ellipsized) {
-
- _cleanup_(sd_journal_closep) sd_journal *j = NULL;
- int r;
-
- assert(mode >= 0);
- assert(mode < _OUTPUT_MODE_MAX);
- assert(unit);
-
- if (how_many <= 0)
- return 0;
-
- r = sd_journal_open(&j, journal_open_flags);
- if (r < 0)
- return log_error_errno(r, "Failed to open journal: %m");
-
- r = add_match_this_boot(j, NULL);
- if (r < 0)
- return r;
-
- if (system_unit)
- r = add_matches_for_unit(j, unit);
- else
- r = add_matches_for_user_unit(j, unit, uid);
- if (r < 0)
- return log_error_errno(r, "Failed to add unit matches: %m");
-
- if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
- _cleanup_free_ char *filter;
-
- filter = journal_make_match_string(j);
- if (!filter)
- return log_oom();
-
- log_debug("Journal filter: %s", filter);
- }
-
- return show_journal(f, j, mode, n_columns, not_before, how_many, flags, ellipsized);
-}
diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h
deleted file mode 100644
index 6643440881..0000000000
--- a/src/shared/logs-show.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "sd-journal.h"
-
-#include "macro.h"
-#include "output-mode.h"
-#include "time-util.h"
-#include "util.h"
-
-int output_journal(
- FILE *f,
- sd_journal *j,
- OutputMode mode,
- unsigned n_columns,
- OutputFlags flags,
- bool *ellipsized);
-
-int add_match_this_boot(sd_journal *j, const char *machine);
-
-int add_matches_for_unit(
- sd_journal *j,
- const char *unit);
-
-int add_matches_for_user_unit(
- sd_journal *j,
- const char *unit,
- uid_t uid);
-
-int show_journal_by_unit(
- FILE *f,
- const char *unit,
- OutputMode mode,
- unsigned n_columns,
- usec_t not_before,
- unsigned how_many,
- uid_t uid,
- OutputFlags flags,
- int journal_open_flags,
- bool system_unit,
- bool *ellipsized);
-
-void json_escape(
- FILE *f,
- const char* p,
- size_t l,
- OutputFlags flags);
diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c
deleted file mode 100644
index 060f8d50c7..0000000000
--- a/src/shared/machine-image.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <linux/fs.h>
-#include "alloc-util.h"
-#include "btrfs-util.h"
-#include "chattr-util.h"
-#include "copy.h"
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "fs-util.h"
-#include "hashmap.h"
-#include "lockfile-util.h"
-#include "log.h"
-#include "macro.h"
-#include "machine-image.h"
-#include "mkdir.h"
-#include "path-util.h"
-#include "rm-rf.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "strv.h"
-#include "time-util.h"
-#include "utf8.h"
-#include "util.h"
-#include "xattr-util.h"
-
-static const char image_search_path[] =
- "/var/lib/machines\0"
- "/var/lib/container\0" /* legacy */
- "/usr/local/lib/machines\0"
- "/usr/lib/machines\0";
-
-Image *image_unref(Image *i) {
- if (!i)
- return NULL;
-
- free(i->name);
- free(i->path);
- return mfree(i);
-}
-
-static char **image_settings_path(Image *image) {
- _cleanup_strv_free_ char **l = NULL;
- char **ret;
- const char *fn, *s;
- unsigned i = 0;
-
- assert(image);
-
- l = new0(char*, 4);
- if (!l)
- return NULL;
-
- fn = strjoina(image->name, ".nspawn");
-
- FOREACH_STRING(s, "/etc/systemd/nspawn/", "/run/systemd/nspawn/") {
- l[i] = strappend(s, fn);
- if (!l[i])
- return NULL;
-
- i++;
- }
-
- l[i] = file_in_same_dir(image->path, fn);
- if (!l[i])
- return NULL;
-
- ret = l;
- l = NULL;
-
- return ret;
-}
-
-static int image_new(
- ImageType t,
- const char *pretty,
- const char *path,
- const char *filename,
- bool read_only,
- usec_t crtime,
- usec_t mtime,
- Image **ret) {
-
- _cleanup_(image_unrefp) Image *i = NULL;
-
- assert(t >= 0);
- assert(t < _IMAGE_TYPE_MAX);
- assert(pretty);
- assert(filename);
- assert(ret);
-
- i = new0(Image, 1);
- if (!i)
- return -ENOMEM;
-
- i->type = t;
- i->read_only = read_only;
- i->crtime = crtime;
- i->mtime = mtime;
- i->usage = i->usage_exclusive = (uint64_t) -1;
- i->limit = i->limit_exclusive = (uint64_t) -1;
-
- i->name = strdup(pretty);
- if (!i->name)
- return -ENOMEM;
-
- if (path)
- i->path = strjoin(path, "/", filename, NULL);
- else
- i->path = strdup(filename);
-
- if (!i->path)
- return -ENOMEM;
-
- path_kill_slashes(i->path);
-
- *ret = i;
- i = NULL;
-
- return 0;
-}
-
-static int image_make(
- const char *pretty,
- int dfd,
- const char *path,
- const char *filename,
- Image **ret) {
-
- struct stat st;
- bool read_only;
- int r;
-
- assert(filename);
-
- /* We explicitly *do* follow symlinks here, since we want to
- * allow symlinking trees into /var/lib/machines/, and treat
- * them normally. */
-
- if (fstatat(dfd, filename, &st, 0) < 0)
- return -errno;
-
- read_only =
- (path && path_startswith(path, "/usr")) ||
- (faccessat(dfd, filename, W_OK, AT_EACCESS) < 0 && errno == EROFS);
-
- if (S_ISDIR(st.st_mode)) {
- _cleanup_close_ int fd = -1;
- unsigned file_attr = 0;
-
- if (!ret)
- return 1;
-
- if (!pretty)
- pretty = filename;
-
- fd = openat(dfd, filename, O_CLOEXEC|O_NOCTTY|O_DIRECTORY);
- if (fd < 0)
- return -errno;
-
- /* btrfs subvolumes have inode 256 */
- if (st.st_ino == 256) {
-
- r = btrfs_is_filesystem(fd);
- if (r < 0)
- return r;
- if (r) {
- BtrfsSubvolInfo info;
-
- /* It's a btrfs subvolume */
-
- r = btrfs_subvol_get_info_fd(fd, 0, &info);
- if (r < 0)
- return r;
-
- r = image_new(IMAGE_SUBVOLUME,
- pretty,
- path,
- filename,
- info.read_only || read_only,
- info.otime,
- 0,
- ret);
- if (r < 0)
- return r;
-
- if (btrfs_quota_scan_ongoing(fd) == 0) {
- BtrfsQuotaInfo quota;
-
- r = btrfs_subvol_get_subtree_quota_fd(fd, 0, &quota);
- if (r >= 0) {
- (*ret)->usage = quota.referenced;
- (*ret)->usage_exclusive = quota.exclusive;
-
- (*ret)->limit = quota.referenced_max;
- (*ret)->limit_exclusive = quota.exclusive_max;
- }
- }
-
- return 1;
- }
- }
-
- /* If the IMMUTABLE bit is set, we consider the
- * directory read-only. Since the ioctl is not
- * supported everywhere we ignore failures. */
- (void) read_attr_fd(fd, &file_attr);
-
- /* It's just a normal directory. */
- r = image_new(IMAGE_DIRECTORY,
- pretty,
- path,
- filename,
- read_only || (file_attr & FS_IMMUTABLE_FL),
- 0,
- 0,
- ret);
- if (r < 0)
- return r;
-
- return 1;
-
- } else if (S_ISREG(st.st_mode) && endswith(filename, ".raw")) {
- usec_t crtime = 0;
-
- /* It's a RAW disk image */
-
- if (!ret)
- return 1;
-
- fd_getcrtime_at(dfd, filename, &crtime, 0);
-
- if (!pretty)
- pretty = strndupa(filename, strlen(filename) - 4);
-
- r = image_new(IMAGE_RAW,
- pretty,
- path,
- filename,
- !(st.st_mode & 0222) || read_only,
- crtime,
- timespec_load(&st.st_mtim),
- ret);
- if (r < 0)
- return r;
-
- (*ret)->usage = (*ret)->usage_exclusive = st.st_blocks * 512;
- (*ret)->limit = (*ret)->limit_exclusive = st.st_size;
-
- return 1;
- }
-
- return 0;
-}
-
-int image_find(const char *name, Image **ret) {
- const char *path;
- int r;
-
- assert(name);
-
- /* There are no images with invalid names */
- if (!image_name_is_valid(name))
- return 0;
-
- NULSTR_FOREACH(path, image_search_path) {
- _cleanup_closedir_ DIR *d = NULL;
-
- d = opendir(path);
- if (!d) {
- if (errno == ENOENT)
- continue;
-
- return -errno;
- }
-
- r = image_make(NULL, dirfd(d), path, name, ret);
- if (r == 0 || r == -ENOENT) {
- _cleanup_free_ char *raw = NULL;
-
- raw = strappend(name, ".raw");
- if (!raw)
- return -ENOMEM;
-
- r = image_make(NULL, dirfd(d), path, raw, ret);
- if (r == 0 || r == -ENOENT)
- continue;
- }
- if (r < 0)
- return r;
-
- return 1;
- }
-
- if (streq(name, ".host"))
- return image_make(".host", AT_FDCWD, NULL, "/", ret);
-
- return 0;
-};
-
-int image_discover(Hashmap *h) {
- const char *path;
- int r;
-
- assert(h);
-
- NULSTR_FOREACH(path, image_search_path) {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
-
- d = opendir(path);
- if (!d) {
- if (errno == ENOENT)
- continue;
-
- return -errno;
- }
-
- FOREACH_DIRENT_ALL(de, d, return -errno) {
- _cleanup_(image_unrefp) Image *image = NULL;
-
- if (!image_name_is_valid(de->d_name))
- continue;
-
- if (hashmap_contains(h, de->d_name))
- continue;
-
- r = image_make(NULL, dirfd(d), path, de->d_name, &image);
- if (r == 0 || r == -ENOENT)
- continue;
- if (r < 0)
- return r;
-
- r = hashmap_put(h, image->name, image);
- if (r < 0)
- return r;
-
- image = NULL;
- }
- }
-
- if (!hashmap_contains(h, ".host")) {
- _cleanup_(image_unrefp) Image *image = NULL;
-
- r = image_make(".host", AT_FDCWD, NULL, "/", &image);
- if (r < 0)
- return r;
-
- r = hashmap_put(h, image->name, image);
- if (r < 0)
- return r;
-
- image = NULL;
-
- }
-
- return 0;
-}
-
-void image_hashmap_free(Hashmap *map) {
- Image *i;
-
- while ((i = hashmap_steal_first(map)))
- image_unref(i);
-
- hashmap_free(map);
-}
-
-int image_remove(Image *i) {
- _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
- _cleanup_strv_free_ char **settings = NULL;
- char **j;
- int r;
-
- assert(i);
-
- if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
- return -EROFS;
-
- settings = image_settings_path(i);
- if (!settings)
- return -ENOMEM;
-
- /* Make sure we don't interfere with a running nspawn */
- r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
- if (r < 0)
- return r;
-
- switch (i->type) {
-
- case IMAGE_SUBVOLUME:
- r = btrfs_subvol_remove(i->path, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
- if (r < 0)
- return r;
- break;
-
- case IMAGE_DIRECTORY:
- /* Allow deletion of read-only directories */
- (void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
- r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
- if (r < 0)
- return r;
-
- break;
-
- case IMAGE_RAW:
- if (unlink(i->path) < 0)
- return -errno;
- break;
-
- default:
- return -EOPNOTSUPP;
- }
-
- STRV_FOREACH(j, settings) {
- if (unlink(*j) < 0 && errno != ENOENT)
- log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", *j);
- }
-
- return 0;
-}
-
-static int rename_settings_file(const char *path, const char *new_name) {
- _cleanup_free_ char *rs = NULL;
- const char *fn;
-
- fn = strjoina(new_name, ".nspawn");
-
- rs = file_in_same_dir(path, fn);
- if (!rs)
- return -ENOMEM;
-
- return rename_noreplace(AT_FDCWD, path, AT_FDCWD, rs);
-}
-
-int image_rename(Image *i, const char *new_name) {
- _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT;
- _cleanup_free_ char *new_path = NULL, *nn = NULL;
- _cleanup_strv_free_ char **settings = NULL;
- unsigned file_attr = 0;
- char **j;
- int r;
-
- assert(i);
-
- if (!image_name_is_valid(new_name))
- return -EINVAL;
-
- if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
- return -EROFS;
-
- settings = image_settings_path(i);
- if (!settings)
- return -ENOMEM;
-
- /* Make sure we don't interfere with a running nspawn */
- r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
- if (r < 0)
- return r;
-
- /* Make sure nobody takes the new name, between the time we
- * checked it is currently unused in all search paths, and the
- * time we take possession of it */
- r = image_name_lock(new_name, LOCK_EX|LOCK_NB, &name_lock);
- if (r < 0)
- return r;
-
- r = image_find(new_name, NULL);
- if (r < 0)
- return r;
- if (r > 0)
- return -EEXIST;
-
- switch (i->type) {
-
- case IMAGE_DIRECTORY:
- /* Turn of the immutable bit while we rename the image, so that we can rename it */
- (void) read_attr_path(i->path, &file_attr);
-
- if (file_attr & FS_IMMUTABLE_FL)
- (void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
-
- /* fall through */
-
- case IMAGE_SUBVOLUME:
- new_path = file_in_same_dir(i->path, new_name);
- break;
-
- case IMAGE_RAW: {
- const char *fn;
-
- fn = strjoina(new_name, ".raw");
- new_path = file_in_same_dir(i->path, fn);
- break;
- }
-
- default:
- return -EOPNOTSUPP;
- }
-
- if (!new_path)
- return -ENOMEM;
-
- nn = strdup(new_name);
- if (!nn)
- return -ENOMEM;
-
- r = rename_noreplace(AT_FDCWD, i->path, AT_FDCWD, new_path);
- if (r < 0)
- return r;
-
- /* Restore the immutable bit, if it was set before */
- if (file_attr & FS_IMMUTABLE_FL)
- (void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL);
-
- free(i->path);
- i->path = new_path;
- new_path = NULL;
-
- free(i->name);
- i->name = nn;
- nn = NULL;
-
- STRV_FOREACH(j, settings) {
- r = rename_settings_file(*j, new_name);
- if (r < 0 && r != -ENOENT)
- log_debug_errno(r, "Failed to rename settings file %s, ignoring: %m", *j);
- }
-
- return 0;
-}
-
-static int clone_settings_file(const char *path, const char *new_name) {
- _cleanup_free_ char *rs = NULL;
- const char *fn;
-
- fn = strjoina(new_name, ".nspawn");
-
- rs = file_in_same_dir(path, fn);
- if (!rs)
- return -ENOMEM;
-
- return copy_file_atomic(path, rs, 0664, false, 0);
-}
-
-int image_clone(Image *i, const char *new_name, bool read_only) {
- _cleanup_release_lock_file_ LockFile name_lock = LOCK_FILE_INIT;
- _cleanup_strv_free_ char **settings = NULL;
- const char *new_path;
- char **j;
- int r;
-
- assert(i);
-
- if (!image_name_is_valid(new_name))
- return -EINVAL;
-
- settings = image_settings_path(i);
- if (!settings)
- return -ENOMEM;
-
- /* Make sure nobody takes the new name, between the time we
- * checked it is currently unused in all search paths, and the
- * time we take possession of it */
- r = image_name_lock(new_name, LOCK_EX|LOCK_NB, &name_lock);
- if (r < 0)
- return r;
-
- r = image_find(new_name, NULL);
- if (r < 0)
- return r;
- if (r > 0)
- return -EEXIST;
-
- switch (i->type) {
-
- case IMAGE_SUBVOLUME:
- case IMAGE_DIRECTORY:
- /* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain
- * directory.*/
-
- new_path = strjoina("/var/lib/machines/", new_name);
-
- r = btrfs_subvol_snapshot(i->path, new_path, (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
- if (r == -EOPNOTSUPP) {
- /* No btrfs snapshots supported, create a normal directory then. */
-
- r = copy_directory(i->path, new_path, false);
- if (r >= 0)
- (void) chattr_path(new_path, read_only ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
- } else if (r >= 0)
- /* Enable "subtree" quotas for the copy, if we didn't copy any quota from the source. */
- (void) btrfs_subvol_auto_qgroup(new_path, 0, true);
-
- break;
-
- case IMAGE_RAW:
- new_path = strjoina("/var/lib/machines/", new_name, ".raw");
-
- r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644, false, FS_NOCOW_FL);
- break;
-
- default:
- return -EOPNOTSUPP;
- }
-
- if (r < 0)
- return r;
-
- STRV_FOREACH(j, settings) {
- r = clone_settings_file(*j, new_name);
- if (r < 0 && r != -ENOENT)
- log_debug_errno(r, "Failed to clone settings %s, ignoring: %m", *j);
- }
-
- return 0;
-}
-
-int image_read_only(Image *i, bool b) {
- _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
- int r;
- assert(i);
-
- if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
- return -EROFS;
-
- /* Make sure we don't interfere with a running nspawn */
- r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
- if (r < 0)
- return r;
-
- switch (i->type) {
-
- case IMAGE_SUBVOLUME:
-
- /* Note that we set the flag only on the top-level
- * subvolume of the image. */
-
- r = btrfs_subvol_set_read_only(i->path, b);
- if (r < 0)
- return r;
-
- break;
-
- case IMAGE_DIRECTORY:
- /* For simple directory trees we cannot use the access
- mode of the top-level directory, since it has an
- effect on the container itself. However, we can
- use the "immutable" flag, to at least make the
- top-level directory read-only. It's not as good as
- a read-only subvolume, but at least something, and
- we can read the value back.*/
-
- r = chattr_path(i->path, b ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
- if (r < 0)
- return r;
-
- break;
-
- case IMAGE_RAW: {
- struct stat st;
-
- if (stat(i->path, &st) < 0)
- return -errno;
-
- if (chmod(i->path, (st.st_mode & 0444) | (b ? 0000 : 0200)) < 0)
- return -errno;
-
- /* If the images is now read-only, it's a good time to
- * defrag it, given that no write patterns will
- * fragment it again. */
- if (b)
- (void) btrfs_defrag(i->path);
- break;
- }
-
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-int image_path_lock(const char *path, int operation, LockFile *global, LockFile *local) {
- _cleanup_free_ char *p = NULL;
- LockFile t = LOCK_FILE_INIT;
- struct stat st;
- int r;
-
- assert(path);
- assert(global);
- assert(local);
-
- /* Locks an image path. This actually creates two locks: one
- * "local" one, next to the image path itself, which might be
- * shared via NFS. And another "global" one, in /run, that
- * uses the device/inode number. This has the benefit that we
- * can even lock a tree that is a mount point, correctly. */
-
- if (path_equal(path, "/"))
- return -EBUSY;
-
- if (!path_is_absolute(path))
- return -EINVAL;
-
- if (stat(path, &st) >= 0) {
- if (asprintf(&p, "/run/systemd/nspawn/locks/inode-%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
- return -ENOMEM;
- }
-
- r = make_lock_file_for(path, operation, &t);
- if (r < 0)
- return r;
-
- if (p) {
- mkdir_p("/run/systemd/nspawn/locks", 0700);
-
- r = make_lock_file(p, operation, global);
- if (r < 0) {
- release_lock_file(&t);
- return r;
- }
- }
-
- *local = t;
- return 0;
-}
-
-int image_set_limit(Image *i, uint64_t referenced_max) {
- assert(i);
-
- if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
- return -EROFS;
-
- if (i->type != IMAGE_SUBVOLUME)
- return -EOPNOTSUPP;
-
- /* We set the quota both for the subvolume as well as for the
- * subtree. The latter is mostly for historical reasons, since
- * we didn't use to have a concept of subtree quota, and hence
- * only modified the subvolume quota. */
-
- (void) btrfs_qgroup_set_limit(i->path, 0, referenced_max);
- (void) btrfs_subvol_auto_qgroup(i->path, 0, true);
- return btrfs_subvol_set_subtree_quota_limit(i->path, 0, referenced_max);
-}
-
-int image_name_lock(const char *name, int operation, LockFile *ret) {
- const char *p;
-
- assert(name);
- assert(ret);
-
- /* Locks an image name, regardless of the precise path used. */
-
- if (!image_name_is_valid(name))
- return -EINVAL;
-
- if (streq(name, ".host"))
- return -EBUSY;
-
- mkdir_p("/run/systemd/nspawn/locks", 0700);
- p = strjoina("/run/systemd/nspawn/locks/name-", name);
-
- return make_lock_file(p, operation, ret);
-}
-
-bool image_name_is_valid(const char *s) {
- if (!filename_is_valid(s))
- return false;
-
- if (string_has_cc(s, NULL))
- return false;
-
- if (!utf8_is_valid(s))
- return false;
-
- /* Temporary files for atomically creating new files */
- if (startswith(s, ".#"))
- return false;
-
- return true;
-}
-
-static const char* const image_type_table[_IMAGE_TYPE_MAX] = {
- [IMAGE_DIRECTORY] = "directory",
- [IMAGE_SUBVOLUME] = "subvolume",
- [IMAGE_RAW] = "raw",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(image_type, ImageType);
diff --git a/src/shared/machine-image.h b/src/shared/machine-image.h
deleted file mode 100644
index 7410168c4f..0000000000
--- a/src/shared/machine-image.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "hashmap.h"
-#include "lockfile-util.h"
-#include "macro.h"
-#include "path-util.h"
-#include "string-util.h"
-#include "time-util.h"
-
-typedef enum ImageType {
- IMAGE_DIRECTORY,
- IMAGE_SUBVOLUME,
- IMAGE_RAW,
- _IMAGE_TYPE_MAX,
- _IMAGE_TYPE_INVALID = -1
-} ImageType;
-
-typedef struct Image {
- ImageType type;
- char *name;
- char *path;
- bool read_only;
-
- usec_t crtime;
- usec_t mtime;
-
- uint64_t usage;
- uint64_t usage_exclusive;
- uint64_t limit;
- uint64_t limit_exclusive;
-
- void *userdata;
-} Image;
-
-Image *image_unref(Image *i);
-void image_hashmap_free(Hashmap *map);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Image*, image_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, image_hashmap_free);
-
-int image_find(const char *name, Image **ret);
-int image_discover(Hashmap *map);
-
-int image_remove(Image *i);
-int image_rename(Image *i, const char *new_name);
-int image_clone(Image *i, const char *new_name, bool read_only);
-int image_read_only(Image *i, bool b);
-
-const char* image_type_to_string(ImageType t) _const_;
-ImageType image_type_from_string(const char *s) _pure_;
-
-bool image_name_is_valid(const char *s) _pure_;
-
-int image_path_lock(const char *path, int operation, LockFile *global, LockFile *local);
-int image_name_lock(const char *name, int operation, LockFile *ret);
-
-int image_set_limit(Image *i, uint64_t referenced_max);
-
-static inline bool IMAGE_IS_HIDDEN(const struct Image *i) {
- assert(i);
-
- return i->name && i->name[0] == '.';
-}
-
-static inline bool IMAGE_IS_VENDOR(const struct Image *i) {
- assert(i);
-
- return i->path && path_startswith(i->path, "/usr");
-}
-
-static inline bool IMAGE_IS_HOST(const struct Image *i) {
- assert(i);
-
- if (i->name && streq(i->name, ".host"))
- return true;
-
- if (i->path && path_equal(i->path, "/"))
- return true;
-
- return false;
-}
diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c
deleted file mode 100644
index 23890c63a0..0000000000
--- a/src/shared/machine-pool.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2015 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/loop.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <sys/prctl.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
-#include <unistd.h>
-
-#include "sd-bus-protocol.h"
-#include "sd-bus.h"
-
-#include "alloc-util.h"
-#include "btrfs-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "lockfile-util.h"
-#include "log.h"
-#include "machine-pool.h"
-#include "macro.h"
-#include "missing.h"
-#include "mkdir.h"
-#include "mount-util.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "process-util.h"
-#include "signal-util.h"
-#include "stat-util.h"
-#include "string-util.h"
-
-#define VAR_LIB_MACHINES_SIZE_START (1024UL*1024UL*500UL)
-#define VAR_LIB_MACHINES_FREE_MIN (1024UL*1024UL*750UL)
-
-static int check_btrfs(void) {
- struct statfs sfs;
-
- if (statfs("/var/lib/machines", &sfs) < 0) {
- if (errno != ENOENT)
- return -errno;
-
- if (statfs("/var/lib", &sfs) < 0)
- return -errno;
- }
-
- return F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC);
-}
-
-static int setup_machine_raw(uint64_t size, sd_bus_error *error) {
- _cleanup_free_ char *tmp = NULL;
- _cleanup_close_ int fd = -1;
- struct statvfs ss;
- pid_t pid = 0;
- siginfo_t si;
- int r;
-
- /* We want to be able to make use of btrfs-specific file
- * system features, in particular subvolumes, reflinks and
- * quota. Hence, if we detect that /var/lib/machines.raw is
- * not located on btrfs, let's create a loopback file, place a
- * btrfs file system into it, and mount it to
- * /var/lib/machines. */
-
- fd = open("/var/lib/machines.raw", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
- if (fd >= 0) {
- r = fd;
- fd = -1;
- return r;
- }
-
- if (errno != ENOENT)
- return sd_bus_error_set_errnof(error, errno, "Failed to open /var/lib/machines.raw: %m");
-
- r = tempfn_xxxxxx("/var/lib/machines.raw", NULL, &tmp);
- if (r < 0)
- return r;
-
- (void) mkdir_p_label("/var/lib", 0755);
- fd = open(tmp, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0600);
- if (fd < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to create /var/lib/machines.raw: %m");
-
- if (fstatvfs(fd, &ss) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to determine free space on /var/lib/machines.raw: %m");
- goto fail;
- }
-
- if (ss.f_bsize * ss.f_bavail < VAR_LIB_MACHINES_FREE_MIN) {
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Not enough free disk space to set up /var/lib/machines.");
- goto fail;
- }
-
- if (ftruncate(fd, size) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to enlarge /var/lib/machines.raw: %m");
- goto fail;
- }
-
- pid = fork();
- if (pid < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to fork mkfs.btrfs: %m");
- goto fail;
- }
-
- if (pid == 0) {
-
- /* Child */
-
- (void) reset_all_signal_handlers();
- (void) reset_signal_mask();
- assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
-
- fd = safe_close(fd);
-
- execlp("mkfs.btrfs", "-Lvar-lib-machines", tmp, NULL);
- if (errno == ENOENT)
- _exit(99);
-
- _exit(EXIT_FAILURE);
- }
-
- r = wait_for_terminate(pid, &si);
- if (r < 0) {
- sd_bus_error_set_errnof(error, r, "Failed to wait for mkfs.btrfs: %m");
- goto fail;
- }
-
- pid = 0;
-
- if (si.si_code != CLD_EXITED) {
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs died abnormally.");
- goto fail;
- }
- if (si.si_status == 99) {
- r = sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing");
- goto fail;
- }
- if (si.si_status != 0) {
- r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs failed with error code %i", si.si_status);
- goto fail;
- }
-
- r = rename_noreplace(AT_FDCWD, tmp, AT_FDCWD, "/var/lib/machines.raw");
- if (r < 0) {
- sd_bus_error_set_errnof(error, r, "Failed to move /var/lib/machines.raw into place: %m");
- goto fail;
- }
-
- r = fd;
- fd = -1;
-
- return r;
-
-fail:
- unlink_noerrno(tmp);
-
- if (pid > 1)
- kill_and_sigcont(pid, SIGKILL);
-
- return r;
-}
-
-int setup_machine_directory(uint64_t size, sd_bus_error *error) {
- _cleanup_release_lock_file_ LockFile lock_file = LOCK_FILE_INIT;
- struct loop_info64 info = {
- .lo_flags = LO_FLAGS_AUTOCLEAR,
- };
- _cleanup_close_ int fd = -1, control = -1, loop = -1;
- _cleanup_free_ char* loopdev = NULL;
- char tmpdir[] = "/tmp/machine-pool.XXXXXX", *mntdir = NULL;
- bool tmpdir_made = false, mntdir_made = false, mntdir_mounted = false;
- char buf[FORMAT_BYTES_MAX];
- int r, nr = -1;
-
- /* btrfs cannot handle file systems < 16M, hence use this as minimum */
- if (size == (uint64_t) -1)
- size = VAR_LIB_MACHINES_SIZE_START;
- else if (size < 16*1024*1024)
- size = 16*1024*1024;
-
- /* Make sure we only set the directory up once at a time */
- r = make_lock_file("/run/systemd/machines.lock", LOCK_EX, &lock_file);
- if (r < 0)
- return r;
-
- r = check_btrfs();
- if (r < 0)
- return sd_bus_error_set_errnof(error, r, "Failed to determine whether /var/lib/machines is located on btrfs: %m");
- if (r > 0) {
- (void) btrfs_subvol_make_label("/var/lib/machines");
-
- r = btrfs_quota_enable("/var/lib/machines", true);
- if (r < 0)
- log_warning_errno(r, "Failed to enable quota for /var/lib/machines, ignoring: %m");
-
- r = btrfs_subvol_auto_qgroup("/var/lib/machines", 0, true);
- if (r < 0)
- log_warning_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines, ignoring: %m");
-
- return 1;
- }
-
- if (path_is_mount_point("/var/lib/machines", AT_SYMLINK_FOLLOW) > 0) {
- log_debug("/var/lib/machines is already a mount point, not creating loopback file for it.");
- return 0;
- }
-
- r = dir_is_populated("/var/lib/machines");
- if (r < 0 && r != -ENOENT)
- return r;
- if (r > 0) {
- log_debug("/var/log/machines is already populated, not creating loopback file for it.");
- return 0;
- }
-
- r = mkfs_exists("btrfs");
- if (r == 0)
- return sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing");
- if (r < 0)
- return r;
-
- fd = setup_machine_raw(size, error);
- if (fd < 0)
- return fd;
-
- control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
- if (control < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to open /dev/loop-control: %m");
-
- nr = ioctl(control, LOOP_CTL_GET_FREE);
- if (nr < 0)
- return sd_bus_error_set_errnof(error, errno, "Failed to allocate loop device: %m");
-
- if (asprintf(&loopdev, "/dev/loop%i", nr) < 0) {
- r = -ENOMEM;
- goto fail;
- }
-
- loop = open(loopdev, O_CLOEXEC|O_RDWR|O_NOCTTY|O_NONBLOCK);
- if (loop < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to open loopback device: %m");
- goto fail;
- }
-
- if (ioctl(loop, LOOP_SET_FD, fd) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to bind loopback device: %m");
- goto fail;
- }
-
- if (ioctl(loop, LOOP_SET_STATUS64, &info) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to enable auto-clear for loopback device: %m");
- goto fail;
- }
-
- /* We need to make sure the new /var/lib/machines directory
- * has an access mode of 0700 at the time it is first made
- * available. mkfs will create it with 0755 however. Hence,
- * let's mount the directory into an inaccessible directory
- * below /tmp first, fix the access mode, and move it to the
- * public place then. */
-
- if (!mkdtemp(tmpdir)) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount parent directory: %m");
- goto fail;
- }
- tmpdir_made = true;
-
- mntdir = strjoina(tmpdir, "/mnt");
- if (mkdir(mntdir, 0700) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount directory: %m");
- goto fail;
- }
- mntdir_made = true;
-
- if (mount(loopdev, mntdir, "btrfs", 0, NULL) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to mount loopback device: %m");
- goto fail;
- }
- mntdir_mounted = true;
-
- r = btrfs_quota_enable(mntdir, true);
- if (r < 0)
- log_warning_errno(r, "Failed to enable quota, ignoring: %m");
-
- r = btrfs_subvol_auto_qgroup(mntdir, 0, true);
- if (r < 0)
- log_warning_errno(r, "Failed to set up default quota hierarchy, ignoring: %m");
-
- if (chmod(mntdir, 0700) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to fix owner: %m");
- goto fail;
- }
-
- (void) mkdir_p_label("/var/lib/machines", 0700);
-
- if (mount(mntdir, "/var/lib/machines", NULL, MS_BIND, NULL) < 0) {
- r = sd_bus_error_set_errnof(error, errno, "Failed to mount directory into right place: %m");
- goto fail;
- }
-
- (void) syncfs(fd);
-
- log_info("Set up /var/lib/machines as btrfs loopback file system of size %s mounted on /var/lib/machines.raw.", format_bytes(buf, sizeof(buf), size));
-
- (void) umount2(mntdir, MNT_DETACH);
- (void) rmdir(mntdir);
- (void) rmdir(tmpdir);
-
- return 1;
-
-fail:
- if (mntdir_mounted)
- (void) umount2(mntdir, MNT_DETACH);
-
- if (mntdir_made)
- (void) rmdir(mntdir);
- if (tmpdir_made)
- (void) rmdir(tmpdir);
-
- if (loop >= 0) {
- (void) ioctl(loop, LOOP_CLR_FD);
- loop = safe_close(loop);
- }
-
- if (control >= 0 && nr >= 0)
- (void) ioctl(control, LOOP_CTL_REMOVE, nr);
-
- return r;
-}
-
-static int sync_path(const char *p) {
- _cleanup_close_ int fd = -1;
-
- fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY);
- if (fd < 0)
- return -errno;
-
- if (syncfs(fd) < 0)
- return -errno;
-
- return 0;
-}
-
-int grow_machine_directory(void) {
- char buf[FORMAT_BYTES_MAX];
- struct statvfs a, b;
- uint64_t old_size, new_size, max_add;
- int r;
-
- /* Ensure the disk space data is accurate */
- sync_path("/var/lib/machines");
- sync_path("/var/lib/machines.raw");
-
- if (statvfs("/var/lib/machines.raw", &a) < 0)
- return -errno;
-
- if (statvfs("/var/lib/machines", &b) < 0)
- return -errno;
-
- /* Don't grow if not enough disk space is available on the host */
- if (((uint64_t) a.f_bavail * (uint64_t) a.f_bsize) <= VAR_LIB_MACHINES_FREE_MIN)
- return 0;
-
- /* Don't grow if at least 1/3th of the fs is still free */
- if (b.f_bavail > b.f_blocks / 3)
- return 0;
-
- /* Calculate how much we are willing to add at most */
- max_add = ((uint64_t) a.f_bavail * (uint64_t) a.f_bsize) - VAR_LIB_MACHINES_FREE_MIN;
-
- /* Calculate the old size */
- old_size = (uint64_t) b.f_blocks * (uint64_t) b.f_bsize;
-
- /* Calculate the new size as three times the size of what is used right now */
- new_size = ((uint64_t) b.f_blocks - (uint64_t) b.f_bavail) * (uint64_t) b.f_bsize * 3;
-
- /* Always, grow at least to the start size */
- if (new_size < VAR_LIB_MACHINES_SIZE_START)
- new_size = VAR_LIB_MACHINES_SIZE_START;
-
- /* If the new size is smaller than the old size, don't grow */
- if (new_size < old_size)
- return 0;
-
- /* Ensure we never add more than the maximum */
- if (new_size > old_size + max_add)
- new_size = old_size + max_add;
-
- r = btrfs_resize_loopback("/var/lib/machines", new_size, true);
- if (r <= 0)
- return r;
-
- /* Also bump the quota, of both the subvolume leaf qgroup, as
- * well as of any subtree quota group by the same id but a
- * higher level, if it exists. */
- (void) btrfs_qgroup_set_limit("/var/lib/machines", 0, new_size);
- (void) btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, new_size);
-
- log_info("Grew /var/lib/machines btrfs loopback file system to %s.", format_bytes(buf, sizeof(buf), new_size));
- return 1;
-}
diff --git a/src/shared/machine-pool.h b/src/shared/machine-pool.h
deleted file mode 100644
index 40fe5ecb3a..0000000000
--- a/src/shared/machine-pool.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2015 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdint.h>
-
-#include "sd-bus.h"
-
-/* Grow the /var/lib/machines directory after each 10MiB written */
-#define GROW_INTERVAL_BYTES (UINT64_C(10) * UINT64_C(1024) * UINT64_C(1024))
-
-int setup_machine_directory(uint64_t size, sd_bus_error *error);
-int grow_machine_directory(void);
diff --git a/src/shared/output-mode.c b/src/shared/output-mode.c
deleted file mode 100644
index 67d8208ad2..0000000000
--- a/src/shared/output-mode.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "output-mode.h"
-#include "string-table.h"
-
-static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
- [OUTPUT_SHORT] = "short",
- [OUTPUT_SHORT_FULL] = "short-full",
- [OUTPUT_SHORT_ISO] = "short-iso",
- [OUTPUT_SHORT_PRECISE] = "short-precise",
- [OUTPUT_SHORT_MONOTONIC] = "short-monotonic",
- [OUTPUT_SHORT_UNIX] = "short-unix",
- [OUTPUT_VERBOSE] = "verbose",
- [OUTPUT_EXPORT] = "export",
- [OUTPUT_JSON] = "json",
- [OUTPUT_JSON_PRETTY] = "json-pretty",
- [OUTPUT_JSON_SSE] = "json-sse",
- [OUTPUT_CAT] = "cat"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(output_mode, OutputMode);
diff --git a/src/shared/output-mode.h b/src/shared/output-mode.h
deleted file mode 100644
index ff29dafcb5..0000000000
--- a/src/shared/output-mode.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "macro.h"
-
-typedef enum OutputMode {
- OUTPUT_SHORT,
- OUTPUT_SHORT_FULL,
- OUTPUT_SHORT_ISO,
- OUTPUT_SHORT_PRECISE,
- OUTPUT_SHORT_MONOTONIC,
- OUTPUT_SHORT_UNIX,
- OUTPUT_VERBOSE,
- OUTPUT_EXPORT,
- OUTPUT_JSON,
- OUTPUT_JSON_PRETTY,
- OUTPUT_JSON_SSE,
- OUTPUT_CAT,
- _OUTPUT_MODE_MAX,
- _OUTPUT_MODE_INVALID = -1
-} OutputMode;
-
-/* The output flags definitions are shared by the logs and process tree output. Some apply to both, some only to the
- * logs output, others only to the process tree output. */
-
-typedef enum OutputFlags {
- OUTPUT_SHOW_ALL = 1 << 0,
- OUTPUT_FOLLOW = 1 << 1,
- OUTPUT_WARN_CUTOFF = 1 << 2,
- OUTPUT_FULL_WIDTH = 1 << 3,
- OUTPUT_COLOR = 1 << 4,
- OUTPUT_CATALOG = 1 << 5,
- OUTPUT_BEGIN_NEWLINE = 1 << 6,
- OUTPUT_UTC = 1 << 7,
- OUTPUT_KERNEL_THREADS = 1 << 8,
- OUTPUT_NO_HOSTNAME = 1 << 9,
-} OutputFlags;
-
-const char* output_mode_to_string(OutputMode m) _const_;
-OutputMode output_mode_from_string(const char *s) _pure_;
diff --git a/src/shared/pager.c b/src/shared/pager.c
deleted file mode 100644
index 09672a4abf..0000000000
--- a/src/shared/pager.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <unistd.h>
-
-#include "copy.h"
-#include "fd-util.h"
-#include "locale-util.h"
-#include "log.h"
-#include "macro.h"
-#include "pager.h"
-#include "process-util.h"
-#include "signal-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "terminal-util.h"
-
-static pid_t pager_pid = 0;
-
-noreturn static void pager_fallback(void) {
- int r;
-
- r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, (uint64_t) -1, false);
- if (r < 0) {
- log_error_errno(r, "Internal pager failed: %m");
- _exit(EXIT_FAILURE);
- }
-
- _exit(EXIT_SUCCESS);
-}
-
-int pager_open(bool no_pager, bool jump_to_end) {
- _cleanup_close_pair_ int fd[2] = { -1, -1 };
- const char *pager;
- pid_t parent_pid;
-
- if (no_pager)
- return 0;
-
- if (pager_pid > 0)
- return 1;
-
- if (terminal_is_dumb())
- return 0;
-
- pager = getenv("SYSTEMD_PAGER");
- if (!pager)
- pager = getenv("PAGER");
-
- /* If the pager is explicitly turned off, honour it */
- if (pager && STR_IN_SET(pager, "", "cat"))
- return 0;
-
- /* Determine and cache number of columns before we spawn the
- * pager so that we get the value from the actual tty */
- (void) columns();
-
- if (pipe(fd) < 0)
- return log_error_errno(errno, "Failed to create pager pipe: %m");
-
- parent_pid = getpid();
-
- pager_pid = fork();
- if (pager_pid < 0)
- return log_error_errno(errno, "Failed to fork pager: %m");
-
- /* In the child start the pager */
- if (pager_pid == 0) {
- const char* less_opts, *less_charset;
-
- (void) reset_all_signal_handlers();
- (void) reset_signal_mask();
-
- (void) dup2(fd[0], STDIN_FILENO);
- safe_close_pair(fd);
-
- /* Initialize a good set of less options */
- less_opts = getenv("SYSTEMD_LESS");
- if (!less_opts)
- less_opts = "FRSXMK";
- if (jump_to_end)
- less_opts = strjoina(less_opts, " +G");
- setenv("LESS", less_opts, 1);
-
- /* Initialize a good charset for less. This is
- * particularly important if we output UTF-8
- * characters. */
- less_charset = getenv("SYSTEMD_LESSCHARSET");
- if (!less_charset && is_locale_utf8())
- less_charset = "utf-8";
- if (less_charset)
- setenv("LESSCHARSET", less_charset, 1);
-
- /* Make sure the pager goes away when the parent dies */
- if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
- _exit(EXIT_FAILURE);
-
- /* Check whether our parent died before we were able
- * to set the death signal */
- if (getppid() != parent_pid)
- _exit(EXIT_SUCCESS);
-
- if (pager) {
- execlp(pager, pager, NULL);
- execl("/bin/sh", "sh", "-c", pager, NULL);
- }
-
- /* Debian's alternatives command for pagers is
- * called 'pager'. Note that we do not call
- * sensible-pagers here, since that is just a
- * shell script that implements a logic that
- * is similar to this one anyway, but is
- * Debian-specific. */
- execlp("pager", "pager", NULL);
-
- execlp("less", "less", NULL);
- execlp("more", "more", NULL);
-
- pager_fallback();
- /* not reached */
- }
-
- /* Return in the parent */
- if (dup2(fd[1], STDOUT_FILENO) < 0)
- return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
- if (dup2(fd[1], STDERR_FILENO) < 0)
- return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
-
- return 1;
-}
-
-void pager_close(void) {
-
- if (pager_pid <= 0)
- return;
-
- /* Inform pager that we are done */
- stdout = safe_fclose(stdout);
- stderr = safe_fclose(stderr);
-
- (void) kill(pager_pid, SIGCONT);
- (void) wait_for_terminate(pager_pid, NULL);
- pager_pid = 0;
-}
-
-bool pager_have(void) {
- return pager_pid > 0;
-}
-
-int show_man_page(const char *desc, bool null_stdio) {
- const char *args[4] = { "man", NULL, NULL, NULL };
- char *e = NULL;
- pid_t pid;
- size_t k;
- int r;
- siginfo_t status;
-
- k = strlen(desc);
-
- if (desc[k-1] == ')')
- e = strrchr(desc, '(');
-
- if (e) {
- char *page = NULL, *section = NULL;
-
- page = strndupa(desc, e - desc);
- section = strndupa(e + 1, desc + k - e - 2);
-
- args[1] = section;
- args[2] = page;
- } else
- args[1] = desc;
-
- pid = fork();
- if (pid < 0)
- return log_error_errno(errno, "Failed to fork: %m");
-
- if (pid == 0) {
- /* Child */
-
- (void) reset_all_signal_handlers();
- (void) reset_signal_mask();
-
- if (null_stdio) {
- r = make_null_stdio();
- if (r < 0) {
- log_error_errno(r, "Failed to kill stdio: %m");
- _exit(EXIT_FAILURE);
- }
- }
-
- execvp(args[0], (char**) args);
- log_error_errno(errno, "Failed to execute man: %m");
- _exit(EXIT_FAILURE);
- }
-
- r = wait_for_terminate(pid, &status);
- if (r < 0)
- return r;
-
- log_debug("Exit code %i status %i", status.si_code, status.si_status);
- return status.si_status;
-}
diff --git a/src/shared/pager.h b/src/shared/pager.h
deleted file mode 100644
index 893e1d2bb6..0000000000
--- a/src/shared/pager.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include "macro.h"
-
-int pager_open(bool no_pager, bool jump_to_end);
-void pager_close(void);
-bool pager_have(void) _pure_;
-
-int show_man_page(const char *page, bool null_stdio);
diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
deleted file mode 100644
index 862096ae7b..0000000000
--- a/src/shared/path-lookup.c
+++ /dev/null
@@ -1,822 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "install.h"
-#include "log.h"
-#include "macro.h"
-#include "mkdir.h"
-#include "path-lookup.h"
-#include "path-util.h"
-#include "rm-rf.h"
-#include "stat-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "util.h"
-
-static int user_runtime_dir(char **ret, const char *suffix) {
- const char *e;
- char *j;
-
- assert(ret);
- assert(suffix);
-
- e = getenv("XDG_RUNTIME_DIR");
- if (!e)
- return -ENXIO;
-
- j = strappend(e, suffix);
- if (!j)
- return -ENOMEM;
-
- *ret = j;
- return 0;
-}
-
-static int user_config_dir(char **ret, const char *suffix) {
- const char *e;
- char *j;
-
- assert(ret);
-
- e = getenv("XDG_CONFIG_HOME");
- if (e)
- j = strappend(e, suffix);
- else {
- const char *home;
-
- home = getenv("HOME");
- if (!home)
- return -ENXIO;
-
- j = strjoin(home, "/.config", suffix, NULL);
- }
-
- if (!j)
- return -ENOMEM;
-
- *ret = j;
- return 0;
-}
-
-static int user_data_dir(char **ret, const char *suffix) {
- const char *e;
- char *j;
-
- assert(ret);
- assert(suffix);
-
- /* We don't treat /etc/xdg/systemd here as the spec
- * suggests because we assume that is a link to
- * /etc/systemd/ anyway. */
-
- e = getenv("XDG_DATA_HOME");
- if (e)
- j = strappend(e, suffix);
- else {
- const char *home;
-
- home = getenv("HOME");
- if (!home)
- return -ENXIO;
-
-
- j = strjoin(home, "/.local/share", suffix, NULL);
- }
- if (!j)
- return -ENOMEM;
-
- *ret = j;
- return 1;
-}
-
-static char** user_dirs(
- const char *persistent_config,
- const char *runtime_config,
- const char *generator,
- const char *generator_early,
- const char *generator_late,
- const char *transient,
- const char *persistent_control,
- const char *runtime_control) {
-
- const char * const config_unit_paths[] = {
- USER_CONFIG_UNIT_PATH,
- "/etc/systemd/user",
- NULL
- };
-
- const char * const data_unit_paths[] = {
- "/usr/local/lib/systemd/user",
- "/usr/local/share/systemd/user",
- USER_DATA_UNIT_PATH,
- "/usr/lib/systemd/user",
- "/usr/share/systemd/user",
- NULL
- };
-
- const char *e;
- _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
- _cleanup_free_ char *data_home = NULL;
- _cleanup_free_ char **res = NULL;
- char **tmp;
- int r;
-
- /* Implement the mechanisms defined in
- *
- * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
- *
- * We look in both the config and the data dirs because we
- * want to encourage that distributors ship their unit files
- * as data, and allow overriding as configuration.
- */
-
- e = getenv("XDG_CONFIG_DIRS");
- if (e) {
- config_dirs = strv_split(e, ":");
- if (!config_dirs)
- return NULL;
- }
-
- r = user_data_dir(&data_home, "/systemd/user");
- if (r < 0 && r != -ENXIO)
- return NULL;
-
- e = getenv("XDG_DATA_DIRS");
- if (e)
- data_dirs = strv_split(e, ":");
- else
- data_dirs = strv_new("/usr/local/share",
- "/usr/share",
- NULL);
- if (!data_dirs)
- return NULL;
-
- /* Now merge everything we found. */
- if (strv_extend(&res, persistent_control) < 0)
- return NULL;
-
- if (strv_extend(&res, runtime_control) < 0)
- return NULL;
-
- if (strv_extend(&res, transient) < 0)
- return NULL;
-
- if (strv_extend(&res, generator_early) < 0)
- return NULL;
-
- if (!strv_isempty(config_dirs))
- if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0)
- return NULL;
-
- if (strv_extend(&res, persistent_config) < 0)
- return NULL;
-
- if (strv_extend_strv(&res, (char**) config_unit_paths, false) < 0)
- return NULL;
-
- if (strv_extend(&res, runtime_config) < 0)
- return NULL;
-
- if (strv_extend(&res, generator) < 0)
- return NULL;
-
- if (strv_extend(&res, data_home) < 0)
- return NULL;
-
- if (!strv_isempty(data_dirs))
- if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
- return NULL;
-
- if (strv_extend_strv(&res, (char**) data_unit_paths, false) < 0)
- return NULL;
-
- if (strv_extend(&res, generator_late) < 0)
- return NULL;
-
- if (path_strv_make_absolute_cwd(res) < 0)
- return NULL;
-
- tmp = res;
- res = NULL;
- return tmp;
-}
-
-static int acquire_generator_dirs(
- UnitFileScope scope,
- char **generator,
- char **generator_early,
- char **generator_late) {
-
- _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL;
- const char *prefix;
-
- assert(generator);
- assert(generator_early);
- assert(generator_late);
-
- switch (scope) {
-
- case UNIT_FILE_SYSTEM:
- prefix = "/run/systemd/";
- break;
-
- case UNIT_FILE_USER: {
- const char *e;
-
- e = getenv("XDG_RUNTIME_DIR");
- if (!e)
- return -ENXIO;
-
- prefix = strjoina(e, "/systemd/");
- break;
- }
-
- case UNIT_FILE_GLOBAL:
- return -EOPNOTSUPP;
-
- default:
- assert_not_reached("Hmm, unexpected scope value.");
- }
-
- x = strappend(prefix, "generator");
- if (!x)
- return -ENOMEM;
-
- y = strappend(prefix, "generator.early");
- if (!y)
- return -ENOMEM;
-
- z = strappend(prefix, "generator.late");
- if (!z)
- return -ENOMEM;
-
- *generator = x;
- *generator_early = y;
- *generator_late = z;
-
- x = y = z = NULL;
- return 0;
-}
-
-static int acquire_transient_dir(UnitFileScope scope, char **ret) {
- assert(ret);
-
- switch (scope) {
-
- case UNIT_FILE_SYSTEM: {
- char *transient;
-
- transient = strdup("/run/systemd/transient");
- if (!transient)
- return -ENOMEM;
-
- *ret = transient;
- return 0;
- }
-
- case UNIT_FILE_USER:
- return user_runtime_dir(ret, "/systemd/transient");
-
- case UNIT_FILE_GLOBAL:
- return -EOPNOTSUPP;
-
- default:
- assert_not_reached("Hmm, unexpected scope value.");
- }
-}
-
-static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **runtime) {
- _cleanup_free_ char *a = NULL, *b = NULL;
- int r;
-
- assert(persistent);
- assert(runtime);
-
- switch (scope) {
-
- case UNIT_FILE_SYSTEM:
- a = strdup(SYSTEM_CONFIG_UNIT_PATH);
- b = strdup("/run/systemd/system");
- break;
-
- case UNIT_FILE_GLOBAL:
- a = strdup(USER_CONFIG_UNIT_PATH);
- b = strdup("/run/systemd/user");
- break;
-
- case UNIT_FILE_USER:
- r = user_config_dir(&a, "/systemd/user");
- if (r < 0)
- return r;
-
- r = user_runtime_dir(runtime, "/systemd/user");
- if (r < 0)
- return r;
-
- *persistent = a;
- a = NULL;
-
- return 0;
-
- default:
- assert_not_reached("Hmm, unexpected scope value.");
- }
-
- if (!a || !b)
- return -ENOMEM;
-
- *persistent = a;
- *runtime = b;
- a = b = NULL;
-
- return 0;
-}
-
-static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **runtime) {
- _cleanup_free_ char *a = NULL;
- int r;
-
- assert(persistent);
- assert(runtime);
-
- switch (scope) {
-
- case UNIT_FILE_SYSTEM: {
- _cleanup_free_ char *b = NULL;
-
- a = strdup("/etc/systemd/system.control");
- if (!a)
- return -ENOMEM;
-
- b = strdup("/run/systemd/system.control");
- if (!b)
- return -ENOMEM;
-
- *runtime = b;
- b = NULL;
-
- break;
- }
-
- case UNIT_FILE_USER:
- r = user_config_dir(&a, "/systemd/system.control");
- if (r < 0)
- return r;
-
- r = user_runtime_dir(runtime, "/systemd/system.control");
- if (r < 0)
- return r;
-
- break;
-
- case UNIT_FILE_GLOBAL:
- return -EOPNOTSUPP;
-
- default:
- assert_not_reached("Hmm, unexpected scope value.");
- }
-
- *persistent = a;
- a = NULL;
-
- return 0;
-}
-
-static int patch_root_prefix(char **p, const char *root_dir) {
- char *c;
-
- assert(p);
-
- if (!*p)
- return 0;
-
- c = prefix_root(root_dir, *p);
- if (!c)
- return -ENOMEM;
-
- free(*p);
- *p = c;
-
- return 0;
-}
-
-static int patch_root_prefix_strv(char **l, const char *root_dir) {
- char **i;
- int r;
-
- if (!root_dir)
- return 0;
-
- STRV_FOREACH(i, l) {
- r = patch_root_prefix(i, root_dir);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-int lookup_paths_init(
- LookupPaths *p,
- UnitFileScope scope,
- LookupPathsFlags flags,
- const char *root_dir) {
-
- _cleanup_free_ char
- *root = NULL,
- *persistent_config = NULL, *runtime_config = NULL,
- *generator = NULL, *generator_early = NULL, *generator_late = NULL,
- *transient = NULL,
- *persistent_control = NULL, *runtime_control = NULL;
- bool append = false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */
- _cleanup_strv_free_ char **paths = NULL;
- const char *e;
- int r;
-
- assert(p);
- assert(scope >= 0);
- assert(scope < _UNIT_FILE_SCOPE_MAX);
-
- if (!isempty(root_dir) && !path_equal(root_dir, "/")) {
- if (scope == UNIT_FILE_USER)
- return -EINVAL;
-
- r = is_dir(root_dir, true);
- if (r < 0)
- return r;
- if (r == 0)
- return -ENOTDIR;
-
- root = strdup(root_dir);
- if (!root)
- return -ENOMEM;
- }
-
- r = acquire_config_dirs(scope, &persistent_config, &runtime_config);
- if (r < 0 && r != -ENXIO)
- return r;
-
- if ((flags & LOOKUP_PATHS_EXCLUDE_GENERATED) == 0) {
- r = acquire_generator_dirs(scope, &generator, &generator_early, &generator_late);
- if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
- return r;
- }
-
- r = acquire_transient_dir(scope, &transient);
- if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
- return r;
-
- r = acquire_control_dirs(scope, &persistent_control, &runtime_control);
- if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO)
- return r;
-
- /* First priority is whatever has been passed to us via env vars */
- e = getenv("SYSTEMD_UNIT_PATH");
- if (e) {
- const char *k;
-
- k = endswith(e, ":");
- if (k) {
- e = strndupa(e, k - e);
- append = true;
- }
-
- /* FIXME: empty components in other places should be
- * rejected. */
-
- r = path_split_and_make_absolute(e, &paths);
- if (r < 0)
- return r;
- }
-
- if (!paths || append) {
- /* Let's figure something out. */
-
- _cleanup_strv_free_ char **add = NULL;
-
- /* For the user units we include share/ in the search
- * path in order to comply with the XDG basedir spec.
- * For the system stuff we avoid such nonsense. OTOH
- * we include /lib in the search path for the system
- * stuff but avoid it for user stuff. */
-
- switch (scope) {
-
- case UNIT_FILE_SYSTEM:
- add = strv_new(
- /* If you modify this you also want to modify
- * systemdsystemunitpath= in systemd.pc.in! */
- STRV_IFNOTNULL(persistent_control),
- STRV_IFNOTNULL(runtime_control),
- STRV_IFNOTNULL(transient),
- STRV_IFNOTNULL(generator_early),
- persistent_config,
- SYSTEM_CONFIG_UNIT_PATH,
- "/etc/systemd/system",
- runtime_config,
- "/run/systemd/system",
- STRV_IFNOTNULL(generator),
- "/usr/local/lib/systemd/system",
- SYSTEM_DATA_UNIT_PATH,
- "/usr/lib/systemd/system",
-#ifdef HAVE_SPLIT_USR
- "/lib/systemd/system",
-#endif
- STRV_IFNOTNULL(generator_late),
- NULL);
- break;
-
- case UNIT_FILE_GLOBAL:
- add = strv_new(
- /* If you modify this you also want to modify
- * systemduserunitpath= in systemd.pc.in, and
- * the arrays in user_dirs() above! */
- STRV_IFNOTNULL(persistent_control),
- STRV_IFNOTNULL(runtime_control),
- STRV_IFNOTNULL(transient),
- STRV_IFNOTNULL(generator_early),
- persistent_config,
- USER_CONFIG_UNIT_PATH,
- "/etc/systemd/user",
- runtime_config,
- "/run/systemd/user",
- STRV_IFNOTNULL(generator),
- "/usr/local/lib/systemd/user",
- "/usr/local/share/systemd/user",
- USER_DATA_UNIT_PATH,
- "/usr/lib/systemd/user",
- "/usr/share/systemd/user",
- STRV_IFNOTNULL(generator_late),
- NULL);
- break;
-
- case UNIT_FILE_USER:
- add = user_dirs(persistent_config, runtime_config,
- generator, generator_early, generator_late,
- transient,
- persistent_config, runtime_control);
- break;
-
- default:
- assert_not_reached("Hmm, unexpected scope?");
- }
-
- if (!add)
- return -ENOMEM;
-
- if (paths) {
- r = strv_extend_strv(&paths, add, true);
- if (r < 0)
- return r;
- } else {
- /* Small optimization: if paths is NULL (and it usually is), we can simply assign 'add' to it,
- * and don't have to copy anything */
- paths = add;
- add = NULL;
- }
- }
-
- r = patch_root_prefix(&persistent_config, root);
- if (r < 0)
- return r;
- r = patch_root_prefix(&runtime_config, root);
- if (r < 0)
- return r;
-
- r = patch_root_prefix(&generator, root);
- if (r < 0)
- return r;
- r = patch_root_prefix(&generator_early, root);
- if (r < 0)
- return r;
- r = patch_root_prefix(&generator_late, root);
- if (r < 0)
- return r;
-
- r = patch_root_prefix(&transient, root);
- if (r < 0)
- return r;
-
- r = patch_root_prefix(&persistent_control, root);
- if (r < 0)
- return r;
-
- r = patch_root_prefix(&runtime_control, root);
- if (r < 0)
- return r;
-
- r = patch_root_prefix_strv(paths, root);
- if (r < 0)
- return -ENOMEM;
-
- p->search_path = strv_uniq(paths);
- paths = NULL;
-
- p->persistent_config = persistent_config;
- p->runtime_config = runtime_config;
- persistent_config = runtime_config = NULL;
-
- p->generator = generator;
- p->generator_early = generator_early;
- p->generator_late = generator_late;
- generator = generator_early = generator_late = NULL;
-
- p->transient = transient;
- transient = NULL;
-
- p->persistent_control = persistent_control;
- p->runtime_control = runtime_control;
- persistent_control = runtime_control = NULL;
-
- p->root_dir = root;
- root = NULL;
-
- return 0;
-}
-
-void lookup_paths_free(LookupPaths *p) {
- if (!p)
- return;
-
- p->search_path = strv_free(p->search_path);
-
- p->persistent_config = mfree(p->persistent_config);
- p->runtime_config = mfree(p->runtime_config);
-
- p->generator = mfree(p->generator);
- p->generator_early = mfree(p->generator_early);
- p->generator_late = mfree(p->generator_late);
-
- p->transient = mfree(p->transient);
-
- p->persistent_control = mfree(p->persistent_control);
- p->runtime_control = mfree(p->runtime_control);
-
- p->root_dir = mfree(p->root_dir);
-}
-
-int lookup_paths_reduce(LookupPaths *p) {
- _cleanup_free_ struct stat *stats = NULL;
- size_t n_stats = 0, allocated = 0;
- unsigned c = 0;
- int r;
-
- assert(p);
-
- /* Drop duplicates and non-existing directories from the search path. We figure out whether two directories are
- * the same by comparing their device and inode numbers. Note one special tweak: when we have a root path set,
- * we do not follow symlinks when retrieving them, because the kernel wouldn't take the root prefix into
- * account when following symlinks. When we have no root path set this restriction does not apply however. */
-
- if (!p->search_path)
- return 0;
-
- while (p->search_path[c]) {
- struct stat st;
- unsigned k;
-
- if (p->root_dir)
- r = lstat(p->search_path[c], &st);
- else
- r = stat(p->search_path[c], &st);
- if (r < 0) {
- if (errno == ENOENT)
- goto remove_item;
-
- /* If something we don't grok happened, let's better leave it in. */
- log_debug_errno(errno, "Failed to stat %s: %m", p->search_path[c]);
- c++;
- continue;
- }
-
- for (k = 0; k < n_stats; k++) {
- if (stats[k].st_dev == st.st_dev &&
- stats[k].st_ino == st.st_ino)
- break;
- }
-
- if (k < n_stats) /* Is there already an entry with the same device/inode? */
- goto remove_item;
-
- if (!GREEDY_REALLOC(stats, allocated, n_stats+1))
- return -ENOMEM;
-
- stats[n_stats++] = st;
- c++;
- continue;
-
- remove_item:
- free(p->search_path[c]);
- memmove(p->search_path + c,
- p->search_path + c + 1,
- (strv_length(p->search_path + c + 1) + 1) * sizeof(char*));
- }
-
- if (strv_isempty(p->search_path)) {
- log_debug("Ignoring unit files.");
- p->search_path = strv_free(p->search_path);
- } else {
- _cleanup_free_ char *t;
-
- t = strv_join(p->search_path, "\n\t");
- if (!t)
- return -ENOMEM;
-
- log_debug("Looking for unit files in (higher priority first):\n\t%s", t);
- }
-
- return 0;
-}
-
-int lookup_paths_mkdir_generator(LookupPaths *p) {
- int r, q;
-
- assert(p);
-
- if (!p->generator || !p->generator_early || !p->generator_late)
- return -EINVAL;
-
- r = mkdir_p_label(p->generator, 0755);
-
- q = mkdir_p_label(p->generator_early, 0755);
- if (q < 0 && r >= 0)
- r = q;
-
- q = mkdir_p_label(p->generator_late, 0755);
- if (q < 0 && r >= 0)
- r = q;
-
- return r;
-}
-
-void lookup_paths_trim_generator(LookupPaths *p) {
- assert(p);
-
- /* Trim empty dirs */
-
- if (p->generator)
- (void) rmdir(p->generator);
- if (p->generator_early)
- (void) rmdir(p->generator_early);
- if (p->generator_late)
- (void) rmdir(p->generator_late);
-}
-
-void lookup_paths_flush_generator(LookupPaths *p) {
- assert(p);
-
- /* Flush the generated unit files in full */
-
- if (p->generator)
- (void) rm_rf(p->generator, REMOVE_ROOT);
- if (p->generator_early)
- (void) rm_rf(p->generator_early, REMOVE_ROOT);
- if (p->generator_late)
- (void) rm_rf(p->generator_late, REMOVE_ROOT);
-}
-
-char **generator_binary_paths(UnitFileScope scope) {
-
- switch (scope) {
-
- case UNIT_FILE_SYSTEM:
- return strv_new("/run/systemd/system-generators",
- "/etc/systemd/system-generators",
- "/usr/local/lib/systemd/system-generators",
- SYSTEM_GENERATOR_PATH,
- NULL);
-
- case UNIT_FILE_GLOBAL:
- case UNIT_FILE_USER:
- return strv_new("/run/systemd/user-generators",
- "/etc/systemd/user-generators",
- "/usr/local/lib/systemd/user-generators",
- USER_GENERATOR_PATH,
- NULL);
-
- default:
- assert_not_reached("Hmm, unexpected scope.");
- }
-}
diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h
deleted file mode 100644
index f9bb2fe237..0000000000
--- a/src/shared/path-lookup.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-typedef struct LookupPaths LookupPaths;
-
-#include "install.h"
-#include "macro.h"
-
-typedef enum LookupPathsFlags {
- LOOKUP_PATHS_EXCLUDE_GENERATED = 1,
-} LookupPathsFlags;
-
-struct LookupPaths {
- /* Where we look for unit files. This includes the individual special paths below, but also any vendor
- * supplied, static unit file paths. */
- char **search_path;
-
- /* Where we shall create or remove our installation symlinks, aka "configuration", and where the user/admin
- * shall place his own unit files. */
- char *persistent_config;
- char *runtime_config;
-
- /* Where to place generated unit files (i.e. those a "generator" tool generated). Note the special semantics of
- * this directory: the generators are flushed each time a "systemctl daemon-reload" is issued. The user should
- * not alter these directories directly. */
- char *generator;
- char *generator_early;
- char *generator_late;
-
- /* Where to place transient unit files (i.e. those created dynamically via the bus API). Note the special
- * semantics of this directory: all units created transiently have their unit files removed as the transient
- * unit is unloaded. The user should not alter this directory directly. */
- char *transient;
-
- /* Where the snippets created by "systemctl set-property" are placed. Note that for transient units, the
- * snippets are placed in the transient directory though (see above). The user should not alter this directory
- * directly. */
- char *persistent_control;
- char *runtime_control;
-
- /* The root directory prepended to all items above, or NULL */
- char *root_dir;
-};
-
-int lookup_paths_init(LookupPaths *p, UnitFileScope scope, LookupPathsFlags flags, const char *root_dir);
-
-int lookup_paths_reduce(LookupPaths *p);
-
-int lookup_paths_mkdir_generator(LookupPaths *p);
-void lookup_paths_trim_generator(LookupPaths *p);
-void lookup_paths_flush_generator(LookupPaths *p);
-
-void lookup_paths_free(LookupPaths *p);
-#define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free)
-
-char **generator_binary_paths(UnitFileScope scope);
diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
deleted file mode 100644
index 293c6673fc..0000000000
--- a/src/shared/ptyfwd.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010-2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "sd-event.h"
-
-#include "alloc-util.h"
-#include "fd-util.h"
-#include "log.h"
-#include "macro.h"
-#include "ptyfwd.h"
-#include "time-util.h"
-
-struct PTYForward {
- sd_event *event;
-
- int master;
-
- PTYForwardFlags flags;
-
- sd_event_source *stdin_event_source;
- sd_event_source *stdout_event_source;
- sd_event_source *master_event_source;
-
- sd_event_source *sigwinch_event_source;
-
- struct termios saved_stdin_attr;
- struct termios saved_stdout_attr;
-
- bool saved_stdin:1;
- bool saved_stdout:1;
-
- bool stdin_readable:1;
- bool stdin_hangup:1;
- bool stdout_writable:1;
- bool stdout_hangup:1;
- bool master_readable:1;
- bool master_writable:1;
- bool master_hangup:1;
-
- bool read_from_master:1;
-
- bool done:1;
-
- bool last_char_set:1;
- char last_char;
-
- char in_buffer[LINE_MAX], out_buffer[LINE_MAX];
- size_t in_buffer_full, out_buffer_full;
-
- usec_t escape_timestamp;
- unsigned escape_counter;
-
- PTYForwardHandler handler;
- void *userdata;
-};
-
-#define ESCAPE_USEC (1*USEC_PER_SEC)
-
-static void pty_forward_disconnect(PTYForward *f) {
-
- if (f) {
- f->stdin_event_source = sd_event_source_unref(f->stdin_event_source);
- f->stdout_event_source = sd_event_source_unref(f->stdout_event_source);
-
- f->master_event_source = sd_event_source_unref(f->master_event_source);
- f->sigwinch_event_source = sd_event_source_unref(f->sigwinch_event_source);
- f->event = sd_event_unref(f->event);
-
- if (f->saved_stdout)
- tcsetattr(STDOUT_FILENO, TCSANOW, &f->saved_stdout_attr);
- if (f->saved_stdin)
- tcsetattr(STDIN_FILENO, TCSANOW, &f->saved_stdin_attr);
-
- f->saved_stdout = f->saved_stdin = false;
- }
-
- /* STDIN/STDOUT should not be nonblocking normally, so let's unconditionally reset it */
- fd_nonblock(STDIN_FILENO, false);
- fd_nonblock(STDOUT_FILENO, false);
-}
-
-static int pty_forward_done(PTYForward *f, int rcode) {
- _cleanup_(sd_event_unrefp) sd_event *e = NULL;
- assert(f);
-
- if (f->done)
- return 0;
-
- e = sd_event_ref(f->event);
-
- f->done = true;
- pty_forward_disconnect(f);
-
- if (f->handler)
- return f->handler(f, rcode, f->userdata);
- else
- return sd_event_exit(e, rcode < 0 ? EXIT_FAILURE : rcode);
-}
-
-static bool look_for_escape(PTYForward *f, const char *buffer, size_t n) {
- const char *p;
-
- assert(f);
- assert(buffer);
- assert(n > 0);
-
- for (p = buffer; p < buffer + n; p++) {
-
- /* Check for ^] */
- if (*p == 0x1D) {
- usec_t nw = now(CLOCK_MONOTONIC);
-
- if (f->escape_counter == 0 || nw > f->escape_timestamp + ESCAPE_USEC) {
- f->escape_timestamp = nw;
- f->escape_counter = 1;
- } else {
- (f->escape_counter)++;
-
- if (f->escape_counter >= 3)
- return true;
- }
- } else {
- f->escape_timestamp = 0;
- f->escape_counter = 0;
- }
- }
-
- return false;
-}
-
-static bool ignore_vhangup(PTYForward *f) {
- assert(f);
-
- if (f->flags & PTY_FORWARD_IGNORE_VHANGUP)
- return true;
-
- if ((f->flags & PTY_FORWARD_IGNORE_INITIAL_VHANGUP) && !f->read_from_master)
- return true;
-
- return false;
-}
-
-static int shovel(PTYForward *f) {
- ssize_t k;
-
- assert(f);
-
- while ((f->stdin_readable && f->in_buffer_full <= 0) ||
- (f->master_writable && f->in_buffer_full > 0) ||
- (f->master_readable && f->out_buffer_full <= 0) ||
- (f->stdout_writable && f->out_buffer_full > 0)) {
-
- if (f->stdin_readable && f->in_buffer_full < LINE_MAX) {
-
- k = read(STDIN_FILENO, f->in_buffer + f->in_buffer_full, LINE_MAX - f->in_buffer_full);
- if (k < 0) {
-
- if (errno == EAGAIN)
- f->stdin_readable = false;
- else if (errno == EIO || errno == EPIPE || errno == ECONNRESET) {
- f->stdin_readable = false;
- f->stdin_hangup = true;
-
- f->stdin_event_source = sd_event_source_unref(f->stdin_event_source);
- } else {
- log_error_errno(errno, "read(): %m");
- return pty_forward_done(f, -errno);
- }
- } else if (k == 0) {
- /* EOF on stdin */
- f->stdin_readable = false;
- f->stdin_hangup = true;
-
- f->stdin_event_source = sd_event_source_unref(f->stdin_event_source);
- } else {
- /* Check if ^] has been pressed three times within one second. If we get this we quite
- * immediately. */
- if (look_for_escape(f, f->in_buffer + f->in_buffer_full, k))
- return pty_forward_done(f, -ECANCELED);
-
- f->in_buffer_full += (size_t) k;
- }
- }
-
- if (f->master_writable && f->in_buffer_full > 0) {
-
- k = write(f->master, f->in_buffer, f->in_buffer_full);
- if (k < 0) {
-
- if (errno == EAGAIN || errno == EIO)
- f->master_writable = false;
- else if (errno == EPIPE || errno == ECONNRESET) {
- f->master_writable = f->master_readable = false;
- f->master_hangup = true;
-
- f->master_event_source = sd_event_source_unref(f->master_event_source);
- } else {
- log_error_errno(errno, "write(): %m");
- return pty_forward_done(f, -errno);
- }
- } else {
- assert(f->in_buffer_full >= (size_t) k);
- memmove(f->in_buffer, f->in_buffer + k, f->in_buffer_full - k);
- f->in_buffer_full -= k;
- }
- }
-
- if (f->master_readable && f->out_buffer_full < LINE_MAX) {
-
- k = read(f->master, f->out_buffer + f->out_buffer_full, LINE_MAX - f->out_buffer_full);
- if (k < 0) {
-
- /* Note that EIO on the master device
- * might be caused by vhangup() or
- * temporary closing of everything on
- * the other side, we treat it like
- * EAGAIN here and try again, unless
- * ignore_vhangup is off. */
-
- if (errno == EAGAIN || (errno == EIO && ignore_vhangup(f)))
- f->master_readable = false;
- else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) {
- f->master_readable = f->master_writable = false;
- f->master_hangup = true;
-
- f->master_event_source = sd_event_source_unref(f->master_event_source);
- } else {
- log_error_errno(errno, "read(): %m");
- return pty_forward_done(f, -errno);
- }
- } else {
- f->read_from_master = true;
- f->out_buffer_full += (size_t) k;
- }
- }
-
- if (f->stdout_writable && f->out_buffer_full > 0) {
-
- k = write(STDOUT_FILENO, f->out_buffer, f->out_buffer_full);
- if (k < 0) {
-
- if (errno == EAGAIN)
- f->stdout_writable = false;
- else if (errno == EIO || errno == EPIPE || errno == ECONNRESET) {
- f->stdout_writable = false;
- f->stdout_hangup = true;
- f->stdout_event_source = sd_event_source_unref(f->stdout_event_source);
- } else {
- log_error_errno(errno, "write(): %m");
- return pty_forward_done(f, -errno);
- }
-
- } else {
-
- if (k > 0) {
- f->last_char = f->out_buffer[k-1];
- f->last_char_set = true;
- }
-
- assert(f->out_buffer_full >= (size_t) k);
- memmove(f->out_buffer, f->out_buffer + k, f->out_buffer_full - k);
- f->out_buffer_full -= k;
- }
- }
- }
-
- if (f->stdin_hangup || f->stdout_hangup || f->master_hangup) {
- /* Exit the loop if any side hung up and if there's
- * nothing more to write or nothing we could write. */
-
- if ((f->out_buffer_full <= 0 || f->stdout_hangup) &&
- (f->in_buffer_full <= 0 || f->master_hangup))
- return pty_forward_done(f, 0);
- }
-
- return 0;
-}
-
-static int on_master_event(sd_event_source *e, int fd, uint32_t revents, void *userdata) {
- PTYForward *f = userdata;
-
- assert(f);
- assert(e);
- assert(e == f->master_event_source);
- assert(fd >= 0);
- assert(fd == f->master);
-
- if (revents & (EPOLLIN|EPOLLHUP))
- f->master_readable = true;
-
- if (revents & (EPOLLOUT|EPOLLHUP))
- f->master_writable = true;
-
- return shovel(f);
-}
-
-static int on_stdin_event(sd_event_source *e, int fd, uint32_t revents, void *userdata) {
- PTYForward *f = userdata;
-
- assert(f);
- assert(e);
- assert(e == f->stdin_event_source);
- assert(fd >= 0);
- assert(fd == STDIN_FILENO);
-
- if (revents & (EPOLLIN|EPOLLHUP))
- f->stdin_readable = true;
-
- return shovel(f);
-}
-
-static int on_stdout_event(sd_event_source *e, int fd, uint32_t revents, void *userdata) {
- PTYForward *f = userdata;
-
- assert(f);
- assert(e);
- assert(e == f->stdout_event_source);
- assert(fd >= 0);
- assert(fd == STDOUT_FILENO);
-
- if (revents & (EPOLLOUT|EPOLLHUP))
- f->stdout_writable = true;
-
- return shovel(f);
-}
-
-static int on_sigwinch_event(sd_event_source *e, const struct signalfd_siginfo *si, void *userdata) {
- PTYForward *f = userdata;
- struct winsize ws;
-
- assert(f);
- assert(e);
- assert(e == f->sigwinch_event_source);
-
- /* The window size changed, let's forward that. */
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
- (void) ioctl(f->master, TIOCSWINSZ, &ws);
-
- return 0;
-}
-
-int pty_forward_new(
- sd_event *event,
- int master,
- PTYForwardFlags flags,
- PTYForward **ret) {
-
- _cleanup_(pty_forward_freep) PTYForward *f = NULL;
- struct winsize ws;
- int r;
-
- f = new0(PTYForward, 1);
- if (!f)
- return -ENOMEM;
-
- f->flags = flags;
-
- if (event)
- f->event = sd_event_ref(event);
- else {
- r = sd_event_default(&f->event);
- if (r < 0)
- return r;
- }
-
- if (!(flags & PTY_FORWARD_READ_ONLY)) {
- r = fd_nonblock(STDIN_FILENO, true);
- if (r < 0)
- return r;
-
- r = fd_nonblock(STDOUT_FILENO, true);
- if (r < 0)
- return r;
- }
-
- r = fd_nonblock(master, true);
- if (r < 0)
- return r;
-
- f->master = master;
-
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
- (void) ioctl(master, TIOCSWINSZ, &ws);
-
- if (!(flags & PTY_FORWARD_READ_ONLY)) {
- if (tcgetattr(STDIN_FILENO, &f->saved_stdin_attr) >= 0) {
- struct termios raw_stdin_attr;
-
- f->saved_stdin = true;
-
- raw_stdin_attr = f->saved_stdin_attr;
- cfmakeraw(&raw_stdin_attr);
- raw_stdin_attr.c_oflag = f->saved_stdin_attr.c_oflag;
- tcsetattr(STDIN_FILENO, TCSANOW, &raw_stdin_attr);
- }
-
- if (tcgetattr(STDOUT_FILENO, &f->saved_stdout_attr) >= 0) {
- struct termios raw_stdout_attr;
-
- f->saved_stdout = true;
-
- raw_stdout_attr = f->saved_stdout_attr;
- cfmakeraw(&raw_stdout_attr);
- raw_stdout_attr.c_iflag = f->saved_stdout_attr.c_iflag;
- raw_stdout_attr.c_lflag = f->saved_stdout_attr.c_lflag;
- tcsetattr(STDOUT_FILENO, TCSANOW, &raw_stdout_attr);
- }
-
- r = sd_event_add_io(f->event, &f->stdin_event_source, STDIN_FILENO, EPOLLIN|EPOLLET, on_stdin_event, f);
- if (r < 0 && r != -EPERM)
- return r;
- }
-
- r = sd_event_add_io(f->event, &f->stdout_event_source, STDOUT_FILENO, EPOLLOUT|EPOLLET, on_stdout_event, f);
- if (r == -EPERM)
- /* stdout without epoll support. Likely redirected to regular file. */
- f->stdout_writable = true;
- else if (r < 0)
- return r;
-
- r = sd_event_add_io(f->event, &f->master_event_source, master, EPOLLIN|EPOLLOUT|EPOLLET, on_master_event, f);
- if (r < 0)
- return r;
-
- r = sd_event_add_signal(f->event, &f->sigwinch_event_source, SIGWINCH, on_sigwinch_event, f);
- if (r < 0)
- return r;
-
- *ret = f;
- f = NULL;
-
- return 0;
-}
-
-PTYForward *pty_forward_free(PTYForward *f) {
- pty_forward_disconnect(f);
- return mfree(f);
-}
-
-int pty_forward_get_last_char(PTYForward *f, char *ch) {
- assert(f);
- assert(ch);
-
- if (!f->last_char_set)
- return -ENXIO;
-
- *ch = f->last_char;
- return 0;
-}
-
-int pty_forward_set_ignore_vhangup(PTYForward *f, bool b) {
- int r;
-
- assert(f);
-
- if (!!(f->flags & PTY_FORWARD_IGNORE_VHANGUP) == b)
- return 0;
-
- SET_FLAG(f->flags, PTY_FORWARD_IGNORE_VHANGUP, b);
-
- if (!ignore_vhangup(f)) {
-
- /* We shall now react to vhangup()s? Let's check
- * immediately if we might be in one */
-
- f->master_readable = true;
- r = shovel(f);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-bool pty_forward_get_ignore_vhangup(PTYForward *f) {
- assert(f);
-
- return !!(f->flags & PTY_FORWARD_IGNORE_VHANGUP);
-}
-
-bool pty_forward_is_done(PTYForward *f) {
- assert(f);
-
- return f->done;
-}
-
-void pty_forward_set_handler(PTYForward *f, PTYForwardHandler cb, void *userdata) {
- assert(f);
-
- f->handler = cb;
- f->userdata = userdata;
-}
diff --git a/src/shared/ptyfwd.h b/src/shared/ptyfwd.h
deleted file mode 100644
index bd5d5fec0d..0000000000
--- a/src/shared/ptyfwd.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010-2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include "sd-event.h"
-
-#include "macro.h"
-
-typedef struct PTYForward PTYForward;
-
-typedef enum PTYForwardFlags {
- PTY_FORWARD_READ_ONLY = 1,
-
- /* Continue reading after hangup? */
- PTY_FORWARD_IGNORE_VHANGUP = 2,
-
- /* Continue reading after hangup but only if we never read anything else? */
- PTY_FORWARD_IGNORE_INITIAL_VHANGUP = 4,
-} PTYForwardFlags;
-
-typedef int (*PTYForwardHandler)(PTYForward *f, int rcode, void*userdata);
-
-int pty_forward_new(sd_event *event, int master, PTYForwardFlags flags, PTYForward **f);
-PTYForward *pty_forward_free(PTYForward *f);
-
-int pty_forward_get_last_char(PTYForward *f, char *ch);
-
-int pty_forward_set_ignore_vhangup(PTYForward *f, bool ignore_vhangup);
-bool pty_forward_get_ignore_vhangup(PTYForward *f);
-
-bool pty_forward_is_done(PTYForward *f);
-
-void pty_forward_set_handler(PTYForward *f, PTYForwardHandler handler, void *userdata);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(PTYForward*, pty_forward_free);
diff --git a/src/shared/resolve-util.c b/src/shared/resolve-util.c
deleted file mode 100644
index e2da81bab7..0000000000
--- a/src/shared/resolve-util.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "conf-parser.h"
-#include "resolve-util.h"
-#include "string-table.h"
-
-DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_support, resolve_support, ResolveSupport, "Failed to parse resolve support setting");
-DEFINE_CONFIG_PARSE_ENUM(config_parse_dnssec_mode, dnssec_mode, DnssecMode, "Failed to parse DNSSEC mode setting");
-
-static const char* const resolve_support_table[_RESOLVE_SUPPORT_MAX] = {
- [RESOLVE_SUPPORT_NO] = "no",
- [RESOLVE_SUPPORT_YES] = "yes",
- [RESOLVE_SUPPORT_RESOLVE] = "resolve",
-};
-DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(resolve_support, ResolveSupport, RESOLVE_SUPPORT_YES);
-
-static const char* const dnssec_mode_table[_DNSSEC_MODE_MAX] = {
- [DNSSEC_NO] = "no",
- [DNSSEC_ALLOW_DOWNGRADE] = "allow-downgrade",
- [DNSSEC_YES] = "yes",
-};
-DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dnssec_mode, DnssecMode, DNSSEC_YES);
diff --git a/src/shared/resolve-util.h b/src/shared/resolve-util.h
deleted file mode 100644
index 8636a6c134..0000000000
--- a/src/shared/resolve-util.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "macro.h"
-
-typedef enum ResolveSupport ResolveSupport;
-typedef enum DnssecMode DnssecMode;
-
-enum ResolveSupport {
- RESOLVE_SUPPORT_NO,
- RESOLVE_SUPPORT_YES,
- RESOLVE_SUPPORT_RESOLVE,
- _RESOLVE_SUPPORT_MAX,
- _RESOLVE_SUPPORT_INVALID = -1
-};
-
-enum DnssecMode {
- /* No DNSSEC validation is done */
- DNSSEC_NO,
-
- /* Validate locally, if the server knows DO, but if not,
- * don't. Don't trust the AD bit. If the server doesn't do
- * DNSSEC properly, downgrade to non-DNSSEC operation. Of
- * course, we then are vulnerable to a downgrade attack, but
- * that's life and what is configured. */
- DNSSEC_ALLOW_DOWNGRADE,
-
- /* Insist on DNSSEC server support, and rather fail than downgrading. */
- DNSSEC_YES,
-
- _DNSSEC_MODE_MAX,
- _DNSSEC_MODE_INVALID = -1
-};
-
-int config_parse_resolve_support(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_dnssec_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-
-const char* resolve_support_to_string(ResolveSupport p) _const_;
-ResolveSupport resolve_support_from_string(const char *s) _pure_;
-
-const char* dnssec_mode_to_string(DnssecMode p) _const_;
-DnssecMode dnssec_mode_from_string(const char *s) _pure_;
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
deleted file mode 100644
index c9b24f1065..0000000000
--- a/src/shared/seccomp-util.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <seccomp.h>
-#include <stddef.h>
-#include <sys/prctl.h>
-#include <linux/seccomp.h>
-
-#include "macro.h"
-#include "seccomp-util.h"
-#include "string-util.h"
-#include "util.h"
-
-const char* seccomp_arch_to_string(uint32_t c) {
- /* Maintain order used in <seccomp.h>.
- *
- * Names used here should be the same as those used for ConditionArchitecture=,
- * except for "subarchitectures" like x32. */
-
- switch(c) {
- case SCMP_ARCH_NATIVE:
- return "native";
- case SCMP_ARCH_X86:
- return "x86";
- case SCMP_ARCH_X86_64:
- return "x86-64";
- case SCMP_ARCH_X32:
- return "x32";
- case SCMP_ARCH_ARM:
- return "arm";
- case SCMP_ARCH_AARCH64:
- return "arm64";
- case SCMP_ARCH_MIPS:
- return "mips";
- case SCMP_ARCH_MIPS64:
- return "mips64";
- case SCMP_ARCH_MIPS64N32:
- return "mips64-n32";
- case SCMP_ARCH_MIPSEL:
- return "mips-le";
- case SCMP_ARCH_MIPSEL64:
- return "mips64-le";
- case SCMP_ARCH_MIPSEL64N32:
- return "mips64-le-n32";
- case SCMP_ARCH_PPC:
- return "ppc";
- case SCMP_ARCH_PPC64:
- return "ppc64";
- case SCMP_ARCH_PPC64LE:
- return "ppc64-le";
- case SCMP_ARCH_S390:
- return "s390";
- case SCMP_ARCH_S390X:
- return "s390x";
- default:
- return NULL;
- }
-}
-
-int seccomp_arch_from_string(const char *n, uint32_t *ret) {
- if (!n)
- return -EINVAL;
-
- assert(ret);
-
- if (streq(n, "native"))
- *ret = SCMP_ARCH_NATIVE;
- else if (streq(n, "x86"))
- *ret = SCMP_ARCH_X86;
- else if (streq(n, "x86-64"))
- *ret = SCMP_ARCH_X86_64;
- else if (streq(n, "x32"))
- *ret = SCMP_ARCH_X32;
- else if (streq(n, "arm"))
- *ret = SCMP_ARCH_ARM;
- else if (streq(n, "arm64"))
- *ret = SCMP_ARCH_AARCH64;
- else if (streq(n, "mips"))
- *ret = SCMP_ARCH_MIPS;
- else if (streq(n, "mips64"))
- *ret = SCMP_ARCH_MIPS64;
- else if (streq(n, "mips64-n32"))
- *ret = SCMP_ARCH_MIPS64N32;
- else if (streq(n, "mips-le"))
- *ret = SCMP_ARCH_MIPSEL;
- else if (streq(n, "mips64-le"))
- *ret = SCMP_ARCH_MIPSEL64;
- else if (streq(n, "mips64-le-n32"))
- *ret = SCMP_ARCH_MIPSEL64N32;
- else if (streq(n, "ppc"))
- *ret = SCMP_ARCH_PPC;
- else if (streq(n, "ppc64"))
- *ret = SCMP_ARCH_PPC64;
- else if (streq(n, "ppc64-le"))
- *ret = SCMP_ARCH_PPC64LE;
- else if (streq(n, "s390"))
- *ret = SCMP_ARCH_S390;
- else if (streq(n, "s390x"))
- *ret = SCMP_ARCH_S390X;
- else
- return -EINVAL;
-
- return 0;
-}
-
-int seccomp_init_conservative(scmp_filter_ctx *ret, uint32_t default_action) {
- scmp_filter_ctx seccomp;
- int r;
-
- /* Much like seccomp_init(), but tries to be a bit more conservative in its defaults: all secondary archs are
- * added by default, and NNP is turned off. */
-
- seccomp = seccomp_init(default_action);
- if (!seccomp)
- return -ENOMEM;
-
- r = seccomp_add_secondary_archs(seccomp);
- if (r < 0)
- goto finish;
-
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
- if (r < 0)
- goto finish;
-
- *ret = seccomp;
- return 0;
-
-finish:
- seccomp_release(seccomp);
- return r;
-}
-
-int seccomp_add_secondary_archs(scmp_filter_ctx ctx) {
-
- /* Add in all possible secondary archs we are aware of that
- * this kernel might support. */
-
- static const int seccomp_arches[] = {
-#if defined(__i386__) || defined(__x86_64__)
- SCMP_ARCH_X86,
- SCMP_ARCH_X86_64,
- SCMP_ARCH_X32,
-
-#elif defined(__arm__) || defined(__aarch64__)
- SCMP_ARCH_ARM,
- SCMP_ARCH_AARCH64,
-
-#elif defined(__arm__) || defined(__aarch64__)
- SCMP_ARCH_ARM,
- SCMP_ARCH_AARCH64,
-
-#elif defined(__mips__) || defined(__mips64__)
- SCMP_ARCH_MIPS,
- SCMP_ARCH_MIPS64,
- SCMP_ARCH_MIPS64N32,
- SCMP_ARCH_MIPSEL,
- SCMP_ARCH_MIPSEL64,
- SCMP_ARCH_MIPSEL64N32,
-
-#elif defined(__powerpc__) || defined(__powerpc64__)
- SCMP_ARCH_PPC,
- SCMP_ARCH_PPC64,
- SCMP_ARCH_PPC64LE,
-
-#elif defined(__s390__) || defined(__s390x__)
- SCMP_ARCH_S390,
- SCMP_ARCH_S390X,
-#endif
- };
-
- unsigned i;
- int r;
-
- for (i = 0; i < ELEMENTSOF(seccomp_arches); i++) {
- r = seccomp_arch_add(ctx, seccomp_arches[i]);
- if (r < 0 && r != -EEXIST)
- return r;
- }
-
- return 0;
-}
-
-static bool is_basic_seccomp_available(void) {
- int r;
- r = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
- return r >= 0;
-}
-
-static bool is_seccomp_filter_available(void) {
- int r;
- r = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
- return r < 0 && errno == EFAULT;
-}
-
-bool is_seccomp_available(void) {
- static int cached_enabled = -1;
- if (cached_enabled < 0)
- cached_enabled = is_basic_seccomp_available() && is_seccomp_filter_available();
- return cached_enabled;
-}
-
-const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
- [SYSCALL_FILTER_SET_BASIC_IO] = {
- /* Basic IO */
- .name = "@basic-io",
- .value =
- "close\0"
- "dup2\0"
- "dup3\0"
- "dup\0"
- "lseek\0"
- "pread64\0"
- "preadv\0"
- "pwrite64\0"
- "pwritev\0"
- "read\0"
- "readv\0"
- "write\0"
- "writev\0"
- },
- [SYSCALL_FILTER_SET_CLOCK] = {
- /* Clock */
- .name = "@clock",
- .value =
- "adjtimex\0"
- "clock_adjtime\0"
- "clock_settime\0"
- "settimeofday\0"
- "stime\0"
- },
- [SYSCALL_FILTER_SET_CPU_EMULATION] = {
- /* CPU emulation calls */
- .name = "@cpu-emulation",
- .value =
- "modify_ldt\0"
- "subpage_prot\0"
- "switch_endian\0"
- "vm86\0"
- "vm86old\0"
- },
- [SYSCALL_FILTER_SET_DEBUG] = {
- /* Debugging/Performance Monitoring/Tracing */
- .name = "@debug",
- .value =
- "lookup_dcookie\0"
- "perf_event_open\0"
- "process_vm_readv\0"
- "process_vm_writev\0"
- "ptrace\0"
- "rtas\0"
-#ifdef __NR_s390_runtime_instr
- "s390_runtime_instr\0"
-#endif
- "sys_debug_setcontext\0"
- },
- [SYSCALL_FILTER_SET_DEFAULT] = {
- /* Default list: the most basic of operations */
- .name = "@default",
- .value =
- "clock_getres\0"
- "clock_gettime\0"
- "clock_nanosleep\0"
- "execve\0"
- "exit\0"
- "exit_group\0"
- "getrlimit\0" /* make sure processes can query stack size and such */
- "gettimeofday\0"
- "nanosleep\0"
- "pause\0"
- "rt_sigreturn\0"
- "sigreturn\0"
- "time\0"
- },
- [SYSCALL_FILTER_SET_IO_EVENT] = {
- /* Event loop use */
- .name = "@io-event",
- .value =
- "_newselect\0"
- "epoll_create1\0"
- "epoll_create\0"
- "epoll_ctl\0"
- "epoll_ctl_old\0"
- "epoll_pwait\0"
- "epoll_wait\0"
- "epoll_wait_old\0"
- "eventfd2\0"
- "eventfd\0"
- "poll\0"
- "ppoll\0"
- "pselect6\0"
- "select\0"
- },
- [SYSCALL_FILTER_SET_IPC] = {
- /* Message queues, SYSV IPC or other IPC */
- .name = "@ipc",
- .value = "ipc\0"
- "memfd_create\0"
- "mq_getsetattr\0"
- "mq_notify\0"
- "mq_open\0"
- "mq_timedreceive\0"
- "mq_timedsend\0"
- "mq_unlink\0"
- "msgctl\0"
- "msgget\0"
- "msgrcv\0"
- "msgsnd\0"
- "pipe2\0"
- "pipe\0"
- "process_vm_readv\0"
- "process_vm_writev\0"
- "semctl\0"
- "semget\0"
- "semop\0"
- "semtimedop\0"
- "shmat\0"
- "shmctl\0"
- "shmdt\0"
- "shmget\0"
- },
- [SYSCALL_FILTER_SET_KEYRING] = {
- /* Keyring */
- .name = "@keyring",
- .value =
- "add_key\0"
- "keyctl\0"
- "request_key\0"
- },
- [SYSCALL_FILTER_SET_MODULE] = {
- /* Kernel module control */
- .name = "@module",
- .value =
- "delete_module\0"
- "finit_module\0"
- "init_module\0"
- },
- [SYSCALL_FILTER_SET_MOUNT] = {
- /* Mounting */
- .name = "@mount",
- .value =
- "chroot\0"
- "mount\0"
- "pivot_root\0"
- "umount2\0"
- "umount\0"
- },
- [SYSCALL_FILTER_SET_NETWORK_IO] = {
- /* Network or Unix socket IO, should not be needed if not network facing */
- .name = "@network-io",
- .value =
- "accept4\0"
- "accept\0"
- "bind\0"
- "connect\0"
- "getpeername\0"
- "getsockname\0"
- "getsockopt\0"
- "listen\0"
- "recv\0"
- "recvfrom\0"
- "recvmmsg\0"
- "recvmsg\0"
- "send\0"
- "sendmmsg\0"
- "sendmsg\0"
- "sendto\0"
- "setsockopt\0"
- "shutdown\0"
- "socket\0"
- "socketcall\0"
- "socketpair\0"
- },
- [SYSCALL_FILTER_SET_OBSOLETE] = {
- /* Unusual, obsolete or unimplemented, some unknown even to libseccomp */
- .name = "@obsolete",
- .value =
- "_sysctl\0"
- "afs_syscall\0"
- "break\0"
- "create_module\0"
- "ftime\0"
- "get_kernel_syms\0"
- "getpmsg\0"
- "gtty\0"
- "lock\0"
- "mpx\0"
- "prof\0"
- "profil\0"
- "putpmsg\0"
- "query_module\0"
- "security\0"
- "sgetmask\0"
- "ssetmask\0"
- "stty\0"
- "sysfs\0"
- "tuxcall\0"
- "ulimit\0"
- "uselib\0"
- "ustat\0"
- "vserver\0"
- },
- [SYSCALL_FILTER_SET_PRIVILEGED] = {
- /* Nice grab-bag of all system calls which need superuser capabilities */
- .name = "@privileged",
- .value =
- "@clock\0"
- "@module\0"
- "@raw-io\0"
- "acct\0"
- "bdflush\0"
- "bpf\0"
- "capset\0"
- "chown32\0"
- "chown\0"
- "chroot\0"
- "fchown32\0"
- "fchown\0"
- "fchownat\0"
- "kexec_file_load\0"
- "kexec_load\0"
- "lchown32\0"
- "lchown\0"
- "nfsservctl\0"
- "pivot_root\0"
- "quotactl\0"
- "reboot\0"
- "setdomainname\0"
- "setfsuid32\0"
- "setfsuid\0"
- "setgroups32\0"
- "setgroups\0"
- "sethostname\0"
- "setresuid32\0"
- "setresuid\0"
- "setreuid32\0"
- "setreuid\0"
- "setuid32\0"
- "setuid\0"
- "swapoff\0"
- "swapon\0"
- "_sysctl\0"
- "vhangup\0"
- },
- [SYSCALL_FILTER_SET_PROCESS] = {
- /* Process control, execution, namespaces */
- .name = "@process",
- .value =
- "arch_prctl\0"
- "clone\0"
- "execveat\0"
- "fork\0"
- "kill\0"
- "prctl\0"
- "setns\0"
- "tgkill\0"
- "tkill\0"
- "unshare\0"
- "vfork\0"
- },
- [SYSCALL_FILTER_SET_RAW_IO] = {
- /* Raw I/O ports */
- .name = "@raw-io",
- .value =
- "ioperm\0"
- "iopl\0"
- "pciconfig_iobase\0"
- "pciconfig_read\0"
- "pciconfig_write\0"
-#ifdef __NR_s390_pci_mmio_read
- "s390_pci_mmio_read\0"
-#endif
-#ifdef __NR_s390_pci_mmio_write
- "s390_pci_mmio_write\0"
-#endif
- },
- [SYSCALL_FILTER_SET_RESOURCES] = {
- /* Alter resource settings */
- .name = "@resources",
- .value =
- "sched_setparam\0"
- "sched_setscheduler\0"
- "sched_setaffinity\0"
- "setpriority\0"
- "setrlimit\0"
- "set_mempolicy\0"
- "migrate_pages\0"
- "move_pages\0"
- "mbind\0"
- "sched_setattr\0"
- "prlimit64\0"
- },
-};
-
-const SyscallFilterSet *syscall_filter_set_find(const char *name) {
- unsigned i;
-
- if (isempty(name) || name[0] != '@')
- return NULL;
-
- for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++)
- if (streq(syscall_filter_sets[i].name, name))
- return syscall_filter_sets + i;
-
- return NULL;
-}
-
-int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action) {
- const char *sys;
- int r;
-
- assert(seccomp);
- assert(set);
-
- NULSTR_FOREACH(sys, set->value) {
- int id;
-
- if (sys[0] == '@') {
- const SyscallFilterSet *other;
-
- other = syscall_filter_set_find(sys);
- if (!other)
- return -EINVAL;
-
- r = seccomp_add_syscall_filter_set(seccomp, other, action);
- } else {
- id = seccomp_syscall_resolve_name(sys);
- if (id == __NR_SCMP_ERROR)
- return -EINVAL;
-
- r = seccomp_rule_add(seccomp, action, id, 0);
- }
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-int seccomp_load_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action) {
- scmp_filter_ctx seccomp;
- int r;
-
- assert(set);
-
- /* The one-stop solution: allocate a seccomp object, add a filter to it, and apply it */
-
- r = seccomp_init_conservative(&seccomp, default_action);
- if (r < 0)
- return r;
-
- r = seccomp_add_syscall_filter_set(seccomp, set, action);
- if (r < 0)
- goto finish;
-
- r = seccomp_load(seccomp);
-
-finish:
- seccomp_release(seccomp);
- return r;
-
-}
diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h
deleted file mode 100644
index 8e209efef2..0000000000
--- a/src/shared/seccomp-util.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <seccomp.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-const char* seccomp_arch_to_string(uint32_t c);
-int seccomp_arch_from_string(const char *n, uint32_t *ret);
-
-int seccomp_init_conservative(scmp_filter_ctx *ret, uint32_t default_action);
-
-int seccomp_add_secondary_archs(scmp_filter_ctx c);
-
-bool is_seccomp_available(void);
-
-typedef struct SyscallFilterSet {
- const char *name;
- const char *value;
-} SyscallFilterSet;
-
-enum {
- SYSCALL_FILTER_SET_BASIC_IO,
- SYSCALL_FILTER_SET_CLOCK,
- SYSCALL_FILTER_SET_CPU_EMULATION,
- SYSCALL_FILTER_SET_DEBUG,
- SYSCALL_FILTER_SET_DEFAULT,
- SYSCALL_FILTER_SET_IO_EVENT,
- SYSCALL_FILTER_SET_IPC,
- SYSCALL_FILTER_SET_KEYRING,
- SYSCALL_FILTER_SET_MODULE,
- SYSCALL_FILTER_SET_MOUNT,
- SYSCALL_FILTER_SET_NETWORK_IO,
- SYSCALL_FILTER_SET_OBSOLETE,
- SYSCALL_FILTER_SET_PRIVILEGED,
- SYSCALL_FILTER_SET_PROCESS,
- SYSCALL_FILTER_SET_RAW_IO,
- SYSCALL_FILTER_SET_RESOURCES,
- _SYSCALL_FILTER_SET_MAX
-};
-
-extern const SyscallFilterSet syscall_filter_sets[];
-
-const SyscallFilterSet *syscall_filter_set_find(const char *name);
-
-int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action);
-
-int seccomp_load_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action);
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
deleted file mode 100644
index ed31a80c8d..0000000000
--- a/src/shared/sleep-config.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "conf-parser.h"
-#include "def.h"
-#include "env-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "log.h"
-#include "macro.h"
-#include "parse-util.h"
-#include "sleep-config.h"
-#include "string-util.h"
-#include "strv.h"
-
-#define USE(x, y) do { (x) = (y); (y) = NULL; } while (0)
-
-int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
-
- _cleanup_strv_free_ char
- **suspend_mode = NULL, **suspend_state = NULL,
- **hibernate_mode = NULL, **hibernate_state = NULL,
- **hybrid_mode = NULL, **hybrid_state = NULL;
- char **modes, **states;
-
- const ConfigTableItem items[] = {
- { "Sleep", "SuspendMode", config_parse_strv, 0, &suspend_mode },
- { "Sleep", "SuspendState", config_parse_strv, 0, &suspend_state },
- { "Sleep", "HibernateMode", config_parse_strv, 0, &hibernate_mode },
- { "Sleep", "HibernateState", config_parse_strv, 0, &hibernate_state },
- { "Sleep", "HybridSleepMode", config_parse_strv, 0, &hybrid_mode },
- { "Sleep", "HybridSleepState", config_parse_strv, 0, &hybrid_state },
- {}
- };
-
- config_parse_many_nulstr(PKGSYSCONFDIR "/sleep.conf",
- CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
- "Sleep\0", config_item_table_lookup, items,
- false, NULL);
-
- if (streq(verb, "suspend")) {
- /* empty by default */
- USE(modes, suspend_mode);
-
- if (suspend_state)
- USE(states, suspend_state);
- else
- states = strv_new("mem", "standby", "freeze", NULL);
-
- } else if (streq(verb, "hibernate")) {
- if (hibernate_mode)
- USE(modes, hibernate_mode);
- else
- modes = strv_new("platform", "shutdown", NULL);
-
- if (hibernate_state)
- USE(states, hibernate_state);
- else
- states = strv_new("disk", NULL);
-
- } else if (streq(verb, "hybrid-sleep")) {
- if (hybrid_mode)
- USE(modes, hybrid_mode);
- else
- modes = strv_new("suspend", "platform", "shutdown", NULL);
-
- if (hybrid_state)
- USE(states, hybrid_state);
- else
- states = strv_new("disk", NULL);
-
- } else
- assert_not_reached("what verb");
-
- if ((!modes && !streq(verb, "suspend")) || !states) {
- strv_free(modes);
- strv_free(states);
- return log_oom();
- }
-
- *_modes = modes;
- *_states = states;
- return 0;
-}
-
-int can_sleep_state(char **types) {
- char **type;
- int r;
- _cleanup_free_ char *p = NULL;
-
- if (strv_isempty(types))
- return true;
-
- /* If /sys is read-only we cannot sleep */
- if (access("/sys/power/state", W_OK) < 0)
- return false;
-
- r = read_one_line_file("/sys/power/state", &p);
- if (r < 0)
- return false;
-
- STRV_FOREACH(type, types) {
- const char *word, *state;
- size_t l, k;
-
- k = strlen(*type);
- FOREACH_WORD_SEPARATOR(word, l, p, WHITESPACE, state)
- if (l == k && memcmp(word, *type, l) == 0)
- return true;
- }
-
- return false;
-}
-
-int can_sleep_disk(char **types) {
- char **type;
- int r;
- _cleanup_free_ char *p = NULL;
-
- if (strv_isempty(types))
- return true;
-
- /* If /sys is read-only we cannot sleep */
- if (access("/sys/power/disk", W_OK) < 0)
- return false;
-
- r = read_one_line_file("/sys/power/disk", &p);
- if (r < 0)
- return false;
-
- STRV_FOREACH(type, types) {
- const char *word, *state;
- size_t l, k;
-
- k = strlen(*type);
- FOREACH_WORD_SEPARATOR(word, l, p, WHITESPACE, state) {
- if (l == k && memcmp(word, *type, l) == 0)
- return true;
-
- if (l == k + 2 &&
- word[0] == '[' &&
- memcmp(word + 1, *type, l - 2) == 0 &&
- word[l-1] == ']')
- return true;
- }
- }
-
- return false;
-}
-
-#define HIBERNATION_SWAP_THRESHOLD 0.98
-
-static int hibernation_partition_size(size_t *size, size_t *used) {
- _cleanup_fclose_ FILE *f;
- unsigned i;
-
- assert(size);
- assert(used);
-
- f = fopen("/proc/swaps", "re");
- if (!f) {
- log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
- "Failed to retrieve open /proc/swaps: %m");
- assert(errno > 0);
- return -errno;
- }
-
- (void) fscanf(f, "%*s %*s %*s %*s %*s\n");
-
- for (i = 1;; i++) {
- _cleanup_free_ char *dev = NULL, *type = NULL;
- size_t size_field, used_field;
- int k;
-
- k = fscanf(f,
- "%ms " /* device/file */
- "%ms " /* type of swap */
- "%zu " /* swap size */
- "%zu " /* used */
- "%*i\n", /* priority */
- &dev, &type, &size_field, &used_field);
- if (k != 4) {
- if (k == EOF)
- break;
-
- log_warning("Failed to parse /proc/swaps:%u", i);
- continue;
- }
-
- if (streq(type, "partition") && endswith(dev, "\\040(deleted)")) {
- log_warning("Ignoring deleted swapfile '%s'.", dev);
- continue;
- }
-
- *size = size_field;
- *used = used_field;
- return 0;
- }
-
- log_debug("No swap partitions were found.");
- return -ENOSYS;
-}
-
-static bool enough_memory_for_hibernation(void) {
- _cleanup_free_ char *active = NULL;
- unsigned long long act = 0;
- size_t size = 0, used = 0;
- int r;
-
- if (getenv_bool("SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK") > 0)
- return true;
-
- r = hibernation_partition_size(&size, &used);
- if (r < 0)
- return false;
-
- r = get_proc_field("/proc/meminfo", "Active(anon)", WHITESPACE, &active);
- if (r < 0) {
- log_error_errno(r, "Failed to retrieve Active(anon) from /proc/meminfo: %m");
- return false;
- }
-
- r = safe_atollu(active, &act);
- if (r < 0) {
- log_error_errno(r, "Failed to parse Active(anon) from /proc/meminfo: %s: %m",
- active);
- return false;
- }
-
- r = act <= (size - used) * HIBERNATION_SWAP_THRESHOLD;
- log_debug("Hibernation is %spossible, Active(anon)=%llu kB, size=%zu kB, used=%zu kB, threshold=%.2g%%",
- r ? "" : "im", act, size, used, 100*HIBERNATION_SWAP_THRESHOLD);
-
- return r;
-}
-
-int can_sleep(const char *verb) {
- _cleanup_strv_free_ char **modes = NULL, **states = NULL;
- int r;
-
- assert(streq(verb, "suspend") ||
- streq(verb, "hibernate") ||
- streq(verb, "hybrid-sleep"));
-
- r = parse_sleep_config(verb, &modes, &states);
- if (r < 0)
- return false;
-
- if (!can_sleep_state(states) || !can_sleep_disk(modes))
- return false;
-
- return streq(verb, "suspend") || enough_memory_for_hibernation();
-}
diff --git a/src/shared/sleep-config.h b/src/shared/sleep-config.h
deleted file mode 100644
index ad10039ff4..0000000000
--- a/src/shared/sleep-config.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-int parse_sleep_config(const char *verb, char ***modes, char ***states);
-
-int can_sleep(const char *verb);
-int can_sleep_disk(char **types);
-int can_sleep_state(char **types);
diff --git a/src/shared/spawn-ask-password-agent.c b/src/shared/spawn-ask-password-agent.c
deleted file mode 100644
index a46b7525f0..0000000000
--- a/src/shared/spawn-ask-password-agent.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "log.h"
-#include "process-util.h"
-#include "spawn-ask-password-agent.h"
-#include "util.h"
-
-static pid_t agent_pid = 0;
-
-int ask_password_agent_open(void) {
- int r;
-
- if (agent_pid > 0)
- return 0;
-
- /* We check STDIN here, not STDOUT, since this is about input,
- * not output */
- if (!isatty(STDIN_FILENO))
- return 0;
-
- r = fork_agent(&agent_pid,
- NULL, 0,
- SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH,
- SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to fork TTY ask password agent: %m");
-
- return 1;
-}
-
-void ask_password_agent_close(void) {
-
- if (agent_pid <= 0)
- return;
-
- /* Inform agent that we are done */
- (void) kill(agent_pid, SIGTERM);
- (void) kill(agent_pid, SIGCONT);
- (void) wait_for_terminate(agent_pid, NULL);
- agent_pid = 0;
-}
diff --git a/src/shared/spawn-ask-password-agent.h b/src/shared/spawn-ask-password-agent.h
deleted file mode 100644
index fb0749b13f..0000000000
--- a/src/shared/spawn-ask-password-agent.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-int ask_password_agent_open(void);
-void ask_password_agent_close(void);
diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c
deleted file mode 100644
index 7dae4d14fe..0000000000
--- a/src/shared/spawn-polkit-agent.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "fd-util.h"
-#include "io-util.h"
-#include "log.h"
-#include "macro.h"
-#include "process-util.h"
-#include "spawn-polkit-agent.h"
-#include "stdio-util.h"
-#include "time-util.h"
-#include "util.h"
-
-#ifdef ENABLE_POLKIT
-static pid_t agent_pid = 0;
-
-int polkit_agent_open(void) {
- int r;
- int pipe_fd[2];
- char notify_fd[DECIMAL_STR_MAX(int) + 1];
-
- if (agent_pid > 0)
- return 0;
-
- /* Clients that run as root don't need to activate/query polkit */
- if (geteuid() == 0)
- return 0;
-
- /* We check STDIN here, not STDOUT, since this is about input,
- * not output */
- if (!isatty(STDIN_FILENO))
- return 0;
-
- if (pipe2(pipe_fd, 0) < 0)
- return -errno;
-
- xsprintf(notify_fd, "%i", pipe_fd[1]);
-
- r = fork_agent(&agent_pid,
- &pipe_fd[1], 1,
- POLKIT_AGENT_BINARY_PATH,
- POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL);
-
- /* Close the writing side, because that's the one for the agent */
- safe_close(pipe_fd[1]);
-
- if (r < 0)
- log_error_errno(r, "Failed to fork TTY ask password agent: %m");
- else
- /* Wait until the agent closes the fd */
- fd_wait_for_event(pipe_fd[0], POLLHUP, USEC_INFINITY);
-
- safe_close(pipe_fd[0]);
-
- return r;
-}
-
-void polkit_agent_close(void) {
-
- if (agent_pid <= 0)
- return;
-
- /* Inform agent that we are done */
- (void) kill(agent_pid, SIGTERM);
- (void) kill(agent_pid, SIGCONT);
-
- (void) wait_for_terminate(agent_pid, NULL);
- agent_pid = 0;
-}
-
-#else
-
-int polkit_agent_open(void) {
- return 0;
-}
-
-void polkit_agent_close(void) {
-}
-
-#endif
diff --git a/src/shared/spawn-polkit-agent.h b/src/shared/spawn-polkit-agent.h
deleted file mode 100644
index 42b2989ded..0000000000
--- a/src/shared/spawn-polkit-agent.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-int polkit_agent_open(void);
-void polkit_agent_close(void);
diff --git a/src/shared/specifier.c b/src/shared/specifier.c
deleted file mode 100644
index 1c17eb5251..0000000000
--- a/src/shared/specifier.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/utsname.h>
-
-#include "sd-id128.h"
-
-#include "alloc-util.h"
-#include "hostname-util.h"
-#include "macro.h"
-#include "specifier.h"
-#include "string-util.h"
-
-/*
- * Generic infrastructure for replacing %x style specifiers in
- * strings. Will call a callback for each replacement.
- *
- */
-
-int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) {
- char *ret, *t;
- const char *f;
- bool percent = false;
- size_t l;
- int r;
-
- assert(text);
- assert(table);
-
- l = strlen(text);
- ret = new(char, l+1);
- if (!ret)
- return -ENOMEM;
-
- t = ret;
-
- for (f = text; *f; f++, l--) {
-
- if (percent) {
- if (*f == '%')
- *(t++) = '%';
- else {
- const Specifier *i;
-
- for (i = table; i->specifier; i++)
- if (i->specifier == *f)
- break;
-
- if (i->lookup) {
- _cleanup_free_ char *w = NULL;
- char *n;
- size_t k, j;
-
- r = i->lookup(i->specifier, i->data, userdata, &w);
- if (r < 0) {
- free(ret);
- return r;
- }
-
- j = t - ret;
- k = strlen(w);
-
- n = new(char, j + k + l + 1);
- if (!n) {
- free(ret);
- return -ENOMEM;
- }
-
- memcpy(n, ret, j);
- memcpy(n + j, w, k);
-
- free(ret);
-
- ret = n;
- t = n + j + k;
- } else {
- *(t++) = '%';
- *(t++) = *f;
- }
- }
-
- percent = false;
- } else if (*f == '%')
- percent = true;
- else
- *(t++) = *f;
- }
-
- *t = 0;
- *_ret = ret;
- return 0;
-}
-
-/* Generic handler for simple string replacements */
-
-int specifier_string(char specifier, void *data, void *userdata, char **ret) {
- char *n;
-
- n = strdup(strempty(data));
- if (!n)
- return -ENOMEM;
-
- *ret = n;
- return 0;
-}
-
-int specifier_machine_id(char specifier, void *data, void *userdata, char **ret) {
- sd_id128_t id;
- char *n;
- int r;
-
- r = sd_id128_get_machine(&id);
- if (r < 0)
- return r;
-
- n = new(char, 33);
- if (!n)
- return -ENOMEM;
-
- *ret = sd_id128_to_string(id, n);
- return 0;
-}
-
-int specifier_boot_id(char specifier, void *data, void *userdata, char **ret) {
- sd_id128_t id;
- char *n;
- int r;
-
- r = sd_id128_get_boot(&id);
- if (r < 0)
- return r;
-
- n = new(char, 33);
- if (!n)
- return -ENOMEM;
-
- *ret = sd_id128_to_string(id, n);
- return 0;
-}
-
-int specifier_host_name(char specifier, void *data, void *userdata, char **ret) {
- char *n;
-
- n = gethostname_malloc();
- if (!n)
- return -ENOMEM;
-
- *ret = n;
- return 0;
-}
-
-int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret) {
- struct utsname uts;
- char *n;
- int r;
-
- r = uname(&uts);
- if (r < 0)
- return -errno;
-
- n = strdup(uts.release);
- if (!n)
- return -ENOMEM;
-
- *ret = n;
- return 0;
-}
diff --git a/src/shared/specifier.h b/src/shared/specifier.h
deleted file mode 100644
index 6b1623ee61..0000000000
--- a/src/shared/specifier.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-typedef int (*SpecifierCallback)(char specifier, void *data, void *userdata, char **ret);
-
-typedef struct Specifier {
- const char specifier;
- const SpecifierCallback lookup;
- void *data;
-} Specifier;
-
-int specifier_printf(const char *text, const Specifier table[], void *userdata, char **ret);
-
-int specifier_string(char specifier, void *data, void *userdata, char **ret);
-
-int specifier_machine_id(char specifier, void *data, void *userdata, char **ret);
-int specifier_boot_id(char specifier, void *data, void *userdata, char **ret);
-int specifier_host_name(char specifier, void *data, void *userdata, char **ret);
-int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret);
diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c
deleted file mode 100644
index 4eff4f692e..0000000000
--- a/src/shared/switch-root.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2012 Harald Hoyer, Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "base-filesystem.h"
-#include "fd-util.h"
-#include "log.h"
-#include "missing.h"
-#include "mkdir.h"
-#include "path-util.h"
-#include "rm-rf.h"
-#include "stdio-util.h"
-#include "string-util.h"
-#include "switch-root.h"
-#include "user-util.h"
-#include "util.h"
-
-int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot, unsigned long mountflags) {
-
- /* Don't try to unmount/move the old "/", there's no way to do it. */
- static const char move_mounts[] =
- "/dev\0"
- "/proc\0"
- "/sys\0"
- "/run\0";
-
- _cleanup_close_ int old_root_fd = -1;
- struct stat new_root_stat;
- bool old_root_remove;
- const char *i, *temporary_old_root;
-
- if (path_equal(new_root, "/"))
- return 0;
-
- temporary_old_root = strjoina(new_root, oldroot);
- mkdir_p_label(temporary_old_root, 0755);
-
- old_root_remove = in_initrd();
-
- if (stat(new_root, &new_root_stat) < 0)
- return log_error_errno(errno, "Failed to stat directory %s: %m", new_root);
-
- /* Work-around for kernel design: the kernel refuses switching
- * root if any file systems are mounted MS_SHARED. Hence
- * remount them MS_PRIVATE here as a work-around.
- *
- * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
- if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
- log_warning_errno(errno, "Failed to make \"/\" private mount: %m");
-
- NULSTR_FOREACH(i, move_mounts) {
- char new_mount[PATH_MAX];
- struct stat sb;
- size_t n;
-
- n = snprintf(new_mount, sizeof new_mount, "%s%s", new_root, i);
- if (n >= sizeof new_mount) {
- bool move = mountflags & MS_MOVE;
-
- log_warning("New path is too long, %s: %s%s",
- move ? "forcing unmount instead" : "ignoring",
- new_root, i);
-
- if (move)
- if (umount2(i, MNT_FORCE) < 0)
- log_warning_errno(errno, "Failed to unmount %s: %m", i);
- continue;
- }
-
- mkdir_p_label(new_mount, 0755);
-
- if (stat(new_mount, &sb) < 0 ||
- sb.st_dev != new_root_stat.st_dev) {
-
- /* Mount point seems to be mounted already or
- * stat failed. Unmount the old mount point. */
- if (umount2(i, MNT_DETACH) < 0)
- log_warning_errno(errno, "Failed to unmount %s: %m", i);
- continue;
- }
-
- if (mount(i, new_mount, NULL, mountflags, NULL) < 0) {
- if (mountflags & MS_MOVE) {
- log_error_errno(errno, "Failed to move mount %s to %s, forcing unmount: %m", i, new_mount);
-
- if (umount2(i, MNT_FORCE) < 0)
- log_warning_errno(errno, "Failed to unmount %s: %m", i);
-
- } else if (mountflags & MS_BIND)
- log_error_errno(errno, "Failed to bind mount %s to %s: %m", i, new_mount);
- }
- }
-
- /* Do not fail, if base_filesystem_create() fails. Not all
- * switch roots are like base_filesystem_create() wants them
- * to look like. They might even boot, if they are RO and
- * don't have the FS layout. Just ignore the error and
- * switch_root() nevertheless. */
- (void) base_filesystem_create(new_root, UID_INVALID, GID_INVALID);
-
- if (chdir(new_root) < 0)
- return log_error_errno(errno, "Failed to change directory to %s: %m", new_root);
-
- if (old_root_remove) {
- old_root_fd = open("/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY|O_DIRECTORY);
- if (old_root_fd < 0)
- log_warning_errno(errno, "Failed to open root directory: %m");
- }
-
- /* We first try a pivot_root() so that we can umount the old
- * root dir. In many cases (i.e. where rootfs is /), that's
- * not possible however, and hence we simply overmount root */
- if (pivot_root(new_root, temporary_old_root) >= 0) {
-
- /* Immediately get rid of the old root, if detach_oldroot is set.
- * Since we are running off it we need to do this lazily. */
- if (detach_oldroot && umount2(oldroot, MNT_DETACH) < 0)
- log_error_errno(errno, "Failed to lazily umount old root dir %s, %s: %m",
- oldroot,
- errno == ENOENT ? "ignoring" : "leaving it around");
-
- } else if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0)
- return log_error_errno(errno, "Failed to mount moving %s to /: %m", new_root);
-
- if (chroot(".") < 0)
- return log_error_errno(errno, "Failed to change root: %m");
-
- if (chdir("/") < 0)
- return log_error_errno(errno, "Failed to change directory: %m");
-
- if (old_root_fd >= 0) {
- struct stat rb;
-
- if (fstat(old_root_fd, &rb) < 0)
- log_warning_errno(errno, "Failed to stat old root directory, leaving: %m");
- else {
- (void) rm_rf_children(old_root_fd, 0, &rb);
- old_root_fd = -1;
- }
- }
-
- return 0;
-}
diff --git a/src/shared/switch-root.h b/src/shared/switch-root.h
deleted file mode 100644
index a7a080b3e8..0000000000
--- a/src/shared/switch-root.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <stdbool.h>
-/***
- This file is part of systemd.
-
- Copyright 2012 Harald Hoyer, Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot, unsigned long mountflags);
diff --git a/src/shared/sysctl-util.c b/src/shared/sysctl-util.c
deleted file mode 100644
index e1ccb3294c..0000000000
--- a/src/shared/sysctl-util.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdio.h>
-#include <string.h>
-
-#include "fileio.h"
-#include "log.h"
-#include "macro.h"
-#include "string-util.h"
-#include "sysctl-util.h"
-
-char *sysctl_normalize(char *s) {
- char *n;
-
- n = strpbrk(s, "/.");
- /* If the first separator is a slash, the path is
- * assumed to be normalized and slashes remain slashes
- * and dots remains dots. */
- if (!n || *n == '/')
- return s;
-
- /* Otherwise, dots become slashes and slashes become
- * dots. Fun. */
- while (n) {
- if (*n == '.')
- *n = '/';
- else
- *n = '.';
-
- n = strpbrk(n + 1, "/.");
- }
-
- return s;
-}
-
-int sysctl_write(const char *property, const char *value) {
- char *p;
-
- assert(property);
- assert(value);
-
- log_debug("Setting '%s' to '%s'", property, value);
-
- p = strjoina("/proc/sys/", property);
- return write_string_file(p, value, 0);
-}
-
-int sysctl_read(const char *property, char **content) {
- char *p;
-
- assert(property);
- assert(content);
-
- p = strjoina("/proc/sys/", property);
- return read_full_file(p, content, NULL);
-}
diff --git a/src/shared/sysctl-util.h b/src/shared/sysctl-util.h
deleted file mode 100644
index 2decb39f58..0000000000
--- a/src/shared/sysctl-util.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2011 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-char *sysctl_normalize(char *s);
-int sysctl_read(const char *property, char **value);
-int sysctl_write(const char *property, const char *value);
-
diff --git a/src/shared/test-tables.h b/src/shared/test-tables.h
deleted file mode 100644
index 228e510104..0000000000
--- a/src/shared/test-tables.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/***
- This file is part of systemd
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-typedef const char* (*lookup_t)(int);
-typedef int (*reverse_t)(const char*);
-
-static inline void _test_table(const char *name,
- lookup_t lookup,
- reverse_t reverse,
- int size,
- bool sparse) {
- int i, boring = 0;
-
- for (i = -1; i < size + 1; i++) {
- const char* val = lookup(i);
- int rev;
-
- if (val) {
- rev = reverse(val);
- boring = 0;
- } else {
- rev = reverse("--no-such--value----");
- boring += i >= 0;
- }
-
- if (boring < 1 || i == size)
- printf("%s: %d → %s → %d\n", name, i, val, rev);
- else if (boring == 1)
- printf("%*s ...\n", (int) strlen(name), "");
-
- assert_se(!(i >= 0 && i < size ?
- sparse ? rev != i && rev != -1 : val == NULL || rev != i :
- val != NULL || rev != -1));
- }
-}
-
-#define test_table(lower, upper) \
- _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX, false)
-
-#define test_table_sparse(lower, upper) \
- _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX, true)
diff --git a/src/shared/tests.c b/src/shared/tests.c
deleted file mode 100644
index 409116290d..0000000000
--- a/src/shared/tests.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <util.h>
-
-#include "tests.h"
-
-char* setup_fake_runtime_dir(void) {
- char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p;
-
- assert_se(mkdtemp(t));
- assert_se(setenv("XDG_RUNTIME_DIR", t, 1) >= 0);
- assert_se(p = strdup(t));
-
- return p;
-}
diff --git a/src/shared/tests.h b/src/shared/tests.h
deleted file mode 100644
index 93f09013a1..0000000000
--- a/src/shared/tests.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-char* setup_fake_runtime_dir(void);
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
deleted file mode 100644
index ca0889f8a6..0000000000
--- a/src/shared/udev-util.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Zbigniew Jędrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "udev.h"
-#include "util.h"
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_device*, udev_device_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_enumerate*, udev_enumerate_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_event*, udev_event_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_rules*, udev_rules_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl*, udev_ctrl_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl_connection*, udev_ctrl_connection_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl_msg*, udev_ctrl_msg_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_monitor*, udev_monitor_unref);
-
-#define _cleanup_udev_unref_ _cleanup_(udev_unrefp)
-#define _cleanup_udev_device_unref_ _cleanup_(udev_device_unrefp)
-#define _cleanup_udev_enumerate_unref_ _cleanup_(udev_enumerate_unrefp)
-#define _cleanup_udev_event_unref_ _cleanup_(udev_event_unrefp)
-#define _cleanup_udev_rules_unref_ _cleanup_(udev_rules_unrefp)
-#define _cleanup_udev_ctrl_unref_ _cleanup_(udev_ctrl_unrefp)
-#define _cleanup_udev_ctrl_connection_unref_ _cleanup_(udev_ctrl_connection_unrefp)
-#define _cleanup_udev_ctrl_msg_unref_ _cleanup_(udev_ctrl_msg_unrefp)
-#define _cleanup_udev_monitor_unref_ _cleanup_(udev_monitor_unrefp)
-#define _cleanup_udev_list_cleanup_ _cleanup_(udev_list_cleanup)
diff --git a/src/shared/uid-range.c b/src/shared/uid-range.c
deleted file mode 100644
index b6ec474390..0000000000
--- a/src/shared/uid-range.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "macro.h"
-#include "uid-range.h"
-#include "user-util.h"
-
-static bool uid_range_intersect(UidRange *range, uid_t start, uid_t nr) {
- assert(range);
-
- return range->start <= start + nr &&
- range->start + range->nr >= start;
-}
-
-static void uid_range_coalesce(UidRange **p, unsigned *n) {
- unsigned i, j;
-
- assert(p);
- assert(n);
-
- for (i = 0; i < *n; i++) {
- for (j = i + 1; j < *n; j++) {
- UidRange *x = (*p)+i, *y = (*p)+j;
-
- if (uid_range_intersect(x, y->start, y->nr)) {
- uid_t begin, end;
-
- begin = MIN(x->start, y->start);
- end = MAX(x->start + x->nr, y->start + y->nr);
-
- x->start = begin;
- x->nr = end - begin;
-
- if (*n > j+1)
- memmove(y, y+1, sizeof(UidRange) * (*n - j -1));
-
- (*n)--;
- j--;
- }
- }
- }
-
-}
-
-static int uid_range_compare(const void *a, const void *b) {
- const UidRange *x = a, *y = b;
-
- if (x->start < y->start)
- return -1;
- if (x->start > y->start)
- return 1;
-
- if (x->nr < y->nr)
- return -1;
- if (x->nr > y->nr)
- return 1;
-
- return 0;
-}
-
-int uid_range_add(UidRange **p, unsigned *n, uid_t start, uid_t nr) {
- bool found = false;
- UidRange *x;
- unsigned i;
-
- assert(p);
- assert(n);
-
- if (nr <= 0)
- return 0;
-
- for (i = 0; i < *n; i++) {
- x = (*p) + i;
- if (uid_range_intersect(x, start, nr)) {
- found = true;
- break;
- }
- }
-
- if (found) {
- uid_t begin, end;
-
- begin = MIN(x->start, start);
- end = MAX(x->start + x->nr, start + nr);
-
- x->start = begin;
- x->nr = end - begin;
- } else {
- UidRange *t;
-
- t = realloc(*p, sizeof(UidRange) * (*n + 1));
- if (!t)
- return -ENOMEM;
-
- *p = t;
- x = t + ((*n) ++);
-
- x->start = start;
- x->nr = nr;
- }
-
- qsort(*p, *n, sizeof(UidRange), uid_range_compare);
- uid_range_coalesce(p, n);
-
- return *n;
-}
-
-int uid_range_add_str(UidRange **p, unsigned *n, const char *s) {
- uid_t start, nr;
- const char *t;
- int r;
-
- assert(p);
- assert(n);
- assert(s);
-
- t = strchr(s, '-');
- if (t) {
- char *b;
- uid_t end;
-
- b = strndupa(s, t - s);
- r = parse_uid(b, &start);
- if (r < 0)
- return r;
-
- r = parse_uid(t+1, &end);
- if (r < 0)
- return r;
-
- if (end < start)
- return -EINVAL;
-
- nr = end - start + 1;
- } else {
- r = parse_uid(s, &start);
- if (r < 0)
- return r;
-
- nr = 1;
- }
-
- return uid_range_add(p, n, start, nr);
-}
-
-int uid_range_next_lower(const UidRange *p, unsigned n, uid_t *uid) {
- uid_t closest = UID_INVALID, candidate;
- unsigned i;
-
- assert(p);
- assert(uid);
-
- candidate = *uid - 1;
-
- for (i = 0; i < n; i++) {
- uid_t begin, end;
-
- begin = p[i].start;
- end = p[i].start + p[i].nr - 1;
-
- if (candidate >= begin && candidate <= end) {
- *uid = candidate;
- return 1;
- }
-
- if (end < candidate)
- closest = end;
- }
-
- if (closest == UID_INVALID)
- return -EBUSY;
-
- *uid = closest;
- return 1;
-}
-
-bool uid_range_contains(const UidRange *p, unsigned n, uid_t uid) {
- unsigned i;
-
- assert(p);
- assert(uid);
-
- for (i = 0; i < n; i++)
- if (uid >= p[i].start && uid < p[i].start + p[i].nr)
- return true;
-
- return false;
-}
diff --git a/src/shared/uid-range.h b/src/shared/uid-range.h
deleted file mode 100644
index 4044eb4c9c..0000000000
--- a/src/shared/uid-range.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <sys/types.h>
-
-typedef struct UidRange {
- uid_t start, nr;
-} UidRange;
-
-int uid_range_add(UidRange **p, unsigned *n, uid_t start, uid_t nr);
-int uid_range_add_str(UidRange **p, unsigned *n, const char *s);
-
-int uid_range_next_lower(const UidRange *p, unsigned n, uid_t *uid);
-bool uid_range_contains(const UidRange *p, unsigned n, uid_t uid);
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
deleted file mode 100644
index 9750dcd817..0000000000
--- a/src/shared/utmp-wtmp.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/utsname.h>
-#include <unistd.h>
-#include <utmpx.h>
-
-#include "alloc-util.h"
-#include "fd-util.h"
-#include "hostname-util.h"
-#include "macro.h"
-#include "path-util.h"
-#include "string-util.h"
-#include "terminal-util.h"
-#include "time-util.h"
-#include "user-util.h"
-#include "util.h"
-#include "utmp-wtmp.h"
-
-int utmp_get_runlevel(int *runlevel, int *previous) {
- struct utmpx *found, lookup = { .ut_type = RUN_LVL };
- int r;
- const char *e;
-
- assert(runlevel);
-
- /* If these values are set in the environment this takes
- * precedence. Presumably, sysvinit does this to work around a
- * race condition that would otherwise exist where we'd always
- * go to disk and hence might read runlevel data that might be
- * very new and does not apply to the current script being
- * executed. */
-
- e = getenv("RUNLEVEL");
- if (e && e[0] > 0) {
- *runlevel = e[0];
-
- if (previous) {
- /* $PREVLEVEL seems to be an Upstart thing */
-
- e = getenv("PREVLEVEL");
- if (e && e[0] > 0)
- *previous = e[0];
- else
- *previous = 0;
- }
-
- return 0;
- }
-
- if (utmpxname(_PATH_UTMPX) < 0)
- return -errno;
-
- setutxent();
-
- found = getutxid(&lookup);
- if (!found)
- r = -errno;
- else {
- int a, b;
-
- a = found->ut_pid & 0xFF;
- b = (found->ut_pid >> 8) & 0xFF;
-
- *runlevel = a;
- if (previous)
- *previous = b;
-
- r = 0;
- }
-
- endutxent();
-
- return r;
-}
-
-static void init_timestamp(struct utmpx *store, usec_t t) {
- assert(store);
-
- if (t <= 0)
- t = now(CLOCK_REALTIME);
-
- store->ut_tv.tv_sec = t / USEC_PER_SEC;
- store->ut_tv.tv_usec = t % USEC_PER_SEC;
-}
-
-static void init_entry(struct utmpx *store, usec_t t) {
- struct utsname uts = {};
-
- assert(store);
-
- init_timestamp(store, t);
-
- if (uname(&uts) >= 0)
- strncpy(store->ut_host, uts.release, sizeof(store->ut_host));
-
- strncpy(store->ut_line, "~", sizeof(store->ut_line)); /* or ~~ ? */
- strncpy(store->ut_id, "~~", sizeof(store->ut_id));
-}
-
-static int write_entry_utmp(const struct utmpx *store) {
- int r;
-
- assert(store);
-
- /* utmp is similar to wtmp, but there is only one entry for
- * each entry type resp. user; i.e. basically a key/value
- * table. */
-
- if (utmpxname(_PATH_UTMPX) < 0)
- return -errno;
-
- setutxent();
-
- if (!pututxline(store))
- r = -errno;
- else
- r = 0;
-
- endutxent();
-
- return r;
-}
-
-static int write_entry_wtmp(const struct utmpx *store) {
- assert(store);
-
- /* wtmp is a simple append-only file where each entry is
- simply appended to the end; i.e. basically a log. */
-
- errno = 0;
- updwtmpx(_PATH_WTMPX, store);
- return -errno;
-}
-
-static int write_utmp_wtmp(const struct utmpx *store_utmp, const struct utmpx *store_wtmp) {
- int r, s;
-
- r = write_entry_utmp(store_utmp);
- s = write_entry_wtmp(store_wtmp);
-
- if (r >= 0)
- r = s;
-
- /* If utmp/wtmp have been disabled, that's a good thing, hence
- * ignore the errors */
- if (r == -ENOENT)
- r = 0;
-
- return r;
-}
-
-static int write_entry_both(const struct utmpx *store) {
- return write_utmp_wtmp(store, store);
-}
-
-int utmp_put_shutdown(void) {
- struct utmpx store = {};
-
- init_entry(&store, 0);
-
- store.ut_type = RUN_LVL;
- strncpy(store.ut_user, "shutdown", sizeof(store.ut_user));
-
- return write_entry_both(&store);
-}
-
-int utmp_put_reboot(usec_t t) {
- struct utmpx store = {};
-
- init_entry(&store, t);
-
- store.ut_type = BOOT_TIME;
- strncpy(store.ut_user, "reboot", sizeof(store.ut_user));
-
- return write_entry_both(&store);
-}
-
-_pure_ static const char *sanitize_id(const char *id) {
- size_t l;
-
- assert(id);
- l = strlen(id);
-
- if (l <= sizeof(((struct utmpx*) NULL)->ut_id))
- return id;
-
- return id + l - sizeof(((struct utmpx*) NULL)->ut_id);
-}
-
-int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line, int ut_type, const char *user) {
- struct utmpx store = {
- .ut_type = INIT_PROCESS,
- .ut_pid = pid,
- .ut_session = sid,
- };
- int r;
-
- assert(id);
-
- init_timestamp(&store, 0);
-
- /* ut_id needs only be nul-terminated if it is shorter than sizeof(ut_id) */
- strncpy(store.ut_id, sanitize_id(id), sizeof(store.ut_id));
-
- if (line)
- strncpy(store.ut_line, basename(line), sizeof(store.ut_line));
-
- r = write_entry_both(&store);
- if (r < 0)
- return r;
-
- if (ut_type == LOGIN_PROCESS || ut_type == USER_PROCESS) {
- store.ut_type = LOGIN_PROCESS;
- r = write_entry_both(&store);
- if (r < 0)
- return r;
- }
-
- if (ut_type == USER_PROCESS) {
- store.ut_type = USER_PROCESS;
- strncpy(store.ut_user, user, sizeof(store.ut_user)-1);
- r = write_entry_both(&store);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
- struct utmpx lookup = {
- .ut_type = INIT_PROCESS /* looks for DEAD_PROCESS, LOGIN_PROCESS, USER_PROCESS, too */
- }, store, store_wtmp, *found;
-
- assert(id);
-
- setutxent();
-
- /* ut_id needs only be nul-terminated if it is shorter than sizeof(ut_id) */
- strncpy(lookup.ut_id, sanitize_id(id), sizeof(lookup.ut_id));
-
- found = getutxid(&lookup);
- if (!found)
- return 0;
-
- if (found->ut_pid != pid)
- return 0;
-
- memcpy(&store, found, sizeof(store));
- store.ut_type = DEAD_PROCESS;
- store.ut_exit.e_termination = code;
- store.ut_exit.e_exit = status;
-
- zero(store.ut_user);
- zero(store.ut_host);
- zero(store.ut_tv);
-
- memcpy(&store_wtmp, &store, sizeof(store_wtmp));
- /* wtmp wants the current time */
- init_timestamp(&store_wtmp, 0);
-
- return write_utmp_wtmp(&store, &store_wtmp);
-}
-
-
-int utmp_put_runlevel(int runlevel, int previous) {
- struct utmpx store = {};
- int r;
-
- assert(runlevel > 0);
-
- if (previous <= 0) {
- /* Find the old runlevel automatically */
-
- r = utmp_get_runlevel(&previous, NULL);
- if (r < 0) {
- if (r != -ESRCH)
- return r;
-
- previous = 0;
- }
- }
-
- if (previous == runlevel)
- return 0;
-
- init_entry(&store, 0);
-
- store.ut_type = RUN_LVL;
- store.ut_pid = (runlevel & 0xFF) | ((previous & 0xFF) << 8);
- strncpy(store.ut_user, "runlevel", sizeof(store.ut_user));
-
- return write_entry_both(&store);
-}
-
-#define TIMEOUT_MSEC 50
-
-static int write_to_terminal(const char *tty, const char *message) {
- _cleanup_close_ int fd = -1;
- const char *p;
- size_t left;
- usec_t end;
-
- assert(tty);
- assert(message);
-
- fd = open(tty, O_WRONLY|O_NDELAY|O_NOCTTY|O_CLOEXEC);
- if (fd < 0 || !isatty(fd))
- return -errno;
-
- p = message;
- left = strlen(message);
-
- end = now(CLOCK_MONOTONIC) + TIMEOUT_MSEC*USEC_PER_MSEC;
-
- while (left > 0) {
- ssize_t n;
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLOUT,
- };
- usec_t t;
- int k;
-
- t = now(CLOCK_MONOTONIC);
-
- if (t >= end)
- return -ETIME;
-
- k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC);
- if (k < 0)
- return -errno;
-
- if (k == 0)
- return -ETIME;
-
- n = write(fd, p, left);
- if (n < 0) {
- if (errno == EAGAIN)
- continue;
-
- return -errno;
- }
-
- assert((size_t) n <= left);
-
- p += n;
- left -= n;
- }
-
- return 0;
-}
-
-int utmp_wall(
- const char *message,
- const char *username,
- const char *origin_tty,
- bool (*match_tty)(const char *tty, void *userdata),
- void *userdata) {
-
- _cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *stdin_tty = NULL;
- char date[FORMAT_TIMESTAMP_MAX];
- struct utmpx *u;
- int r;
-
- hn = gethostname_malloc();
- if (!hn)
- return -ENOMEM;
- if (!username) {
- un = getlogname_malloc();
- if (!un)
- return -ENOMEM;
- }
-
- if (!origin_tty) {
- getttyname_harder(STDIN_FILENO, &stdin_tty);
- origin_tty = stdin_tty;
- }
-
- if (asprintf(&text,
- "\a\r\n"
- "Broadcast message from %s@%s%s%s (%s):\r\n\r\n"
- "%s\r\n\r\n",
- un ?: username, hn,
- origin_tty ? " on " : "", strempty(origin_tty),
- format_timestamp(date, sizeof(date), now(CLOCK_REALTIME)),
- message) < 0)
- return -ENOMEM;
-
- setutxent();
-
- r = 0;
-
- while ((u = getutxent())) {
- _cleanup_free_ char *buf = NULL;
- const char *path;
- int q;
-
- if (u->ut_type != USER_PROCESS || u->ut_user[0] == 0)
- continue;
-
- /* this access is fine, because strlen("/dev/") << 32 (UT_LINESIZE) */
- if (path_startswith(u->ut_line, "/dev/"))
- path = u->ut_line;
- else {
- if (asprintf(&buf, "/dev/%.*s", (int) sizeof(u->ut_line), u->ut_line) < 0)
- return -ENOMEM;
-
- path = buf;
- }
-
- if (!match_tty || match_tty(path, userdata)) {
- q = write_to_terminal(path, text);
- if (q < 0)
- r = q;
- }
- }
-
- return r;
-}
diff --git a/src/shared/utmp-wtmp.h b/src/shared/utmp-wtmp.h
deleted file mode 100644
index 438e270a26..0000000000
--- a/src/shared/utmp-wtmp.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <sys/types.h>
-
-#include "time-util.h"
-#include "util.h"
-
-#ifdef HAVE_UTMP
-int utmp_get_runlevel(int *runlevel, int *previous);
-
-int utmp_put_shutdown(void);
-int utmp_put_reboot(usec_t timestamp);
-int utmp_put_runlevel(int runlevel, int previous);
-
-int utmp_put_dead_process(const char *id, pid_t pid, int code, int status);
-int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line, int ut_type, const char *user);
-
-int utmp_wall(
- const char *message,
- const char *username,
- const char *origin_tty,
- bool (*match_tty)(const char *tty, void *userdata),
- void *userdata);
-
-#else /* HAVE_UTMP */
-
-static inline int utmp_get_runlevel(int *runlevel, int *previous) {
- return -ESRCH;
-}
-static inline int utmp_put_shutdown(void) {
- return 0;
-}
-static inline int utmp_put_reboot(usec_t timestamp) {
- return 0;
-}
-static inline int utmp_put_runlevel(int runlevel, int previous) {
- return 0;
-}
-static inline int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
- return 0;
-}
-static inline int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line, int ut_type, const char *user) {
- return 0;
-}
-static inline int utmp_wall(
- const char *message,
- const char *username,
- const char *origin_tty,
- bool (*match_tty)(const char *tty, void *userdata),
- void *userdata) {
- return 0;
-}
-
-#endif /* HAVE_UTMP */
diff --git a/src/shared/vlan-util.c b/src/shared/vlan-util.c
deleted file mode 100644
index 78d66dd3d9..0000000000
--- a/src/shared/vlan-util.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "vlan-util.h"
-#include "parse-util.h"
-#include "conf-parser.h"
-
-int parse_vlanid(const char *p, uint16_t *ret) {
- uint16_t id;
- int r;
-
- r = safe_atou16(p, &id);
- if (r < 0)
- return r;
- if (!vlanid_is_valid(id))
- return -ERANGE;
-
- *ret = id;
- return 0;
-}
-
-int config_parse_vlanid(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- uint16_t *id = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = parse_vlanid(rvalue, id);
- if (r == -ERANGE) {
- log_syntax(unit, LOG_ERR, filename, line, r, "VLAN identifier outside of valid range 0…4094, ignoring: %s", rvalue);
- return 0;
- }
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VLAN identifier value, ignoring: %s", rvalue);
- return 0;
- }
-
- return 0;
-}
diff --git a/src/shared/vlan-util.h b/src/shared/vlan-util.h
deleted file mode 100644
index ce6763b3a3..0000000000
--- a/src/shared/vlan-util.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2016 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <inttypes.h>
-
-#define VLANID_MAX 4094
-#define VLANID_INVALID UINT16_MAX
-
-/* Note that we permit VLAN Id 0 here, as that is apparently OK by the Linux kernel */
-static inline bool vlanid_is_valid(uint16_t id) {
- return id <= VLANID_MAX;
-}
-
-int parse_vlanid(const char *p, uint16_t *ret);
-
-int config_parse_vlanid(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/shared/watchdog.c b/src/shared/watchdog.c
deleted file mode 100644
index 4f3e0125f3..0000000000
--- a/src/shared/watchdog.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <linux/watchdog.h>
-
-#include "fd-util.h"
-#include "log.h"
-#include "time-util.h"
-#include "watchdog.h"
-
-static int watchdog_fd = -1;
-static usec_t watchdog_timeout = USEC_INFINITY;
-
-static int update_timeout(void) {
- int r;
-
- if (watchdog_fd < 0)
- return 0;
-
- if (watchdog_timeout == USEC_INFINITY)
- return 0;
- else if (watchdog_timeout == 0) {
- int flags;
-
- flags = WDIOS_DISABLECARD;
- r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
- if (r < 0)
- return log_warning_errno(errno, "Failed to disable hardware watchdog: %m");
- } else {
- int sec, flags;
- char buf[FORMAT_TIMESPAN_MAX];
-
- sec = (int) ((watchdog_timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
- r = ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec);
- if (r < 0)
- return log_warning_errno(errno, "Failed to set timeout to %is: %m", sec);
-
- watchdog_timeout = (usec_t) sec * USEC_PER_SEC;
- log_info("Set hardware watchdog to %s.", format_timespan(buf, sizeof(buf), watchdog_timeout, 0));
-
- flags = WDIOS_ENABLECARD;
- r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
- if (r < 0) {
- /* ENOTTY means the watchdog is always enabled so we're fine */
- log_full(errno == ENOTTY ? LOG_DEBUG : LOG_WARNING,
- "Failed to enable hardware watchdog: %m");
- if (errno != ENOTTY)
- return -errno;
- }
-
- r = ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0);
- if (r < 0)
- return log_warning_errno(errno, "Failed to ping hardware watchdog: %m");
- }
-
- return 0;
-}
-
-static int open_watchdog(void) {
- struct watchdog_info ident;
-
- if (watchdog_fd >= 0)
- return 0;
-
- watchdog_fd = open("/dev/watchdog", O_WRONLY|O_CLOEXEC);
- if (watchdog_fd < 0)
- return -errno;
-
- if (ioctl(watchdog_fd, WDIOC_GETSUPPORT, &ident) >= 0)
- log_info("Hardware watchdog '%s', version %x",
- ident.identity,
- ident.firmware_version);
-
- return update_timeout();
-}
-
-int watchdog_set_timeout(usec_t *usec) {
- int r;
-
- watchdog_timeout = *usec;
-
- /* If we didn't open the watchdog yet and didn't get any
- * explicit timeout value set, don't do anything */
- if (watchdog_fd < 0 && watchdog_timeout == USEC_INFINITY)
- return 0;
-
- if (watchdog_fd < 0)
- r = open_watchdog();
- else
- r = update_timeout();
-
- *usec = watchdog_timeout;
-
- return r;
-}
-
-int watchdog_ping(void) {
- int r;
-
- if (watchdog_fd < 0) {
- r = open_watchdog();
- if (r < 0)
- return r;
- }
-
- r = ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0);
- if (r < 0)
- return log_warning_errno(errno, "Failed to ping hardware watchdog: %m");
-
- return 0;
-}
-
-void watchdog_close(bool disarm) {
- int r;
-
- if (watchdog_fd < 0)
- return;
-
- if (disarm) {
- int flags;
-
- /* Explicitly disarm it */
- flags = WDIOS_DISABLECARD;
- r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
- if (r < 0)
- log_warning_errno(errno, "Failed to disable hardware watchdog: %m");
-
- /* To be sure, use magic close logic, too */
- for (;;) {
- static const char v = 'V';
-
- if (write(watchdog_fd, &v, 1) > 0)
- break;
-
- if (errno != EINTR) {
- log_error_errno(errno, "Failed to disarm watchdog timer: %m");
- break;
- }
- }
- }
-
- watchdog_fd = safe_close(watchdog_fd);
-}
diff --git a/src/shared/watchdog.h b/src/shared/watchdog.h
deleted file mode 100644
index f6ec178ea1..0000000000
--- a/src/shared/watchdog.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2012 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include "time-util.h"
-#include "util.h"
-
-int watchdog_set_timeout(usec_t *usec);
-int watchdog_ping(void);
-void watchdog_close(bool disarm);