int main(int argc, char *argv[]) { _cleanup_(sd_bus_unrefp) sd_bus *a = NULL, *b = NULL; sd_id128_t server_id; bool is_unix; int r, in_fd, out_fd; log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); log_parse_environment(); log_open(); r = parse_argv(argc, argv); if (r <= 0) goto finish; r = sd_listen_fds(0); if (r == 0) { in_fd = STDIN_FILENO; out_fd = STDOUT_FILENO; } else if (r == 1) { in_fd = SD_LISTEN_FDS_START; out_fd = SD_LISTEN_FDS_START; } else { log_error("Illegal number of file descriptors passed\n"); goto finish; } is_unix = sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 && sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0; r = sd_bus_new(&a); if (r < 0) { log_error_errno(r, "Failed to allocate bus: %m"); goto finish; } r = sd_bus_set_address(a, arg_bus_path); if (r < 0) { log_error_errno(r, "Failed to set address to connect to: %m"); goto finish; } r = sd_bus_negotiate_fds(a, is_unix); if (r < 0) { log_error_errno(r, "Failed to set FD negotiation: %m"); goto finish; } r = sd_bus_start(a); if (r < 0) { log_error_errno(r, "Failed to start bus client: %m"); goto finish; } r = sd_bus_get_bus_id(a, &server_id); if (r < 0) { log_error_errno(r, "Failed to get server ID: %m"); goto finish; } r = sd_bus_new(&b); if (r < 0) { log_error_errno(r, "Failed to allocate bus: %m"); goto finish; } r = sd_bus_set_fd(b, in_fd, out_fd); if (r < 0) { log_error_errno(r, "Failed to set fds: %m"); goto finish; } r = sd_bus_set_server(b, 1, server_id); if (r < 0) { log_error_errno(r, "Failed to set server mode: %m"); goto finish; } r = sd_bus_negotiate_fds(b, is_unix); if (r < 0) { log_error_errno(r, "Failed to set FD negotiation: %m"); goto finish; } r = sd_bus_set_anonymous(b, true); if (r < 0) { log_error_errno(r, "Failed to set anonymous authentication: %m"); goto finish; } r = sd_bus_start(b); if (r < 0) { log_error_errno(r, "Failed to start bus client: %m"); goto finish; } for (;;) { _cleanup_(sd_bus_message_unrefp)sd_bus_message *m = NULL; int events_a, events_b, fd; uint64_t timeout_a, timeout_b, t; struct timespec _ts, *ts; r = sd_bus_process(a, &m); if (r < 0) { log_error_errno(r, "Failed to process bus a: %m"); goto finish; } if (m) { r = sd_bus_send(b, m, NULL); if (r < 0) { log_error_errno(r, "Failed to send message: %m"); 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; goto finish; } if (m) { r = sd_bus_send(a, m, NULL); if (r < 0) { log_error_errno(r, "Failed to send message: %m"); goto finish; } } if (r > 0) continue; fd = sd_bus_get_fd(a); if (fd < 0) { log_error_errno(r, "Failed to get fd: %m"); goto finish; } events_a = sd_bus_get_events(a); if (events_a < 0) { log_error_errno(r, "Failed to get events mask: %m"); goto finish; } r = sd_bus_get_timeout(a, &timeout_a); if (r < 0) { log_error_errno(r, "Failed to get timeout: %m"); goto finish; } events_b = sd_bus_get_events(b); if (events_b < 0) { log_error_errno(r, "Failed to get events mask: %m"); goto finish; } r = sd_bus_get_timeout(b, &timeout_b); if (r < 0) { log_error_errno(r, "Failed to get timeout: %m"); 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); } { struct pollfd p[3] = { {.fd = fd, .events = events_a, }, {.fd = STDIN_FILENO, .events = events_b & POLLIN, }, {.fd = STDOUT_FILENO, .events = events_b & POLLOUT, }};
static int server_init(sd_bus **_bus) { sd_bus *bus = NULL; sd_id128_t id; int r; const char *unique; assert_se(_bus); r = sd_bus_open_user(&bus); if (r < 0) { log_error_errno(r, "Failed to connect to user bus: %m"); goto fail; } r = sd_bus_get_bus_id(bus, &id); if (r < 0) { log_error_errno(r, "Failed to get server ID: %m"); goto fail; } r = sd_bus_get_unique_name(bus, &unique); if (r < 0) { log_error_errno(r, "Failed to get unique name: %m"); goto fail; } log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id)); log_info("Unique ID: %s", unique); log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h')); r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0); if (r < 0) { log_error_errno(r, "Failed to acquire name: %m"); goto fail; } r = sd_bus_add_fallback(bus, NULL, "/foo/bar", object_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add object: %m"); goto fail; } r = sd_bus_add_match(bus, NULL, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add match: %m"); goto fail; } r = sd_bus_add_match(bus, NULL, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add match: %m"); goto fail; } bus_match_dump(&bus->match_callbacks, 0); *_bus = bus; return 0; fail: if (bus) sd_bus_unref(bus); return r; }