+ a = strdup(address);
+ if (!a)
+ return -ENOMEM;
+
+ free(bus->address);
+ bus->address = a;
+
+ return 0;
+}
+
+_public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(input_fd >= 0, -EINVAL);
+ assert_return(output_fd >= 0, -EINVAL);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ bus->input_fd = input_fd;
+ bus->output_fd = output_fd;
+ return 0;
+}
+
+_public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
+ char *p, **a;
+
+ assert_return(bus, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(path, -EINVAL);
+ assert_return(!strv_isempty(argv), -EINVAL);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ p = strdup(path);
+ if (!p)
+ return -ENOMEM;
+
+ a = strv_copy(argv);
+ if (!a) {
+ free(p);
+ return -ENOMEM;
+ }
+
+ free(bus->exec_path);
+ strv_free(bus->exec_argv);
+
+ bus->exec_path = p;
+ bus->exec_argv = a;
+
+ return 0;
+}
+
+_public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ bus->bus_client = !!b;
+ return 0;
+}
+
+_public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
+ return 0;
+}
+
+_public_ int sd_bus_negotiate_attach_timestamp(sd_bus *bus, int b) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_TIMESTAMP, b);
+ return 0;
+}
+
+_public_ int sd_bus_negotiate_attach_creds(sd_bus *bus, uint64_t mask) {
+ assert_return(bus, -EINVAL);
+ assert_return(mask <= _SD_BUS_CREDS_MAX, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_CREDS,
+ !!(mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID)));
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_COMM,
+ !!(mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)));
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_EXE,
+ !!(mask & SD_BUS_CREDS_EXE));
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_CMDLINE,
+ !!(mask & SD_BUS_CREDS_CMDLINE));
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_CGROUP,
+ !!(mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)));
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_CAPS,
+ !!(mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)));
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_SECLABEL,
+ !!(mask & SD_BUS_CREDS_SELINUX_CONTEXT));
+
+ SET_FLAG(bus->attach_flags, KDBUS_ATTACH_AUDIT,
+ !!(mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)));
+
+ bus->creds_mask = mask;
+
+ return 0;
+}
+
+_public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
+ assert_return(bus, -EINVAL);
+ assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ bus->is_server = !!b;
+ bus->server_id = server_id;
+ return 0;
+}
+
+_public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
+ assert_return(bus, -EINVAL);
+ assert_return(bus->state == BUS_UNSET, -EPERM);
+ assert_return(!bus_pid_changed(bus), -ECHILD);
+
+ bus->anonymous_auth = !!b;
+ return 0;
+}
+
+static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {