int main(int argc, char *argv[]) { sd_bus_slot *slot = NULL; int r; char *mode = NULL; if (argc != 2) { fprintf(stderr, "syntax: %s [server|client]\n", argv[0]); return 1; } mode = argv[1]; /* Connect to system bus */ r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); goto finish; } if (!strcmp("server", mode)) { r = sd_bus_add_object_vtable(bus, &slot, OBJ, /* object path */ INT, /* interface name */ signal_vtable, NULL); if (r < 0) { fprintf(stderr, "Failed to issue method call: %s\n", strerror(-r)); goto finish; } /* Take a well-known service name so that clients can find us */ r = sd_bus_request_name(bus, INT, 0); if (r < 0) { fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r)); goto finish; } } else if (!strcmp("client", mode)) { r = sd_bus_add_match(bus, &slot, FILTER, bus_signal_cb, NULL); if (r < 0) { fprintf(stderr, "Failed: sd_bus_add_match: %s\n", strerror(-r)); goto finish; } } else { fprintf(stderr, "Invalid operating mode %s", mode); return 1; } for (;;) { /* Process requests */ r = sd_bus_process(bus, NULL); if (r < 0) { fprintf(stderr, "Failed to process bus: %s\n", strerror(-r)); goto finish; } if (r > 0) { continue; } r = sd_bus_wait(bus, (uint64_t) - 1); if (r < 0) { fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r)); goto finish; } } finish: sd_bus_slot_unref(slot); sd_bus_unref(bus); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }
/* * ------------------------------------------------ * Called as part of setting up skeleton services. * ----------------------------------------------- */ int start_led_services() { /* Generic error reporter. */ int rc = -1; int num_leds = 0; int count_leds = 0; /* Bus and slot where we are offering the LED dbus service. */ sd_bus *bus_type = NULL; sd_bus_slot *led_slot = NULL; /* For walking '/sys/class/leds/' looking for names of LED.*/ struct dirent **led_list; /* Get a hook onto system bus. */ rc = sd_bus_open_system(&bus_type); if(rc < 0) { fprintf(stderr,"Error opening system bus.\n"); return rc; } count_leds = num_leds = scandir("/sys/class/leds/", &led_list, led_select, alphasort); if(num_leds <= 0) { fprintf(stderr,"No LEDs present in the system\n"); sd_bus_slot_unref(led_slot); sd_bus_unref(bus_type); return rc; } /* Fully qualified Dbus object for a particular LED */ char led_object[128] = {0}; int len = 0; /* For each led present, announce the service on dbus. */ while(num_leds--) { memset(led_object, 0x0, sizeof(led_object)); len = snprintf(led_object, sizeof(led_object), "%s%s", "/org/openbmc/control/led/", led_list[num_leds]->d_name); if(len >= sizeof(led_object)) { fprintf(stderr, "Error. LED object is too long:[%d]\n",len); rc = -1; break; } /* Install the object */ rc = sd_bus_add_object_vtable(bus_type, &led_slot, led_object, /* object path */ "org.openbmc.Led", /* interface name */ led_control_vtable, NULL); if (rc < 0) { fprintf(stderr, "Failed to add object to dbus: %s\n", strerror(-rc)); break; } } /* Done with all registration. */ while (count_leds > 0) { free(led_list[--count_leds]); } free(led_list); /* If we had success in adding the providers, request for a bus name. */ if(rc == 0) { /* Take one in OpenBmc */ rc = sd_bus_request_name(bus_type, "org.openbmc.control.led", 0); if (rc < 0) { fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-rc)); } else { for (;;) { /* Process requests */ rc = sd_bus_process(bus_type, NULL); if (rc < 0) { fprintf(stderr, "Failed to process bus: %s\n", strerror(-rc)); break; } if (rc > 0) { continue; } rc = sd_bus_wait(bus_type, (uint64_t) - 1); if (rc < 0) { fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-rc)); break; } } } } sd_bus_slot_unref(led_slot); sd_bus_unref(bus_type); return rc; }
static void *server(void *p) { struct context *c = p; sd_bus *bus = NULL; sd_id128_t id; bool quit = false; int r; assert_se(sd_id128_randomize(&id) >= 0); assert_se(sd_bus_new(&bus) >= 0); assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0); assert_se(sd_bus_set_server(bus, 1, id) >= 0); assert_se(sd_bus_set_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0); assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0); assert_se(sd_bus_start(bus) >= 0); while (!quit) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; r = sd_bus_process(bus, &m); if (r < 0) { log_error("Failed to process requests: %s", strerror(-r)); goto fail; } if (r == 0) { r = sd_bus_wait(bus, (uint64_t) -1); if (r < 0) { log_error("Failed to wait: %s", strerror(-r)); goto fail; } continue; } if (!m) continue; log_info("Got message! member=%s", strna(sd_bus_message_get_member(m))); if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) { assert_se((sd_bus_can_send(bus, 'h') >= 1) == (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds)); r = sd_bus_message_new_method_return(bus, m, &reply); if (r < 0) { log_error("Failed to allocate return: %s", strerror(-r)); goto fail; } quit = true; } else if (sd_bus_message_is_method_call(m, NULL, NULL)) { r = sd_bus_message_new_method_error( bus, m, &SD_BUS_ERROR_MAKE("org.freedesktop.DBus.Error.UnknownMethod", "Unknown method."), &reply); if (r < 0) { log_error("Failed to allocate return: %s", strerror(-r)); goto fail; } } if (reply) { r = sd_bus_send(bus, reply, NULL); if (r < 0) { log_error("Failed to send reply: %s", strerror(-r)); goto fail; } } } r = 0; fail: if (bus) { sd_bus_flush(bus); sd_bus_unref(bus); } return INT_TO_PTR(r); }
static void* client2(void*p) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; bool quit = false; const char *mid; int r; r = sd_bus_open_user(&bus); if (r < 0) { log_error_errno(r, "Failed to connect to user bus: %m"); goto finish; } r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd.test", "/foo/bar/waldo/piep", "org.object.test", "Foobar"); if (r < 0) { log_error_errno(r, "Failed to allocate method call: %m"); goto finish; } r = sd_bus_send(bus, m, NULL); if (r < 0) { log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); goto finish; } m = sd_bus_message_unref(m); r = sd_bus_message_new_signal( bus, &m, "/foobar", "foo.bar", "Notify"); if (r < 0) { log_error_errno(r, "Failed to allocate signal: %m"); goto finish; } r = sd_bus_send(bus, m, NULL); if (r < 0) { log_error("Failed to issue signal: %s", bus_error_message(&error, -r)); goto finish; } m = sd_bus_message_unref(m); r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd.test", "/", "org.freedesktop.DBus.Peer", "GetMachineId"); if (r < 0) { log_error_errno(r, "Failed to allocate method call: %m"); goto finish; } r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); goto finish; } r = sd_bus_message_read(reply, "s", &mid); if (r < 0) { log_error_errno(r, "Failed to parse machine ID: %m"); goto finish; } log_info("Machine ID is %s.", mid); m = sd_bus_message_unref(m); r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd.test", "/", "org.freedesktop.systemd.test", "Slow"); if (r < 0) { log_error_errno(r, "Failed to allocate method call: %m"); goto finish; } reply = sd_bus_message_unref(reply); r = sd_bus_call(bus, m, 200 * USEC_PER_MSEC, &error, &reply); if (r < 0) log_info("Failed to issue method call: %s", bus_error_message(&error, -r)); else log_info("Slow call succeed."); m = sd_bus_message_unref(m); r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd.test", "/", "org.freedesktop.systemd.test", "Slow"); if (r < 0) { log_error_errno(r, "Failed to allocate method call: %m"); goto finish; } r = sd_bus_call_async(bus, NULL, m, quit_callback, &quit, 200 * USEC_PER_MSEC); if (r < 0) { log_info("Failed to issue method call: %s", bus_error_message(&error, -r)); goto finish; } while (!quit) { r = sd_bus_process(bus, NULL); if (r < 0) { log_error_errno(r, "Failed to process requests: %m"); goto finish; } if (r == 0) { r = sd_bus_wait(bus, (uint64_t) -1); if (r < 0) { log_error_errno(r, "Failed to wait: %m"); goto finish; } } } r = 0; finish: if (bus) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *q; r = sd_bus_message_new_method_call( bus, &q, "org.freedesktop.systemd.test", "/", "org.freedesktop.systemd.test", "ExitClient2"); if (r < 0) { log_error_errno(r, "Failed to allocate method call: %m"); goto finish; } (void) sd_bus_send(bus, q, NULL); } return INT_TO_PTR(r); }
static int server(sd_bus *bus) { int r; bool client1_gone = false, client2_gone = false; while (!client1_gone || !client2_gone) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; pid_t pid = 0; const char *label = NULL; r = sd_bus_process(bus, &m); if (r < 0) { log_error_errno(r, "Failed to process requests: %m"); goto fail; } if (r == 0) { r = sd_bus_wait(bus, (uint64_t) -1); if (r < 0) { log_error_errno(r, "Failed to wait: %m"); goto fail; } continue; } if (!m) continue; sd_bus_creds_get_pid(sd_bus_message_get_creds(m), &pid); sd_bus_creds_get_selinux_context(sd_bus_message_get_creds(m), &label); log_info("Got message! member=%s pid="PID_FMT" label=%s", strna(sd_bus_message_get_member(m)), pid, strna(label)); /* bus_message_dump(m); */ /* sd_bus_message_rewind(m, true); */ if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) { const char *hello; _cleanup_free_ char *lowercase = NULL; r = sd_bus_message_read(m, "s", &hello); if (r < 0) { log_error_errno(r, "Failed to get parameter: %m"); goto fail; } lowercase = strdup(hello); if (!lowercase) { r = log_oom(); goto fail; } ascii_strlower(lowercase); r = sd_bus_reply_method_return(m, "s", lowercase); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) { r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } client1_gone = true; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) { r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } client2_gone = true; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) { sleep(1); r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "FileDescriptor")) { int fd; static const char x = 'X'; r = sd_bus_message_read(m, "h", &fd); if (r < 0) { log_error_errno(r, "Failed to get parameter: %m"); goto fail; } log_info("Received fd=%d", fd); if (write(fd, &x, 1) < 0) { log_error_errno(errno, "Failed to write to fd: %m"); safe_close(fd); goto fail; } r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, NULL, NULL)) { r = sd_bus_reply_method_error( m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method.")); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } } r = 0; fail: if (bus) { sd_bus_flush(bus); sd_bus_unref(bus); } return r; }
/* * First of all, creates a transaction; * then reads the newly created bus path, * adds a match to the bus to wait until installation is really finished before notifying the user. * finally, calls InstallFiles method, and processes the bus while finished == 0. */ void *install_package(void *str) { sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *mess = NULL; sd_bus *install_bus = NULL; const char *path; int r, inhibit_fd = -1, finished = 0; r = sd_bus_open_system(&install_bus); if (r < 0) { print_and_warn(strerror(-r), ERR_LINE); goto finish; } INFO("calling CreateTransaction on bus."); r = sd_bus_call_method(install_bus, "org.freedesktop.PackageKit", "/org/freedesktop/PackageKit", "org.freedesktop.PackageKit", "CreateTransaction", &error, &mess, NULL); if (r < 0) { print_and_warn(error.message, ERR_LINE); goto finish; } if (config.inhibit) { inhibit_fd = inhibit_suspend("Package installation..."); } sd_bus_message_read(mess, "o", &path); r = sd_bus_add_match(install_bus, NULL, "type='signal',interface='org.freedesktop.PackageKit.Transaction',member='Finished'", match_callback, &finished); if (r < 0) { print_and_warn(strerror(-r), ERR_LINE); goto finish; } sd_bus_flush(install_bus); INFO("calling InstallFiles on bus."); r = sd_bus_call_method(install_bus, "org.freedesktop.PackageKit", path, "org.freedesktop.PackageKit.Transaction", "InstallFiles", &error, NULL, "tas", 0, 1, (char *)str); if (r < 0) { print_and_warn(error.message, ERR_LINE); goto finish; } while (!finished) { r = sd_bus_process(install_bus, NULL); if (r > 0) { continue; } r = sd_bus_wait(install_bus, (uint64_t) -1); if (r < 0) { break; } } finish: stop_inhibition(inhibit_fd); close_bus(&error, mess, install_bus); pthread_detach(pthread_self()); pthread_exit(NULL); }