0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering/***
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering This file is part of systemd.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering Copyright 2013 Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering systemd is free software; you can redistribute it and/or modify it
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering under the terms of the GNU Lesser General Public License as published by
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering (at your option) any later version.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering systemd is distributed in the hope that it will be useful, but
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering Lesser General Public License for more details.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering You should have received a copy of the GNU Lesser General Public License
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering***/
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering#include "alloc-util.h"
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering#include "bus-internal.h"
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering#include "bus-util.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "cgroup-util.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "conf-parser.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "dirent-util.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "fd-util.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "fileio.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "mkdir.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "special.h"
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering#include "unit-name.h"
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering#include "util.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringstatic const char *arg_dest_late = "/tmp", *arg_dest = "/tmp";
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poetteringstatic int create_dbus_files(
e7d179acb9f50dec4a16c6c222dd147d7e53c6bbLennart Poettering const char *path,
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering const char *name,
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering const char *service,
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering const char *exec,
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering const char *user,
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering const char *type) {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering _cleanup_free_ char *b = NULL, *s = NULL, *lnk = NULL;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering int r;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering assert(path);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering assert(name);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering assert(service || exec);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering if (!service) {
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering _cleanup_free_ char *a = NULL;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering s = strjoin("dbus-", name, ".service", NULL);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (!s)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return log_oom();
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering a = strjoin(arg_dest_late, "/", s, NULL);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (!a)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return log_oom();
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering f = fopen(a, "wxe");
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (!f)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return log_error_errno(errno, "Failed to create %s: %m", a);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering fprintf(f,
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering "# Automatically generated by systemd-dbus1-generator\n\n"
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering "[Unit]\n"
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering "SourcePath=%s\n"
d76f90f1711e55d23ee6c8c0957fa3db17927327Lennart Poettering "Description=DBUS1: %s\n"
d76f90f1711e55d23ee6c8c0957fa3db17927327Lennart Poettering "Documentation=man:systemd-dbus1-generator(8)\n\n"
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering "[Service]\n"
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering "ExecStart=%s\n"
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering "Type=dbus\n"
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering "BusName=%s\n",
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering path,
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering name,
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering exec,
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering name);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (user)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering fprintf(f, "User=%s\n", user);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (type) {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering fprintf(f, "Environment=DBUS_STARTER_BUS_TYPE=%s\n", type);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (streq(type, "system"))
105e151299dc1208855380be2b22d0db2d66ebc6Lennart Poettering fprintf(f, "Environment=DBUS_STARTER_ADDRESS=" DEFAULT_SYSTEM_BUS_ADDRESS "\n");
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering else if (streq(type, "session")) {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering char *run;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering run = getenv("XDG_RUNTIME_DIR");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (!run) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering log_error("XDG_RUNTIME_DIR not set.");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return -EINVAL;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering fprintf(f, "Environment=DBUS_STARTER_ADDRESS="KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT "\n",
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering getuid(), run);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering r = fflush_and_check(f);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (r < 0)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return log_error_errno(r, "Failed to write %s: %m", a);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering f = safe_fclose(f);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering service = s;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering b = strjoin(arg_dest_late, "/", name, ".busname", NULL);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!b)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return log_oom();
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering f = fopen(b, "wxe");
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!f)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return log_error_errno(errno, "Failed to create %s: %m", b);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering fprintf(f,
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "# Automatically generated by systemd-dbus1-generator\n\n"
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "[Unit]\n"
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "SourcePath=%s\n"
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "Description=DBUS1: %s\n"
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "Documentation=man:systemd-dbus1-generator(8)\n\n"
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "[BusName]\n"
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "Name=%s\n"
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "Service=%s\n"
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "AllowWorld=talk\n",
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering path,
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering name,
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering name,
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering service);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering r = fflush_and_check(f);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (r < 0)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return log_error_errno(r, "Failed to write %s: %m", b);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering lnk = strjoin(arg_dest_late, "/" SPECIAL_BUSNAMES_TARGET ".wants/", name, ".busname", NULL);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!lnk)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return log_oom();
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering mkdir_parents_label(lnk, 0755);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (symlink(b, lnk))
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return 0;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering}
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poetteringstatic int add_dbus(const char *path, const char *fname, const char *type) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering _cleanup_free_ char *name = NULL, *exec = NULL, *user = NULL, *service = NULL;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering const ConfigTableItem table[] = {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering { "D-BUS Service", "Name", config_parse_string, 0, &name },
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering { "D-BUS Service", "Exec", config_parse_string, 0, &exec },
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering { "D-BUS Service", "User", config_parse_string, 0, &user },
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering { "D-BUS Service", "SystemdService", config_parse_string, 0, &service },
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering { },
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering };
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering char *p;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering int r;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering assert(path);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering assert(fname);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering p = strjoina(path, "/", fname);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering r = config_parse(NULL, p, NULL,
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering "D-BUS Service\0",
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering config_item_table_lookup, table,
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering true, false, true, NULL);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (r < 0)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return r;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!name) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering log_warning("Activation file %s lacks name setting, ignoring.", p);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return 0;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!service_name_is_valid(name)) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering log_warning("Bus service name %s is not valid, ignoring.", name);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return 0;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (streq(name, "org.freedesktop.systemd1")) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering log_debug("Skipping %s, identified as systemd.", p);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return 0;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (service) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (!unit_name_is_valid(service, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering log_warning("Unit name %s is not valid, ignoring.", service);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (!endswith(service, ".service")) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering log_warning("Bus names can only activate services, ignoring %s.", p);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering } else {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (streq(exec, "/bin/false") || !exec) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering log_warning("Neither service name nor binary path specified, ignoring %s.", p);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (exec[0] != '/') {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering log_warning("Exec= in %s does not start with an absolute path, ignoring.", p);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return create_dbus_files(p, name, service, exec, user, type);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering}
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringstatic int parse_dbus_fragments(const char *path, const char *type) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering _cleanup_closedir_ DIR *d = NULL;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering struct dirent *de;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering int r;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering assert(path);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering assert(type);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering d = opendir(path);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (!d) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (errno == -ENOENT)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return log_error_errno(errno, "Failed to enumerate D-Bus activated services: %m");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering r = 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering FOREACH_DIRENT(de, d, goto fail) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering int q;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (!endswith(de->d_name, ".service"))
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering continue;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering q = add_dbus(path, de->d_name, type);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (q < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering r = q;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return r;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringfail:
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return log_error_errno(errno, "Failed to read D-Bus services directory: %m");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering}
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringstatic int link_busnames_target(const char *units) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering const char *f, *t;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering f = strjoina(units, "/" SPECIAL_BUSNAMES_TARGET);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering t = strjoina(arg_dest, "/" SPECIAL_BASIC_TARGET ".wants/" SPECIAL_BUSNAMES_TARGET);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering mkdir_parents_label(t, 0755);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (symlink(f, t) < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", t);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering}
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringstatic int link_compatibility(const char *units) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering const char *f, *t;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering f = strjoina(units, "/systemd-bus-proxyd.socket");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering t = strjoina(arg_dest, "/" SPECIAL_DBUS_SOCKET);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering mkdir_parents_label(t, 0755);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (symlink(f, t) < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", t);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering f = strjoina(units, "/systemd-bus-proxyd.socket");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering t = strjoina(arg_dest, "/" SPECIAL_SOCKETS_TARGET ".wants/systemd-bus-proxyd.socket");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering mkdir_parents_label(t, 0755);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (symlink(f, t) < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return log_error_errno(errno, "Failed to create symlink %s: %m", t);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering t = strjoina(arg_dest, "/" SPECIAL_DBUS_SERVICE);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (symlink("/dev/null", t) < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return log_error_errno(errno, "Failed to mask %s: %m", t);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering}
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringint main(int argc, char *argv[]) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering const char *path, *type, *units;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering int r, q;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (argc > 1 && argc != 4) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering log_error("This program takes three or no arguments.");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return EXIT_FAILURE;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (argc > 1) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering arg_dest = argv[1];
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering arg_dest_late = argv[3];
2a0d751be498be89e18f130ca02b2197f83b6baaLennart Poettering }
2a0d751be498be89e18f130ca02b2197f83b6baaLennart Poettering
2a0d751be498be89e18f130ca02b2197f83b6baaLennart Poettering log_set_target(LOG_TARGET_SAFE);
2a0d751be498be89e18f130ca02b2197f83b6baaLennart Poettering log_parse_environment();
2a0d751be498be89e18f130ca02b2197f83b6baaLennart Poettering log_open();
2a0d751be498be89e18f130ca02b2197f83b6baaLennart Poettering
2a0d751be498be89e18f130ca02b2197f83b6baaLennart Poettering umask(0022);
2a0d751be498be89e18f130ca02b2197f83b6baaLennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (!is_kdbus_available())
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering r = cg_pid_get_owner_uid(0, NULL);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (r >= 0) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering path = "/usr/share/dbus-1/services";
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering type = "session";
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering units = USER_DATA_UNIT_PATH;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering } else if (r == -ENXIO) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering path = "/usr/share/dbus-1/system-services";
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering type = "system";
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering units = SYSTEM_DATA_UNIT_PATH;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering } else
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return log_error_errno(r, "Failed to determine whether we are running as user or system instance: %m");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering r = parse_dbus_fragments(path, type);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering /* FIXME: One day this should just be pulled in statically from basic.target */
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering q = link_busnames_target(units);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (q < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering r = q;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering q = link_compatibility(units);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (q < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering r = q;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering}
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering