- r = sd_bus_set_address(a, arg_address);
- if (r < 0) {
- log_error("Failed to set address to connect to: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_negotiate_fds(a, is_unix);
- if (r < 0) {
- log_error("Failed to set FD negotiation: %s", strerror(-r));
- goto finish;
- }
-
- if (ucred.pid > 0) {
- a->fake_creds.pid = ucred.pid;
- a->fake_creds.uid = ucred.uid;
- a->fake_creds.gid = ucred.gid;
- a->fake_creds_valid = true;
- }
-
- if (peersec) {
- a->fake_label = peersec;
- peersec = NULL;
- }
-
- a->manual_peer_interface = true;
-
- r = sd_bus_start(a);
- if (r < 0) {
- log_error("Failed to start bus client: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_get_server_id(a, &server_id);
- if (r < 0) {
- log_error("Failed to get server ID: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_new(&b);
- if (r < 0) {
- log_error("Failed to allocate bus: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_set_fd(b, in_fd, out_fd);
- if (r < 0) {
- log_error("Failed to set fds: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_set_server(b, 1, server_id);
- if (r < 0) {
- log_error("Failed to set server mode: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_negotiate_fds(b, is_unix);
- if (r < 0) {
- log_error("Failed to set FD negotiation: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_set_anonymous(b, true);
- if (r < 0) {
- log_error("Failed to set anonymous authentication: %s", strerror(-r));
- goto finish;
- }
-
- b->manual_peer_interface = true;
-
- r = sd_bus_start(b);
- if (r < 0) {
- log_error("Failed to start bus client: %s", strerror(-r));
- goto finish;
- }
-
- r = rename_service(a, b);
- if (r < 0)
- log_debug("Failed to rename process: %s", strerror(-r));
-
- if (a->is_kernel) {
- _cleanup_free_ char *match = NULL;
- const char *unique;
-
- r = sd_bus_get_unique_name(a, &unique);
- if (r < 0) {
- log_error("Failed to get unique name: %s", strerror(-r));
- goto finish;
- }
-
- match = strjoin("type='signal',"
- "sender='org.freedesktop.DBus',"
- "path='/org/freedesktop/DBus',"
- "interface='org.freedesktop.DBus',"
- "member='NameOwnerChanged',"
- "arg1='",
- unique,
- "'",
- NULL);
- if (!match) {
- log_oom();
- goto finish;
- }
-
- r = sd_bus_add_match(a, match, NULL, NULL);
- if (r < 0) {
- log_error("Failed to add match for NameLost: %s", strerror(-r));
- goto finish;
- }
-
- free(match);
- match = strjoin("type='signal',"
- "sender='org.freedesktop.DBus',"
- "path='/org/freedesktop/DBus',"
- "interface='org.freedesktop.DBus',"
- "member='NameOwnerChanged',"
- "arg2='",
- unique,
- "'",
- NULL);
- if (!match) {
- log_oom();
- goto finish;
- }
-
- r = sd_bus_add_match(a, match, NULL, NULL);
- if (r < 0) {
- log_error("Failed to add match for NameAcquired: %s", strerror(-r));
- goto finish;
- }
- }
-
- for (;;) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- int events_a, events_b, fd;
- uint64_t timeout_a, timeout_b, t;
- struct timespec _ts, *ts;
- struct pollfd *pollfd;
- int k;
-
- if (got_hello) {
- r = sd_bus_process(a, &m);
- if (r < 0) {
- /* treat 'connection reset by peer' as clean exit condition */
- if (r == -ECONNRESET)
- r = 0;
- else
- log_error("Failed to process bus a: %s", strerror(-r));
-
- goto finish;
- }
-
- if (m) {
- /* We officially got EOF, let's quit */
- if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
- r = 0;
- goto finish;
- }
-
- k = synthesize_name_acquired(a, b, m);
- if (k < 0) {
- r = k;
- log_error("Failed to synthesize message: %s", strerror(-r));
- goto finish;
- }
-
- k = sd_bus_send(b, m, NULL);
- if (k < 0) {
- if (k == -ECONNRESET)
- r = 0;
- else {
- r = k;
- log_error("Failed to send message: %s", strerror(-r));
- }
-
- goto finish;
- }
- }
-
- if (r > 0)
- continue;
- }
-
- r = sd_bus_process(b, &m);
- if (r < 0) {
- /* treat 'connection reset by peer' as clean exit condition */
- if (r == -ECONNRESET)
- r = 0;
- else
- log_error("Failed to process bus b: %s", strerror(-r));
-
- goto finish;
- }
-
- if (m) {
- /* We officially got EOF, let's quit */
- if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
- r = 0;
- goto finish;
- }
-
- k = process_hello(a, b, m, &got_hello);
- if (k < 0) {
- r = k;
- log_error("Failed to process HELLO: %s", strerror(-r));
- goto finish;
- }
-
- if (k > 0)
- r = k;
- else {
- k = process_policy(a, b, m);
- if (k < 0) {
- r = k;
- log_error("Failed to process policy: %s", strerror(-r));
- goto finish;
- }
-
- k = sd_bus_send(a, m, NULL);
- if (k < 0) {
- if (r == -ECONNRESET)
- r = 0;
- else {
- r = k;
- log_error("Failed to send message: %s", strerror(-r));
- }
-
- goto finish;
- }
- }
- }
-
- if (r > 0)
- continue;
-
- fd = sd_bus_get_fd(a);
- if (fd < 0) {
- log_error("Failed to get fd: %s", strerror(-r));
- goto finish;
- }
-
- events_a = sd_bus_get_events(a);
- if (events_a < 0) {
- log_error("Failed to get events mask: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_get_timeout(a, &timeout_a);
- if (r < 0) {
- log_error("Failed to get timeout: %s", strerror(-r));
- goto finish;
- }
-
- events_b = sd_bus_get_events(b);
- if (events_b < 0) {
- log_error("Failed to get events mask: %s", strerror(-r));
- goto finish;
- }
-
- r = sd_bus_get_timeout(b, &timeout_b);
- if (r < 0) {
- log_error("Failed to get timeout: %s", strerror(-r));
- goto finish;
- }
-
- t = timeout_a;
- if (t == (uint64_t) -1 || (timeout_b != (uint64_t) -1 && timeout_b < timeout_a))
- t = timeout_b;
-
- if (t == (uint64_t) -1)
- ts = NULL;
- else {
- usec_t nw;
-
- nw = now(CLOCK_MONOTONIC);
- if (t > nw)
- t -= nw;
- else
- t = 0;
-
- ts = timespec_store(&_ts, t);
- }
-
- pollfd = (struct pollfd[3]) {
- {.fd = fd, .events = events_a, },
- {.fd = in_fd, .events = events_b & POLLIN, },
- {.fd = out_fd, .events = events_b & POLLOUT, }
- };
-
- r = ppoll(pollfd, 3, ts, NULL);
- if (r < 0) {
- log_error("ppoll() failed: %m");
- goto finish;
- }
- }
-
- r = 0;