X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fdbus1-generator%2Fdbus1-generator.c;h=a7b36d18e9fb0e552a9bd024449aa75b08b2056b;hb=c3834f9b881f2b1a68dc7d797c134f0b66b47b57;hp=93c6392f8349f0f7a240ab5de74253d1a2705f3d;hpb=674eb68520107d771e3458287025a73387f938c4;p=elogind.git diff --git a/src/dbus1-generator/dbus1-generator.c b/src/dbus1-generator/dbus1-generator.c index 93c6392f8..a7b36d18e 100644 --- a/src/dbus1-generator/dbus1-generator.c +++ b/src/dbus1-generator/dbus1-generator.c @@ -28,7 +28,7 @@ #include "unit-name.h" #include "cgroup-util.h" -static const char *arg_dest = "/tmp"; +static const char *arg_dest_late = "/tmp", *arg_dest = "/tmp"; static int create_dbus_files( const char *path, @@ -43,6 +43,7 @@ static int create_dbus_files( assert(path); assert(name); + assert(service || exec); if (!service) { _cleanup_free_ char *a = NULL; @@ -51,7 +52,7 @@ static int create_dbus_files( if (!s) return log_oom(); - a = strjoin(arg_dest, "/", s, NULL); + a = strjoin(arg_dest_late, "/", s, NULL); if (!a) return log_oom(); @@ -64,8 +65,9 @@ static int create_dbus_files( fprintf(f, "# Automatically generated by systemd-dbus1-generator\n\n" "[Unit]\n" - "Source=%s\n" - "Description=DBUS1: %s\n\n" + "SourcePath=%s\n" + "Description=DBUS1: %s\n" + "Documentation=man:systemd-dbus1-generator(8)\n\n" "[Service]\n" "ExecStart=%s\n" "Type=dbus\n" @@ -83,9 +85,19 @@ static int create_dbus_files( fprintf(f, "Environment=DBUS_STARTER_BUS_TYPE=%s\n", type); if (streq(type, "system")) - fprintf(f, "Environment=DBUS_STARTER_ADDRESS=kernel:/dev/kdbus/0-system\n"); - else if (streq(type, "session")) - fprintf(f, "Environment=DBUS_STARTER_ADDRESS=kernel:/dev/kdbus/%lu-user\n", (unsigned long) getuid()); + fprintf(f, "Environment=DBUS_STARTER_ADDRESS=" DEFAULT_SYSTEM_BUS_PATH "\n"); + else if (streq(type, "session")) { + char *run; + + run = getenv("XDG_RUNTIME_DIR"); + if (!run) { + log_error("XDG_RUNTIME_DIR not set."); + return -EINVAL; + } + + fprintf(f, "Environment=DBUS_STARTER_ADDRESS="KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT "\n", + (unsigned long) getuid(), run); + } } fflush(f); @@ -97,7 +109,7 @@ static int create_dbus_files( service = s; } - b = strjoin(arg_dest, "/", name, ".busname", NULL); + b = strjoin(arg_dest_late, "/", name, ".busname", NULL); if (!b) return log_oom(); @@ -110,8 +122,9 @@ static int create_dbus_files( fprintf(f, "# Automatically generated by systemd-dbus1-generator\n\n" "[Unit]\n" - "Source=%s\n" - "Description=DBUS1: %s\n\n" + "SourcePath=%s\n" + "Description=DBUS1: %s\n" + "Documentation=man:systemd-dbus1-generator(8)\n\n" "[BusName]\n" "Name=%s\n" "Service=%s\n", @@ -126,13 +139,13 @@ static int create_dbus_files( return -errno; } - lnk = strjoin(arg_dest, "/" SPECIAL_BUSNAMES_TARGET ".wants/", name, ".busname", NULL); + lnk = strjoin(arg_dest_late, "/" SPECIAL_BUSNAMES_TARGET ".wants/", name, ".busname", NULL); if (!lnk) return log_oom(); mkdir_parents_label(lnk, 0755); if (symlink(b, lnk)) { - log_error("Failed to create symlinks %s: %m", lnk); + log_error("Failed to create symlink %s: %m", lnk); return -errno; } @@ -183,8 +196,13 @@ static int add_dbus(const char *path, const char *fname, const char *type) { return 0; } + if (streq(name, "org.freedesktop.systemd1")) { + log_debug("Skipping %s, identified as systemd.", p); + return 0; + } + if (service) { - if (!unit_name_is_valid(service, false)) { + if (!unit_name_is_valid(service, TEMPLATE_INVALID)) { log_warning("Unit name %s is not valid, ignoring.", service); return 0; } @@ -193,7 +211,7 @@ static int add_dbus(const char *path, const char *fname, const char *type) { return 0; } } else { - if (!exec) { + if (streq(exec, "/bin/false") || !exec) { log_warning("Neither service name nor binary path specified, ignoring %s.", p); return 0; } @@ -207,25 +225,15 @@ static int add_dbus(const char *path, const char *fname, const char *type) { return create_dbus_files(p, name, service, exec, user, type); } -static int parse_dbus_fragments(void) { +static int parse_dbus_fragments(const char *path, const char *type) { _cleanup_closedir_ DIR *d = NULL; struct dirent *de; - const char *p, *type; int r; - r = cg_pid_get_owner_uid(0, NULL); - if (r >= 0) { - p = "/usr/share/dbus-1/services"; - type = "session"; - } else if (r == -ENOENT) { - p = "/usr/share/dbus-1/system-services"; - type = "systemd"; - } else if (r < 0) { - log_error("Failed to determine whether we are running as user or system instance: %s", strerror(-r)); - return r; - } + assert(path); + assert(type); - d = opendir(p); + d = opendir(path); if (!d) { if (errno == -ENOENT) return 0; @@ -241,7 +249,7 @@ static int parse_dbus_fragments(void) { if (!endswith(de->d_name, ".service")) continue; - q = add_dbus(p, de->d_name, type); + q = add_dbus(path, de->d_name, type); if (q < 0) r = q; } @@ -253,16 +261,62 @@ fail: return -errno; } +static int link_busnames_target(const char *units) { + const char *f, *t; + + f = strappenda(units, "/" SPECIAL_BUSNAMES_TARGET); + t = strappenda(arg_dest, "/" SPECIAL_BASIC_TARGET ".wants/" SPECIAL_BUSNAMES_TARGET); + + mkdir_parents_label(t, 0755); + if (symlink(f, t) < 0) { + log_error("Failed to create symlink %s: %m", t); + return -errno; + } + + return 0; +} + +static int link_compatibility(const char *units) { + const char *f, *t; + + f = strappenda(units, "/systemd-bus-proxyd.socket"); + t = strappenda(arg_dest, "/" SPECIAL_DBUS_SOCKET); + mkdir_parents_label(t, 0755); + if (symlink(f, t) < 0) { + log_error("Failed to create symlink %s: %m", t); + return -errno; + } + + f = strappenda(units, "/systemd-bus-proxyd.socket"); + t = strappenda(arg_dest, "/" SPECIAL_SOCKETS_TARGET ".wants/systemd-bus-proxyd.socket"); + mkdir_parents_label(t, 0755); + if (symlink(f, t) < 0) { + log_error("Failed to create symlink %s: %m", t); + return -errno; + } + + t = strappenda(arg_dest, "/" SPECIAL_DBUS_SERVICE); + if (symlink("/dev/null", t) < 0) { + log_error("Failed to mask %s: %m", t); + return -errno; + } + + return 0; +} + int main(int argc, char *argv[]) { - int r; + const char *path, *type, *units; + int r, q; if (argc > 1 && argc != 4) { log_error("This program takes three or no arguments."); return EXIT_FAILURE; } - if (argc > 1) - arg_dest = argv[3]; + if (argc > 1) { + arg_dest = argv[1]; + arg_dest_late = argv[3]; + } log_set_target(LOG_TARGET_SAFE); log_parse_environment(); @@ -273,7 +327,30 @@ int main(int argc, char *argv[]) { if (access("/dev/kdbus/control", F_OK) < 0) return 0; - r = parse_dbus_fragments(); + r = cg_pid_get_owner_uid(0, NULL); + if (r >= 0) { + path = "/usr/share/dbus-1/services"; + type = "session"; + units = USER_DATA_UNIT_PATH; + } else if (r == -ENOENT) { + path = "/usr/share/dbus-1/system-services"; + type = "system"; + units = SYSTEM_DATA_UNIT_PATH; + } else { + log_error("Failed to determine whether we are running as user or system instance: %s", strerror(-r)); + return r; + } + + r = parse_dbus_fragments(path, type); + + /* FIXME: One day this should just be pulled in statically from basic.target */ + q = link_busnames_target(units); + if (q < 0) + r = q; + + q = link_compatibility(units); + if (q < 0) + r = q; return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }