static void start_scope_unit(sd_bus *connection, pid_t child_pid, long memory_limit, char *devices, const char *unit_name) { sd_bus_message *message = NULL; check(sd_bus_message_new_method_call(connection, &message, systemd_bus_name, systemd_path_name, manager_interface, "StartTransientUnit")); check(sd_bus_message_append(message, "ss", unit_name, "fail")); check(sd_bus_message_open_container(message, 'a', "(sv)")); check(sd_bus_message_append(message, "(sv)", "PIDs", "au", 1, child_pid)); check(sd_bus_message_append(message, "(sv)", "Description", "s", "Playpen application sandbox")); check(sd_bus_message_append(message, "(sv)", "MemoryLimit", "t", 1024ULL * 1024ULL * (unsigned long long)memory_limit)); check(sd_bus_message_append(message, "(sv)", "DevicePolicy", "s", "strict")); if (devices) { check(sd_bus_message_open_container(message, 'r', "sv")); check(sd_bus_message_append(message, "s", "DeviceAllow")); check(sd_bus_message_open_container(message, 'v', "a(ss)")); check(sd_bus_message_open_container(message, 'a', "(ss)")); for (char *s_ptr = devices, *saveptr; ; s_ptr = NULL) { const char *device = strtok_r(s_ptr, ",", &saveptr); if (!device) break; char *split = strchr(device, ':'); if (!split) errx(EXIT_FAILURE, "invalid device parameter `%s`", device); *split = '\0'; sd_bus_message_append(message, "(ss)", device, split + 1); } check(sd_bus_message_close_container(message)); check(sd_bus_message_close_container(message)); check(sd_bus_message_close_container(message)); } check(sd_bus_message_append(message, "(sv)", "CPUAccounting", "b", 1)); check(sd_bus_message_append(message, "(sv)", "BlockIOAccounting", "b", 1)); check(sd_bus_message_close_container(message)); check(sd_bus_message_append(message, "a(sa(sv))", 0)); sd_bus_error error = SD_BUS_ERROR_NULL; int rc = sd_bus_call(connection, message, 0, &error, NULL); if (rc < 0) errx(EXIT_FAILURE, "%s", sd_bus_error_is_set(&error) ? error.message : strerror(-rc)); sd_bus_message_unref(message); wait_for_unit(child_pid, unit_name); }
static int append_address(sd_bus_message *reply, DnsResourceRecord *rr) { int r; assert(reply); assert(rr); r = sd_bus_message_open_container(reply, 'r', "iay"); if (r < 0) return r; if (rr->key->type == DNS_TYPE_A) { r = sd_bus_message_append(reply, "i", AF_INET); if (r < 0) return r; r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr)); } else if (rr->key->type == DNS_TYPE_AAAA) { r = sd_bus_message_append(reply, "i", AF_INET6); if (r < 0) return r; r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr)); } else return -EAFNOSUPPORT; if (r < 0) return r; r = sd_bus_message_close_container(reply); if (r < 0) return r; return 0; }
static int adapter_set_powered(struct context *ctx, const char *path, bool powered) { sd_bus *bus = sol_bus_client_get_bus(ctx->bluez); const char *service = sol_bus_client_get_service(ctx->bluez); sd_bus_message *m; int r; m = create_property_set(bus, service, path, "org.bluez.Adapter1", "Powered"); SOL_NULL_CHECK(m, -ENOMEM); r = sd_bus_message_open_container(m, 'v', "b"); SOL_INT_CHECK_GOTO(r, < 0, done); r = sd_bus_message_append(m, "b", &powered); SOL_INT_CHECK_GOTO(r, < 0, done); r = sd_bus_message_close_container(m); SOL_INT_CHECK_GOTO(r, < 0, done); r = sd_bus_call_async(bus, NULL, m, sol_bus_log_callback, NULL, 0); SOL_INT_CHECK_GOTO(r, < 0, done); done: sd_bus_message_unref(m); return r; }
static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bus_message **ret) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; char **i; int r; assert(bus); assert(name); assert(ret); r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartTransientUnit"); if (r < 0) return r; r = sd_bus_message_append(m, "ss", name, "fail"); if (r < 0) return r; r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return r; STRV_FOREACH(i, arg_property) { r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) return r; r = bus_append_unit_property_assignment(m, *i); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return r; }
_public_ int sd_bus_set_property( sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, const char *type, ...) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; va_list ap; int r; bus_assert_return(bus, -EINVAL, error); bus_assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL, error); bus_assert_return(member_name_is_valid(member), -EINVAL, error); bus_assert_return(signature_is_single(type, false), -EINVAL, error); bus_assert_return(!bus_pid_changed(bus), -ECHILD, error); if (!BUS_IS_OPEN(bus->state)) { r = -ENOTCONN; goto fail; } r = sd_bus_message_new_method_call(bus, &m, destination, path, "org.freedesktop.DBus.Properties", "Set"); if (r < 0) goto fail; r = sd_bus_message_append(m, "ss", strempty(interface), member); if (r < 0) goto fail; r = sd_bus_message_open_container(m, 'v', type); if (r < 0) goto fail; va_start(ap, type); r = sd_bus_message_appendv(m, type, ap); va_end(ap); if (r < 0) goto fail; r = sd_bus_message_close_container(m); if (r < 0) goto fail; return sd_bus_call(bus, m, 0, error, NULL); fail: return sd_bus_error_set_errno(error, r); }
static int transient_unit_set_properties(sd_bus_message *m, char **properties) { char **i; int r; r = sd_bus_message_append(m, "(sv)", "Description", "s", arg_description); if (r < 0) return r; STRV_FOREACH(i, properties) { r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) return r; r = bus_append_unit_property_assignment(m, *i); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return r; }
int register_machine( const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; r = sd_bus_default_system(&bus); if (r < 0) return log_error_errno(r, "Failed to open system bus: %m"); if (keep_unit) { r = sd_bus_call_method( bus, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "RegisterMachineWithNetwork", &error, NULL, "sayssusai", machine_name, SD_BUS_MESSAGE_APPEND_ID128(uuid), "nspawn", "container", (uint32_t) pid, strempty(directory), local_ifindex > 0 ? 1 : 0, local_ifindex); } else { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; char **i; unsigned j; r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "CreateMachineWithNetwork"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_append( m, "sayssusai", machine_name, SD_BUS_MESSAGE_APPEND_ID128(uuid), "nspawn", "container", (uint32_t) pid, strempty(directory), local_ifindex > 0 ? 1 : 0, local_ifindex); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); if (!isempty(slice)) { r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice); if (r < 0) return bus_log_create_error(r); } r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "strict"); if (r < 0) return bus_log_create_error(r); /* If you make changes here, also make sure to update * [email protected], to keep the device * policies in sync regardless if we are run with or * without the --keep-unit switch. */ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 9, /* Allow the container to * access and create the API * device nodes, so that * PrivateDevices= in the * container can work * fine */ "/dev/null", "rwm", "/dev/zero", "rwm", "/dev/full", "rwm", "/dev/random", "rwm", "/dev/urandom", "rwm", "/dev/tty", "rwm", "/dev/net/tun", "rwm", /* Allow the container * access to ptys. However, * do not permit the * container to ever create * these device nodes. */ "/dev/pts/ptmx", "rw", "char-pts", "rw"); if (r < 0) return bus_log_create_error(r); for (j = 0; j < n_mounts; j++) { CustomMount *cm = mounts + j; if (cm->type != CUSTOM_MOUNT_BIND) continue; r = is_device_node(cm->source); if (r < 0) return log_error_errno(r, "Failed to stat %s: %m", cm->source); if (r) { r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1, cm->source, cm->read_only ? "r" : "rw"); if (r < 0) return log_error_errno(r, "Failed to append message arguments: %m"); } } if (kill_signal != 0) { r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed"); if (r < 0) return bus_log_create_error(r); } STRV_FOREACH(i, properties) { r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) return bus_log_create_error(r); r = bus_append_unit_property_assignment(m, *i); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); } r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, NULL); }
static int start_transient_service( sd_bus *bus, char **argv, int *retval) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; _cleanup_free_ char *service = NULL, *pty_path = NULL; _cleanup_close_ int master = -1; int r; assert(bus); assert(argv); assert(retval); if (arg_pty) { if (arg_transport == BUS_TRANSPORT_LOCAL) { master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY); if (master < 0) return log_error_errno(errno, "Failed to acquire pseudo tty: %m"); r = ptsname_malloc(master, &pty_path); if (r < 0) return log_error_errno(r, "Failed to determine tty name: %m"); if (unlockpt(master) < 0) return log_error_errno(errno, "Failed to unlock tty: %m"); } else if (arg_transport == BUS_TRANSPORT_MACHINE) { _cleanup_(sd_bus_unrefp) sd_bus *system_bus = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *pty_reply = NULL; const char *s; r = sd_bus_default_system(&system_bus); if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); r = sd_bus_call_method(system_bus, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "OpenMachinePTY", &error, &pty_reply, "s", arg_host); if (r < 0) { log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r)); return r; } r = sd_bus_message_read(pty_reply, "hs", &master, &s); if (r < 0) return bus_log_parse_error(r); master = fcntl(master, F_DUPFD_CLOEXEC, 3); if (master < 0) return log_error_errno(errno, "Failed to duplicate master fd: %m"); pty_path = strdup(s); if (!pty_path) return log_oom(); } else assert_not_reached("Can't allocate tty via ssh"); } if (!arg_no_block) { r = bus_wait_for_jobs_new(bus, &w); if (r < 0) return log_error_errno(r, "Could not watch jobs: %m"); } if (arg_unit) { r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); } else { r = make_unit_name(bus, UNIT_SERVICE, &service); if (r < 0) return r; } r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartTransientUnit"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); if (r < 0) return bus_log_create_error(r); /* Name and mode */ r = sd_bus_message_append(m, "ss", service, "fail"); if (r < 0) return bus_log_create_error(r); /* Properties */ r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); r = transient_service_set_properties(m, argv, pty_path); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); /* Auxiliary units */ r = sd_bus_message_append(m, "a(sa(sv))", 0); if (r < 0) return bus_log_create_error(r); polkit_agent_open_if_enabled(); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) return log_error_errno(r, "Failed to start transient service unit: %s", bus_error_message(&error, r)); if (w) { const char *object; r = sd_bus_message_read(reply, "o", &object); if (r < 0) return bus_log_parse_error(r); r = bus_wait_for_jobs_one(w, object, arg_quiet); if (r < 0) return r; } if (!arg_quiet) log_info("Running as unit: %s", service); if (arg_wait || master >= 0) { _cleanup_(run_context_free) RunContext c = {}; c.bus = sd_bus_ref(bus); r = sd_event_default(&c.event); if (r < 0) return log_error_errno(r, "Failed to get event loop: %m"); if (master >= 0) { assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGWINCH, SIGTERM, SIGINT, -1) >= 0); (void) sd_event_add_signal(c.event, NULL, SIGINT, NULL, NULL); (void) sd_event_add_signal(c.event, NULL, SIGTERM, NULL, NULL); if (!arg_quiet) log_info("Press ^] three times within 1s to disconnect TTY."); r = pty_forward_new(c.event, master, PTY_FORWARD_IGNORE_INITIAL_VHANGUP, &c.forward); if (r < 0) return log_error_errno(r, "Failed to create PTY forwarder: %m"); pty_forward_set_handler(c.forward, pty_forward_handler, &c); } if (arg_wait) { _cleanup_free_ char *path = NULL; const char *mt; path = unit_dbus_path_from_name(service); if (!path) return log_oom(); mt = strjoina("type='signal'," "sender='org.freedesktop.systemd1'," "path='", path, "'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'"); r = sd_bus_add_match(bus, &c.match, mt, on_properties_changed, &c); if (r < 0) return log_error_errno(r, "Failed to add properties changed signal."); r = sd_bus_attach_event(bus, c.event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop."); } r = sd_event_loop(c.event); if (r < 0) return log_error_errno(r, "Failed to run event loop: %m"); if (c.forward) { char last_char = 0; r = pty_forward_get_last_char(c.forward, &last_char); if (r >= 0 && !arg_quiet && last_char != '\n') fputc('\n', stdout); } if (!arg_quiet) { if (!isempty(c.result)) log_info("Finished with result: %s", strna(c.result)); if (c.exit_code == CLD_EXITED) log_info("Main processes terminated with: code=%s/status=%i", sigchld_code_to_string(c.exit_code), c.exit_status); else if (c.exit_code > 0) log_info("Main processes terminated with: code=%s/status=%s", sigchld_code_to_string(c.exit_code), signal_to_string(c.exit_status)); if (c.inactive_enter_usec > 0 && c.inactive_enter_usec != USEC_INFINITY && c.inactive_exit_usec > 0 && c.inactive_exit_usec != USEC_INFINITY && c.inactive_enter_usec > c.inactive_exit_usec) { char ts[FORMAT_TIMESPAN_MAX]; log_info("Service runtime: %s", format_timespan(ts, sizeof(ts), c.inactive_enter_usec - c.inactive_exit_usec, USEC_PER_MSEC)); } if (c.cpu_usage_nsec > 0 && c.cpu_usage_nsec != NSEC_INFINITY) { char ts[FORMAT_TIMESPAN_MAX]; log_info("CPU time consumed: %s", format_timespan(ts, sizeof(ts), (c.cpu_usage_nsec + NSEC_PER_USEC - 1) / NSEC_PER_USEC, USEC_PER_MSEC)); } } /* Try to propagate the service's return value */ if (c.result && STR_IN_SET(c.result, "success", "exit-code") && c.exit_code == CLD_EXITED) *retval = c.exit_status; else *retval = EXIT_FAILURE; } return 0; }
static int start_transient_scope( sd_bus *bus, char **argv) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; _cleanup_strv_free_ char **env = NULL, **user_env = NULL; _cleanup_free_ char *scope = NULL; const char *object = NULL; int r; assert(bus); assert(argv); r = bus_wait_for_jobs_new(bus, &w); if (r < 0) return log_oom(); if (arg_unit) { r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".scope", &scope); if (r < 0) return log_error_errno(r, "Failed to mangle scope name: %m"); } else { r = make_unit_name(bus, UNIT_SCOPE, &scope); if (r < 0) return r; } r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartTransientUnit"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); if (r < 0) return bus_log_create_error(r); /* Name and Mode */ r = sd_bus_message_append(m, "ss", scope, "fail"); if (r < 0) return bus_log_create_error(r); /* Properties */ r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); r = transient_scope_set_properties(m); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); /* Auxiliary units */ r = sd_bus_message_append(m, "a(sa(sv))", 0); if (r < 0) return bus_log_create_error(r); polkit_agent_open_if_enabled(); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { log_error("Failed to start transient scope unit: %s", bus_error_message(&error, -r)); return r; } if (arg_nice_set) { if (setpriority(PRIO_PROCESS, 0, arg_nice) < 0) return log_error_errno(errno, "Failed to set nice level: %m"); } if (arg_exec_group) { gid_t gid; r = get_group_creds(&arg_exec_group, &gid); if (r < 0) return log_error_errno(r, "Failed to resolve group %s: %m", arg_exec_group); if (setresgid(gid, gid, gid) < 0) return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid); } if (arg_exec_user) { const char *home, *shell; uid_t uid; gid_t gid; r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell); if (r < 0) return log_error_errno(r, "Failed to resolve user %s: %m", arg_exec_user); r = strv_extendf(&user_env, "HOME=%s", home); if (r < 0) return log_oom(); r = strv_extendf(&user_env, "SHELL=%s", shell); if (r < 0) return log_oom(); r = strv_extendf(&user_env, "USER=%s", arg_exec_user); if (r < 0) return log_oom(); r = strv_extendf(&user_env, "LOGNAME=%s", arg_exec_user); if (r < 0) return log_oom(); if (!arg_exec_group) { if (setresgid(gid, gid, gid) < 0) return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid); } if (setresuid(uid, uid, uid) < 0) return log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", uid); } env = strv_env_merge(3, environ, user_env, arg_environment); if (!env) return log_oom(); r = sd_bus_message_read(reply, "o", &object); if (r < 0) return bus_log_parse_error(r); r = bus_wait_for_jobs_one(w, object, arg_quiet); if (r < 0) return r; if (!arg_quiet) log_info("Running scope as unit: %s", scope); execvpe(argv[0], argv, env); return log_error_errno(errno, "Failed to execute: %m"); }
static void bus_method_resolve_record_complete(DnsQuery *q) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; unsigned added = 0, i; int r; assert(q); if (q->state != DNS_TRANSACTION_SUCCESS) { r = reply_query_state(q); goto finish; } r = sd_bus_message_new_method_return(q->request, &reply); if (r < 0) goto finish; r = sd_bus_message_append(reply, "i", q->answer_ifindex); if (r < 0) goto finish; r = sd_bus_message_open_container(reply, 'a', "(qqay)"); if (r < 0) goto finish; if (q->answer) { answer = dns_answer_ref(q->answer); for (i = 0; i < answer->n_rrs; i++) { _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; size_t start; r = dns_question_matches_rr(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r == 0) continue; r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0); if (r < 0) goto finish; r = dns_packet_append_rr(p, answer->rrs[i], &start); if (r < 0) goto finish; r = sd_bus_message_open_container(reply, 'r', "qqay"); if (r < 0) goto finish; r = sd_bus_message_append(reply, "qq", answer->rrs[i]->key->class, answer->rrs[i]->key->type); if (r < 0) goto finish; r = sd_bus_message_append_array(reply, 'y', DNS_PACKET_DATA(p) + start, p->size - start); if (r < 0) goto finish; r = sd_bus_message_close_container(reply); if (r < 0) goto finish; added ++; } }
static int ratbagd_profile_get_resolutions(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) { struct ratbagd_profile *profile = userdata; unsigned int i, n_resolutions; int r; r = sd_bus_message_open_container(reply, 'a', "a{sv}"); if (r < 0) return r; n_resolutions = ratbag_profile_get_num_resolutions(profile->lib_profile); for (i = 0; i < n_resolutions; ++i) { struct ratbag_resolution *resolution; bool cap_separate_xy_resolution; unsigned int dpi_x, dpi_y, report_rate; resolution = ratbag_profile_get_resolution(profile->lib_profile, i); if (!resolution) continue; cap_separate_xy_resolution = ratbag_resolution_has_capability(resolution, RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION); report_rate = ratbag_resolution_get_report_rate(resolution); if (cap_separate_xy_resolution) { dpi_x = ratbag_resolution_get_dpi_x(resolution); dpi_y = ratbag_resolution_get_dpi_y(resolution); } else { dpi_x = ratbag_resolution_get_dpi(resolution); } r = sd_bus_message_open_container(reply, 'a', "{sv}"); if (r < 0) return r; if (cap_separate_xy_resolution) { r = sd_bus_message_append(reply, "{sv}", "dpi-x", "u", dpi_x); if (r < 0) return r; r = sd_bus_message_append(reply, "{sv}", "dpi-y", "u", dpi_y); if (r < 0) return r; } else { r = sd_bus_message_append(reply, "{sv}", "dpi", "u", dpi_x); if (r < 0) return r; } r = sd_bus_message_append(reply, "{sv}", "report-rate", "u", report_rate); if (r < 0) return r; r = sd_bus_message_close_container(reply); if (r < 0) return r; } return sd_bus_message_close_container(reply); }
static void bus_method_resolve_hostname_complete(DnsQuery *q) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *canonical = NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; unsigned added = 0, i; int r; assert(q); if (q->state != DNS_TRANSACTION_SUCCESS) { r = reply_query_state(q); goto finish; } r = sd_bus_message_new_method_return(q->request, &reply); if (r < 0) goto finish; r = sd_bus_message_append(reply, "i", q->answer_ifindex); if (r < 0) goto finish; r = sd_bus_message_open_container(reply, 'a', "(iay)"); if (r < 0) goto finish; if (q->answer) { answer = dns_answer_ref(q->answer); for (i = 0; i < answer->n_rrs; i++) { r = dns_question_matches_rr(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r == 0) { /* Hmm, if this is not an address record, maybe it's a cname? If so, remember this */ r = dns_question_matches_cname(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r > 0) cname = dns_resource_record_ref(answer->rrs[i]); continue; } r = append_address(reply, answer->rrs[i]); if (r < 0) goto finish; if (!canonical) canonical = dns_resource_record_ref(answer->rrs[i]); added ++; } } if (added <= 0) { if (!cname) { r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of requested type", q->request_hostname); goto finish; } /* This has a cname? Then update the query with the * new cname. */ r = dns_query_cname_redirect(q, cname->cname.name); if (r < 0) { if (r == -ELOOP) r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname); else r = sd_bus_reply_method_errno(q->request, -r, NULL); goto finish; } /* Before we restart the query, let's see if any of * the RRs we already got already answers our query */ for (i = 0; i < answer->n_rrs; i++) { r = dns_question_matches_rr(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r == 0) continue; r = append_address(reply, answer->rrs[i]); if (r < 0) goto finish; if (!canonical) canonical = dns_resource_record_ref(answer->rrs[i]); added++; } /* If we didn't find anything, then let's restart the * query, this time with the cname */ if (added <= 0) { r = dns_query_go(q); if (r == -ESRCH) { r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found"); goto finish; } if (r < 0) { r = sd_bus_reply_method_errno(q->request, -r, NULL); goto finish; } return; } } r = sd_bus_message_close_container(reply); if (r < 0) goto finish; /* Return the precise spelling and uppercasing reported by the server */ assert(canonical); r = sd_bus_message_append(reply, "st", DNS_RESOURCE_KEY_NAME(canonical->key), SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family)); if (r < 0) goto finish; r = sd_bus_send(q->manager->bus, reply, NULL); finish: if (r < 0) { log_error_errno(r, "Failed to send hostname reply: %m"); sd_bus_reply_method_errno(q->request, -r, NULL); } dns_query_free(q); }
static void bus_method_resolve_address_complete(DnsQuery *q) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; unsigned added = 0, i; int r; assert(q); if (q->state != DNS_TRANSACTION_SUCCESS) { r = reply_query_state(q); goto finish; } r = sd_bus_message_new_method_return(q->request, &reply); if (r < 0) goto finish; r = sd_bus_message_append(reply, "i", q->answer_ifindex); if (r < 0) goto finish; r = sd_bus_message_open_container(reply, 'a', "s"); if (r < 0) goto finish; if (q->answer) { answer = dns_answer_ref(q->answer); for (i = 0; i < answer->n_rrs; i++) { r = dns_question_matches_rr(q->question, answer->rrs[i]); if (r < 0) goto finish; if (r == 0) continue; r = sd_bus_message_append(reply, "s", answer->rrs[i]->ptr.name); if (r < 0) goto finish; added ++; } } if (added <= 0) { _cleanup_free_ char *ip = NULL; in_addr_to_string(q->request_family, &q->request_address, &ip); r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", ip); goto finish; } r = sd_bus_message_close_container(reply); if (r < 0) goto finish; r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family)); if (r < 0) goto finish; r = sd_bus_send(q->manager->bus, reply, NULL); finish: if (r < 0) { log_error_errno(r, "Failed to send address reply: %m"); sd_bus_reply_method_errno(q->request, -r, NULL); } dns_query_free(q); }
int main(int argc, char *argv[]) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; int r, boolean; const char *x, *y, *z, *a, *b, *c, *d; uint8_t u, v; void *buffer = NULL; size_t sz; char *h; const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array; r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &m); assert_se(r >= 0); r = sd_bus_message_append(m, "s", "a string"); assert_se(r >= 0); r = sd_bus_message_append(m, "s", NULL); assert_se(r < 0); r = sd_bus_message_append(m, "as", 2, "string #1", "string #2"); assert_se(r >= 0); r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after"); assert_se(r >= 0); r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo"); assert_se(r >= 0); r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3"); assert_se(r >= 0); r = sd_bus_message_open_container(m, 'a', "s"); assert_se(r >= 0); r = sd_bus_message_append_basic(m, 's', "foobar"); assert_se(r >= 0); r = sd_bus_message_append_basic(m, 's', "waldo"); assert_se(r >= 0); r = sd_bus_message_close_container(m); assert_se(r >= 0); r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array)); assert_se(r >= 0); r = bus_message_seal(m, 4711); assert_se(r >= 0); bus_message_dump(m); r = bus_message_get_blob(m, &buffer, &sz); assert_se(r >= 0); h = hexmem(buffer, sz); assert_se(h); log_info("message size = %lu, contents =\n%s", (unsigned long) sz, h); free(h); #ifdef HAVE_GLIB { GDBusMessage *g; char *p; #if !defined(GLIB_VERSION_2_36) g_type_init(); #endif g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL); p = g_dbus_message_print(g, 0); log_info("%s", p); g_free(p); g_object_unref(g); } #endif { DBusMessage *w; DBusError error; dbus_error_init(&error); w = dbus_message_demarshal(buffer, sz, &error); if (!w) { log_error("%s", error.message); } else dbus_message_unref(w); } m = sd_bus_message_unref(m); r = bus_message_from_malloc(buffer, sz, NULL, 0, NULL, NULL, &m); assert_se(r >= 0); bus_message_dump(m); assert_se(sd_bus_message_rewind(m, true) >= 0); r = sd_bus_message_read(m, "sas", &x, 2, &y, &z); assert_se(r > 0); assert_se(streq(x, "a string")); assert_se(streq(y, "string #1")); assert_se(streq(z, "string #2")); r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d); assert_se(r > 0); assert_se(streq(x, "foobar")); assert_se(streq(y, "foo")); assert_se(streq(z, "bar")); assert_se(streq(a, "waldo")); assert_se(streq(b, "piep")); assert_se(streq(c, "pap")); assert_se(streq(d, "after")); r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y); assert_se(r > 0); assert_se(u == 3); assert_se(streq(x, "foo")); assert_se(v == 5); assert_se(streq(y, "waldo")); r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d); assert_se(r > 0); assert_se(boolean); assert_se(streq(x, "aaa")); assert_se(streq(y, "1")); assert_se(streq(a, "bbb")); assert_se(streq(b, "2")); assert_se(streq(c, "ccc")); assert_se(streq(d, "3")); r = sd_bus_message_read(m, "as", 2, &x, &y); assert_se(r > 0); assert_se(streq(x, "foobar")); assert_se(streq(y, "waldo")); r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz); assert_se(r > 0); assert_se(sz == sizeof(integer_array)); assert_se(memcmp(integer_array, return_array, sz) == 0); r = sd_bus_message_peek_type(m, NULL, NULL); assert_se(r == 0); return 0; }
int bus_image_common_get_metadata( Manager *m, sd_bus_message *message, const char *name_or_path, Image *image, sd_bus_error *error) { _cleanup_(portable_metadata_unrefp) PortableMetadata *os_release = NULL; _cleanup_hashmap_free_ Hashmap *unit_files = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_free_ PortableMetadata **sorted = NULL; _cleanup_strv_free_ char **matches = NULL; size_t i; int r; assert(name_or_path || image); assert(message); if (!m) { assert(image); m = image->userdata; } r = sd_bus_message_read_strv(message, &matches); if (r < 0) return r; r = bus_image_acquire(m, message, name_or_path, image, BUS_IMAGE_AUTHENTICATE_BY_PATH, "org.freedesktop.portable1.inspect-images", &image, error); if (r < 0) return r; if (r == 0) /* Will call us back */ return 1; r = portable_extract( image->path, matches, &os_release, &unit_files, error); if (r < 0) return r; r = portable_metadata_hashmap_to_sorted_array(unit_files, &sorted); if (r < 0) return r; r = sd_bus_message_new_method_return(message, &reply); if (r < 0) return r; r = sd_bus_message_append(reply, "s", image->path); if (r < 0) return r; r = append_fd(reply, os_release); if (r < 0) return r; r = sd_bus_message_open_container(reply, 'a', "{say}"); if (r < 0) return r; for (i = 0; i < hashmap_size(unit_files); i++) { r = sd_bus_message_open_container(reply, 'e', "say"); if (r < 0) return r; r = sd_bus_message_append(reply, "s", sorted[i]->name); if (r < 0) return r; r = append_fd(reply, sorted[i]); if (r < 0) return r; r = sd_bus_message_close_container(reply); if (r < 0) return r; } r = sd_bus_message_close_container(reply); if (r < 0) return r; return sd_bus_send(NULL, reply, NULL); }
//------------------------------------------------------------------------ // Takes FRU data, invokes Parser for each fru record area and updates // Inventory //------------------------------------------------------------------------ int ipmi_update_inventory(fru_area_vec_t & area_vec) { // Generic error reporter int rc = 0; // Dictionary object to hold Name:Value pair sd_bus_message *fru_dict = NULL; // SD Bus error report mechanism. sd_bus_error bus_error = SD_BUS_ERROR_NULL; // Response from sd bus calls sd_bus_message *response = NULL; // For each FRU area, extract the needed data , get it parsed and update // the Inventory. for(auto& iter : area_vec) { // Start fresh on each. sd_bus_error_free(&bus_error); sd_bus_message_unref(response); sd_bus_message_unref(fru_dict); // Constructor to allow further initializations and customization. rc = sd_bus_message_new_method_call((iter)->get_bus_type(), &fru_dict, (iter)->get_bus_name(), (iter)->get_obj_path(), (iter)->get_intf_name(), "update"); if(rc < 0) { fprintf(stderr,"ERROR: creating a update method call for bus_name:[%s]\n", (iter)->get_bus_name()); break; } // A Dictionary ({}) having (string, variant) rc = sd_bus_message_open_container(fru_dict, 'a', "{sv}"); if(rc < 0) { fprintf(stderr,"ERROR:[%d] creating a dict container:\n",errno); break; } // Fill the container with information rc = parse_fru_area((iter)->get_type(), (void *)(iter)->get_data(), (iter)->get_len(), fru_dict); if(rc < 0) { fprintf(stderr,"ERROR parsing FRU records\n"); break; } sd_bus_message_close_container(fru_dict); // Now, Make the actual call to update the FRU inventory database with the // dictionary given by FRU Parser. There is no response message expected for // this. rc = sd_bus_call((iter)->get_bus_type(), // On the System Bus fru_dict, // With the Name:value dictionary array 0, // &bus_error, // Object to return error. &response); // Response message if any. if(rc < 0) { fprintf(stderr, "ERROR:[%s] updating FRU inventory for ID:[0x%X]\n", bus_error.message, (iter)->get_fruid()); break; } else if((iter)->is_bmc_fru()) { // For FRUs that are accessible by HostBoot, host boot does all of // these. printf("SUCCESS: Updated:[%s_%d] successfully. Setting Valid bit\n", (iter)->get_name(), (iter)->get_fruid()); (iter)->set_valid(true); } else { printf("SUCCESS: Updated:[%s_%d] successfully\n", (iter)->get_name(), (iter)->get_fruid()); } } // END walking the vector of areas and updating sd_bus_error_free(&bus_error); sd_bus_message_unref(response); sd_bus_message_unref(fru_dict); return rc; }
static int start_transient_timer( sd_bus *bus, char **argv) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; _cleanup_free_ char *timer = NULL, *service = NULL; const char *object = NULL; int r; assert(bus); assert(argv); r = bus_wait_for_jobs_new(bus, &w); if (r < 0) return log_oom(); if (arg_unit) { switch (unit_name_to_type(arg_unit)) { case UNIT_SERVICE: service = strdup(arg_unit); if (!service) return log_oom(); r = unit_name_change_suffix(service, ".timer", &timer); if (r < 0) return log_error_errno(r, "Failed to change unit suffix: %m"); break; case UNIT_TIMER: timer = strdup(arg_unit); if (!timer) return log_oom(); r = unit_name_change_suffix(timer, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to change unit suffix: %m"); break; default: r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".timer", &timer); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); break; } } else { r = make_unit_name(bus, UNIT_SERVICE, &service); if (r < 0) return r; r = unit_name_change_suffix(service, ".timer", &timer); if (r < 0) return log_error_errno(r, "Failed to change unit suffix: %m"); } r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartTransientUnit"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); if (r < 0) return bus_log_create_error(r); /* Name and Mode */ r = sd_bus_message_append(m, "ss", timer, "fail"); if (r < 0) return bus_log_create_error(r); /* Properties */ r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); r = transient_timer_set_properties(m); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_open_container(m, 'a', "(sa(sv))"); if (r < 0) return bus_log_create_error(r); if (!strv_isempty(argv)) { r = sd_bus_message_open_container(m, 'r', "sa(sv)"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_append(m, "s", service); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); r = transient_service_set_properties(m, argv, NULL); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); } r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); polkit_agent_open_if_enabled(); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { log_error("Failed to start transient timer unit: %s", bus_error_message(&error, -r)); return r; } r = sd_bus_message_read(reply, "o", &object); if (r < 0) return bus_log_parse_error(r); r = bus_wait_for_jobs_one(w, object, arg_quiet); if (r < 0) return r; if (!arg_quiet) { log_info("Running timer as unit: %s", timer); if (argv[0]) log_info("Will run service as unit: %s", service); } return 0; }
int allocate_scope( sd_bus *bus, const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; _cleanup_free_ char *scope = NULL; const char *description, *object; int r; assert(bus); r = bus_wait_for_jobs_new(bus, &w); if (r < 0) return log_error_errno(r, "Could not watch job: %m"); r = unit_name_mangle_with_suffix(machine_name, UNIT_NAME_NOGLOB, ".scope", &scope); if (r < 0) return log_error_errno(r, "Failed to mangle scope name: %m"); r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartTransientUnit"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_append(m, "ss", scope, "fail"); if (r < 0) return bus_log_create_error(r); /* Properties */ r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); description = strjoina("Container ", machine_name); r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)", "PIDs", "au", 1, pid, "Description", "s", description, "Delegate", "b", 1, "Slice", "s", isempty(slice) ? "machine.slice" : slice); if (r < 0) return bus_log_create_error(r); r = append_controller_property(bus, m); if (r < 0) return r; r = append_machine_properties( m, mounts, n_mounts, kill_signal, properties); if (r < 0) return r; r = bus_append_unit_property_assignment_many(m, UNIT_SCOPE, properties); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); /* No auxiliary units */ r = sd_bus_message_append( m, "a(sa(sv))", 0); if (r < 0) return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { log_error("Failed to allocate scope: %s", bus_error_message(&error, r)); return r; } r = sd_bus_message_read(reply, "o", &object); if (r < 0) return bus_log_parse_error(r); r = bus_wait_for_jobs_one(w, object, false); if (r < 0) return r; return 0; }
int main(int argc, char *argv[]) { _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL; const char *unique; uint8_t *p; sd_bus *a, *b; int r, bus_ref; sd_bus_message *m; int f; uint64_t sz; uint32_t u32; size_t i, l; char *s; _cleanup_close_ int sfd = -1; log_set_max_level(LOG_DEBUG); assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0); bus_ref = bus_kernel_create_bus(name, false, &bus_name); if (bus_ref == -ENOENT) return EXIT_TEST_SKIP; assert_se(bus_ref >= 0); address = strappend("kernel:path=", bus_name); assert_se(address); r = sd_bus_new(&a); assert_se(r >= 0); r = sd_bus_new(&b); assert_se(r >= 0); r = sd_bus_set_address(a, address); assert_se(r >= 0); r = sd_bus_set_address(b, address); assert_se(r >= 0); r = sd_bus_start(a); assert_se(r >= 0); r = sd_bus_start(b); assert_se(r >= 0); r = sd_bus_get_unique_name(a, &unique); assert_se(r >= 0); r = sd_bus_message_new_method_call(b, &m, unique, "/a/path", "an.inter.face", "AMethod"); assert_se(r >= 0); r = sd_bus_message_open_container(m, 'r', "aysay"); assert_se(r >= 0); r = sd_bus_message_append_array_space(m, 'y', FIRST_ARRAY, (void**) &p); assert_se(r >= 0); p[0] = '<'; memset(p+1, 'L', FIRST_ARRAY-2); p[FIRST_ARRAY-1] = '>'; f = memfd_new_and_map(NULL, STRING_SIZE, (void**) &s); assert_se(f >= 0); s[0] = '<'; for (i = 1; i < STRING_SIZE-2; i++) s[i] = '0' + (i % 10); s[STRING_SIZE-2] = '>'; s[STRING_SIZE-1] = 0; munmap(s, STRING_SIZE); r = memfd_get_size(f, &sz); assert_se(r >= 0); assert_se(sz == STRING_SIZE); r = sd_bus_message_append_string_memfd(m, f, 0, (uint64_t) -1); assert_se(r >= 0); close(f); f = memfd_new_and_map(NULL, SECOND_ARRAY, (void**) &p); assert_se(f >= 0); p[0] = '<'; memset(p+1, 'P', SECOND_ARRAY-2); p[SECOND_ARRAY-1] = '>'; munmap(p, SECOND_ARRAY); r = memfd_get_size(f, &sz); assert_se(r >= 0); assert_se(sz == SECOND_ARRAY); r = sd_bus_message_append_array_memfd(m, 'y', f, 0, (uint64_t) -1); assert_se(r >= 0); close(f); r = sd_bus_message_close_container(m); assert_se(r >= 0); r = sd_bus_message_append(m, "u", 4711); assert_se(r >= 0); assert_se((sfd = memfd_new_and_map(NULL, 6, (void**) &p)) >= 0); memcpy(p, "abcd\0", 6); munmap(p, 6); assert_se(sd_bus_message_append_string_memfd(m, sfd, 1, 4) >= 0); r = bus_message_seal(m, 55, 99*USEC_PER_SEC); assert_se(r >= 0); bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); r = sd_bus_send(b, m, NULL); assert_se(r >= 0); sd_bus_message_unref(m); r = sd_bus_process(a, &m); assert_se(r > 0); bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); sd_bus_message_rewind(m, true); r = sd_bus_message_enter_container(m, 'r', "aysay"); assert_se(r > 0); r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l); assert_se(r > 0); assert_se(l == FIRST_ARRAY); assert_se(p[0] == '<'); for (i = 1; i < l-1; i++) assert_se(p[i] == 'L'); assert_se(p[l-1] == '>'); r = sd_bus_message_read(m, "s", &s); assert_se(r > 0); assert_se(s[0] == '<'); for (i = 1; i < STRING_SIZE-2; i++) assert_se(s[i] == (char) ('0' + (i % 10))); assert_se(s[STRING_SIZE-2] == '>'); assert_se(s[STRING_SIZE-1] == 0); r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l); assert_se(r > 0); assert_se(l == SECOND_ARRAY); assert_se(p[0] == '<'); for (i = 1; i < l-1; i++) assert_se(p[i] == 'P'); assert_se(p[l-1] == '>'); r = sd_bus_message_exit_container(m); assert_se(r > 0); r = sd_bus_message_read(m, "u", &u32); assert_se(r > 0); assert_se(u32 == 4711); r = sd_bus_message_read(m, "s", &s); assert_se(r > 0); assert_se(streq_ptr(s, "bcd")); sd_bus_message_unref(m); sd_bus_unref(a); sd_bus_unref(b); return 0; }
int bus_test_polkit( sd_bus_message *call, int capability, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e) { int r; assert(call); assert(action); /* Tests non-interactively! */ r = check_good_user(call, good_user); if (r != 0) return r; r = sd_bus_query_sender_privilege(call, capability); if (r < 0) return r; else if (r > 0) return 1; #ifdef ENABLE_POLKIT else { _cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; int authorized = false, challenge = false; const char *sender, **k, **v; sender = sd_bus_message_get_sender(call); if (!sender) return -EBADMSG; r = sd_bus_message_new_method_call( call->bus, &request, "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", "org.freedesktop.PolicyKit1.Authority", "CheckAuthorization"); if (r < 0) return r; r = sd_bus_message_append( request, "(sa{sv})s", "system-bus-name", 1, "name", "s", sender, action); if (r < 0) return r; r = sd_bus_message_open_container(request, 'a', "{ss}"); if (r < 0) return r; STRV_FOREACH_PAIR(k, v, details) { r = sd_bus_message_append(request, "{ss}", *k, *v); if (r < 0) return r; } r = sd_bus_message_close_container(request); if (r < 0) return r; r = sd_bus_message_append(request, "us", 0, NULL); if (r < 0) return r; r = sd_bus_call(call->bus, request, 0, e, &reply); if (r < 0) { /* Treat no PK available as access denied */ if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) { sd_bus_error_free(e); return -EACCES; } return r; } r = sd_bus_message_enter_container(reply, 'r', "bba{ss}"); if (r < 0) return r; r = sd_bus_message_read(reply, "bb", &authorized, &challenge); if (r < 0) return r; if (authorized) return 1; if (_challenge) { *_challenge = challenge; return 0; } }
int register_machine( sd_bus *bus, const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit, const char *service) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(bus); if (keep_unit) { r = sd_bus_call_method( bus, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "RegisterMachineWithNetwork", &error, NULL, "sayssusai", machine_name, SD_BUS_MESSAGE_APPEND_ID128(uuid), service, "container", (uint32_t) pid, strempty(directory), local_ifindex > 0 ? 1 : 0, local_ifindex); } else { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "CreateMachineWithNetwork"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_append( m, "sayssusai", machine_name, SD_BUS_MESSAGE_APPEND_ID128(uuid), service, "container", (uint32_t) pid, strempty(directory), local_ifindex > 0 ? 1 : 0, local_ifindex); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); if (!isempty(slice)) { r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice); if (r < 0) return bus_log_create_error(r); } r = append_controller_property(bus, m); if (r < 0) return r; r = append_machine_properties( m, mounts, n_mounts, kill_signal, properties); if (r < 0) return r; r = bus_append_unit_property_assignment_many(m, UNIT_SERVICE, properties); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); r = sd_bus_call(bus, m, 0, &error, NULL); } if (r < 0) { log_error("Failed to register machine: %s", bus_error_message(&error, r)); return r; } return 0; }
static int transient_service_set_properties(sd_bus_message *m, char **argv, const char *pty_path) { int r; assert(m); r = transient_unit_set_properties(m, arg_property); if (r < 0) return r; r = transient_kill_set_properties(m); if (r < 0) return r; r = transient_cgroup_set_properties(m); if (r < 0) return r; if (arg_wait) { r = sd_bus_message_append(m, "(sv)", "AddRef", "b", 1); if (r < 0) return r; } if (arg_remain_after_exit) { r = sd_bus_message_append(m, "(sv)", "RemainAfterExit", "b", arg_remain_after_exit); if (r < 0) return r; } if (arg_service_type) { r = sd_bus_message_append(m, "(sv)", "Type", "s", arg_service_type); if (r < 0) return r; } if (arg_exec_user) { r = sd_bus_message_append(m, "(sv)", "User", "s", arg_exec_user); if (r < 0) return r; } if (arg_exec_group) { r = sd_bus_message_append(m, "(sv)", "Group", "s", arg_exec_group); if (r < 0) return r; } if (arg_nice_set) { r = sd_bus_message_append(m, "(sv)", "Nice", "i", arg_nice); if (r < 0) return r; } if (pty_path) { const char *e; r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)", "StandardInput", "s", "tty", "StandardOutput", "s", "tty", "StandardError", "s", "tty", "TTYPath", "s", pty_path); if (r < 0) return r; e = getenv("TERM"); if (e) { char *n; n = strjoina("TERM=", e); r = sd_bus_message_append(m, "(sv)", "Environment", "as", 1, n); if (r < 0) return r; } } if (!strv_isempty(arg_environment)) { r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) return r; r = sd_bus_message_append(m, "s", "Environment"); if (r < 0) return r; r = sd_bus_message_open_container(m, 'v', "as"); if (r < 0) return r; r = sd_bus_message_append_strv(m, arg_environment); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return r; } /* Exec container */ { r = sd_bus_message_open_container(m, 'r', "sv"); if (r < 0) return r; r = sd_bus_message_append(m, "s", "ExecStart"); if (r < 0) return r; r = sd_bus_message_open_container(m, 'v', "a(sasb)"); if (r < 0) return r; r = sd_bus_message_open_container(m, 'a', "(sasb)"); if (r < 0) return r; r = sd_bus_message_open_container(m, 'r', "sasb"); if (r < 0) return r; r = sd_bus_message_append(m, "s", argv[0]); if (r < 0) return r; r = sd_bus_message_append_strv(m, argv); if (r < 0) return r; r = sd_bus_message_append(m, "b", false); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return r; r = sd_bus_message_close_container(m); if (r < 0) return r; } return 0; }
int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; Machine *m = userdata; int r; assert(message); assert(m); r = sd_bus_message_new_method_return(message, &reply); if (r < 0) return r; r = sd_bus_message_open_container(reply, 'a', "(iay)"); if (r < 0) return r; switch (m->class) { case MACHINE_HOST: { _cleanup_free_ struct local_address *addresses = NULL; struct local_address *a; int n, i; n = local_addresses(NULL, 0, AF_UNSPEC, &addresses); if (n < 0) return n; for (a = addresses, i = 0; i < n; a++, i++) { r = sd_bus_message_open_container(reply, 'r', "iay"); if (r < 0) return r; r = sd_bus_message_append(reply, "i", addresses[i].family); if (r < 0) return r; r = sd_bus_message_append_array(reply, 'y', &addresses[i].address, FAMILY_ADDRESS_SIZE(addresses[i].family)); if (r < 0) return r; r = sd_bus_message_close_container(reply); if (r < 0) return r; } break; } case MACHINE_CONTAINER: { _cleanup_close_pair_ int pair[2] = { -1, -1 }; _cleanup_free_ char *us = NULL, *them = NULL; _cleanup_close_ int netns_fd = -1; const char *p; siginfo_t si; pid_t child; r = readlink_malloc("/proc/self/ns/net", &us); if (r < 0) return r; p = procfs_file_alloca(m->leader, "ns/net"); r = readlink_malloc(p, &them); if (r < 0) return r; if (streq(us, them)) return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name); r = namespace_open(m->leader, NULL, NULL, &netns_fd, NULL, NULL); if (r < 0) return r; if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0) return -errno; child = fork(); if (child < 0) return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m"); if (child == 0) { _cleanup_free_ struct local_address *addresses = NULL; struct local_address *a; int i, n; pair[0] = safe_close(pair[0]); r = namespace_enter(-1, -1, netns_fd, -1, -1); if (r < 0) _exit(EXIT_FAILURE); n = local_addresses(NULL, 0, AF_UNSPEC, &addresses); if (n < 0) _exit(EXIT_FAILURE); for (a = addresses, i = 0; i < n; a++, i++) { struct iovec iov[2] = { { .iov_base = &a->family, .iov_len = sizeof(a->family) }, { .iov_base = &a->address, .iov_len = FAMILY_ADDRESS_SIZE(a->family) }, }; r = writev(pair[1], iov, 2); if (r < 0) _exit(EXIT_FAILURE); } pair[1] = safe_close(pair[1]); _exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { _cleanup_free_ char *bus_name = NULL, *address = NULL; uint8_t *p; sd_bus *a, *b; int r, bus_ref; sd_bus_message *m; sd_memfd *f; uint64_t sz; uint32_t u32; size_t i, l; char *s; log_set_max_level(LOG_DEBUG); bus_ref = bus_kernel_create("deine-mutter", &bus_name); if (bus_ref == -ENOENT) return EXIT_TEST_SKIP; assert_se(bus_ref >= 0); address = strappend("kernel:path=", bus_name); assert_se(address); r = sd_bus_new(&a); assert_se(r >= 0); r = sd_bus_new(&b); assert_se(r >= 0); r = sd_bus_set_address(a, address); assert_se(r >= 0); r = sd_bus_set_address(b, address); assert_se(r >= 0); r = sd_bus_start(a); assert_se(r >= 0); r = sd_bus_start(b); assert_se(r >= 0); r = sd_bus_message_new_method_call(b, ":1.1", "/a/path", "an.inter.face", "AMethod", &m); assert_se(r >= 0); r = sd_bus_message_open_container(m, 'r', "aysay"); assert_se(r >= 0); r = sd_bus_message_append_array_space(m, 'y', FIRST_ARRAY, (void**) &p); assert_se(r >= 0); memset(p, 'L', FIRST_ARRAY); r = sd_memfd_new_and_map(&f, STRING_SIZE, (void**) &s); assert_se(r >= 0); for (i = 0; i < STRING_SIZE-1; i++) s[i] = '0' + (i % 10); s[STRING_SIZE-1] = 0; munmap(s, STRING_SIZE); r = sd_memfd_get_size(f, &sz); assert_se(r >= 0); assert_se(sz == STRING_SIZE); r = sd_bus_message_append_string_memfd(m, f); assert_se(r >= 0); sd_memfd_free(f); r = sd_memfd_new_and_map(&f, SECOND_ARRAY, (void**) &p); assert_se(r >= 0); memset(p, 'P', SECOND_ARRAY); munmap(p, SECOND_ARRAY); r = sd_memfd_get_size(f, &sz); assert_se(r >= 0); assert_se(sz == SECOND_ARRAY); r = sd_bus_message_append_array_memfd(m, 'y', f); assert_se(r >= 0); sd_memfd_free(f); r = sd_bus_message_close_container(m); assert_se(r >= 0); r = sd_bus_message_append(m, "u", 4711); assert_se(r >= 0); r = bus_message_seal(m, 55); assert_se(r >= 0); bus_message_dump(m, stdout, true); r = sd_bus_send(b, m, NULL); assert_se(r >= 0); sd_bus_message_unref(m); r = sd_bus_process(a, &m); assert_se(r > 0); bus_message_dump(m, stdout, true); sd_bus_message_rewind(m, true); r = sd_bus_message_enter_container(m, 'r', "aysay"); assert_se(r > 0); r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l); assert_se(r > 0); assert_se(l == FIRST_ARRAY); for (i = 0; i < l; i++) assert_se(p[i] == 'L'); r = sd_bus_message_read(m, "s", &s); assert_se(r > 0); for (i = 0; i < STRING_SIZE-1; i++) assert_se(s[i] == (char) ('0' + (i % 10))); assert_se(s[STRING_SIZE-1] == 0); r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l); assert_se(r > 0); assert_se(l == SECOND_ARRAY); for (i = 0; i < l; i++) assert_se(p[i] == 'P'); r = sd_bus_message_exit_container(m); assert_se(r > 0); r = sd_bus_message_read(m, "u", &u32); assert_se(r > 0); assert_se(u32 == 4711); sd_bus_message_unref(m); sd_bus_unref(a); sd_bus_unref(b); return 0; }
int main(int argc, char *argv[]) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *copy = NULL; int r, boolean; const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature; uint8_t u, v; void *buffer = NULL; size_t sz; char *h; const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array; char *s; _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL; _cleanup_fclose_ FILE *ms = NULL; size_t first_size = 0, second_size = 0, third_size = 0; _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; double dbl; uint64_t u64; r = sd_bus_default_system(&bus); if (r < 0) return EXIT_TEST_SKIP; r = sd_bus_message_new_method_call(bus, &m, "foobar.waldo", "/", "foobar.waldo", "Piep"); assert_se(r >= 0); r = sd_bus_message_append(m, ""); assert_se(r >= 0); r = sd_bus_message_append(m, "s", "a string"); assert_se(r >= 0); r = sd_bus_message_append(m, "s", NULL); assert_se(r >= 0); r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss"); assert_se(r >= 0); r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after"); assert_se(r >= 0); r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo"); assert_se(r >= 0); r = sd_bus_message_append(m, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10); assert_se(r >= 0); r = sd_bus_message_append(m, "()"); assert_se(r >= 0); r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3"); assert_se(r >= 0); r = sd_bus_message_open_container(m, 'a', "s"); assert_se(r >= 0); r = sd_bus_message_append_basic(m, 's', "foobar"); assert_se(r >= 0); r = sd_bus_message_append_basic(m, 's', "waldo"); assert_se(r >= 0); r = sd_bus_message_close_container(m); assert_se(r >= 0); r = sd_bus_message_append_string_space(m, 5, &s); assert_se(r >= 0); strcpy(s, "hallo"); r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array)); assert_se(r >= 0); r = sd_bus_message_append_array(m, 'u', NULL, 0); assert_se(r >= 0); r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/"); assert_se(r >= 0); r = bus_message_seal(m, 4711, 0); assert_se(r >= 0); bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); ms = open_memstream(&first, &first_size); bus_message_dump(m, ms, 0); fflush(ms); assert_se(!ferror(ms)); r = bus_message_get_blob(m, &buffer, &sz); assert_se(r >= 0); h = hexmem(buffer, sz); assert_se(h); log_info("message size = %zu, contents =\n%s", sz, h); free(h); #ifdef HAVE_GLIB { GDBusMessage *g; char *p; #if !defined(GLIB_VERSION_2_36) g_type_init(); #endif g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL); p = g_dbus_message_print(g, 0); log_info("%s", p); g_free(p); g_object_unref(g); } #endif #ifdef HAVE_DBUS { DBusMessage *w; DBusError error; dbus_error_init(&error); w = dbus_message_demarshal(buffer, sz, &error); if (!w) log_error("%s", error.message); else dbus_message_unref(w); dbus_error_free(&error); } #endif m = sd_bus_message_unref(m); r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m); assert_se(r >= 0); bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); fclose(ms); ms = open_memstream(&second, &second_size); bus_message_dump(m, ms, 0); fflush(ms); assert_se(!ferror(ms)); assert_se(first_size == second_size); assert_se(memcmp(first, second, first_size) == 0); assert_se(sd_bus_message_rewind(m, true) >= 0); r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature); assert_se(r > 0); assert_se(streq(x, "a string")); assert_se(streq(x2, "")); assert_se(streq(y, "string #1")); assert_se(streq(z, "string #2")); assert_se(streq(a_signature, "sba(tt)ss")); r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d); assert_se(r > 0); assert_se(streq(x, "foobar")); assert_se(streq(y, "foo")); assert_se(streq(z, "bar")); assert_se(streq(a, "waldo")); assert_se(streq(b, "piep")); assert_se(streq(c, "pap")); assert_se(streq(d, "after")); r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y); assert_se(r > 0); assert_se(u == 3); assert_se(streq(x, "foo")); assert_se(v == 5); assert_se(streq(y, "waldo")); r = sd_bus_message_read(m, "y(ty)", &v, &u64, &u); assert_se(r > 0); assert_se(v == 8); assert_se(u64 == 777); assert_se(u == 7); r = sd_bus_message_read(m, "y(yt)", &v, &u, &u64); assert_se(r > 0); assert_se(v == 9); assert_se(u == 77); assert_se(u64 == 7777); r = sd_bus_message_read(m, "y", &v); assert_se(r > 0); assert_se(v == 10); r = sd_bus_message_read(m, "()"); assert_se(r > 0); r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d); assert_se(r > 0); assert_se(boolean); assert_se(streq(x, "aaa")); assert_se(streq(y, "1")); assert_se(streq(a, "bbb")); assert_se(streq(b, "2")); assert_se(streq(c, "ccc")); assert_se(streq(d, "3")); assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0); r = sd_bus_message_read(m, "as", 2, &x, &y); assert_se(r > 0); assert_se(streq(x, "foobar")); assert_se(streq(y, "waldo")); r = sd_bus_message_read_basic(m, 's', &s); assert_se(r > 0); assert_se(streq(s, "hallo")); r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz); assert_se(r > 0); assert_se(sz == sizeof(integer_array)); assert_se(memcmp(integer_array, return_array, sz) == 0); r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz); assert_se(r > 0); assert_se(sz == 0); r = sd_bus_message_read(m, "a(stdo)", 1, &x, &u64, &dbl, &y); assert_se(r > 0); assert_se(streq(x, "foo")); assert_se(u64 == 815ULL); assert_se(fabs(dbl - 47.0) < 0.1); assert_se(streq(y, "/")); r = sd_bus_message_peek_type(m, NULL, NULL); assert_se(r == 0); r = sd_bus_message_new_method_call(bus, ©, "foobar.waldo", "/", "foobar.waldo", "Piep"); assert_se(r >= 0); r = sd_bus_message_rewind(m, true); assert_se(r >= 0); r = sd_bus_message_copy(copy, m, true); assert_se(r >= 0); r = bus_message_seal(copy, 4712, 0); assert_se(r >= 0); fclose(ms); ms = open_memstream(&third, &third_size); bus_message_dump(copy, ms, 0); fflush(ms); assert_se(!ferror(ms)); printf("<%.*s>\n", (int) first_size, first); printf("<%.*s>\n", (int) third_size, third); assert_se(first_size == third_size); assert_se(memcmp(first, third, third_size) == 0); r = sd_bus_message_rewind(m, true); assert_se(r >= 0); assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0); r = sd_bus_message_skip(m, "ssasg"); assert_se(r > 0); assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0); r = sd_bus_message_skip(m, "sass"); assert_se(r >= 0); assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0); r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()"); assert_se(r >= 0); assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0); r = sd_bus_message_read(m, "b", &boolean); assert_se(r > 0); assert_se(boolean); r = sd_bus_message_enter_container(m, 0, NULL); assert_se(r > 0); r = sd_bus_message_read(m, "(ss)", &x, &y); assert_se(r > 0); r = sd_bus_message_read(m, "(ss)", &a, &b); assert_se(r > 0); r = sd_bus_message_read(m, "(ss)", &c, &d); assert_se(r > 0); r = sd_bus_message_read(m, "(ss)", &x, &y); assert_se(r == 0); r = sd_bus_message_exit_container(m); assert_se(r >= 0); assert_se(streq(x, "aaa")); assert_se(streq(y, "1")); assert_se(streq(a, "bbb")); assert_se(streq(b, "2")); assert_se(streq(c, "ccc")); assert_se(streq(d, "3")); test_bus_label_escape(); test_bus_path_encode(); test_bus_path_encode_unique(); test_bus_path_encode_many(); return 0; }
//------------------------------------------------------------------------ // Takes FRU data, invokes Parser for each fru record area and updates // Inventory //------------------------------------------------------------------------ int ipmi_update_inventory(const uint8_t fruid, const uint8_t *fru_data, fru_area_vec_t & area_vec) { // Now, use this fru dictionary object and connect with FRU Inventory Dbus // and update the data for this FRU ID. int rc = 0; // Dictionary object to hold Name:Value pair sd_bus_message *fru_dict = NULL; // SD Bus error report mechanism. sd_bus_error bus_error = SD_BUS_ERROR_NULL; // Gets a hook onto either a SYSTEM or SESSION bus sd_bus *bus_type = ipmid_get_sd_bus_connection(); // Req message contains the specifics about which method etc that we want to // access on which bus, object sd_bus_message *response = NULL; // For each FRU area, extract the needed data , get it parsed and update // the Inventory. for(auto& iter : area_vec) { uint8_t area_type = (iter).type; uint8_t area_data[(iter).len]; memset(area_data, 0x0, sizeof(area_data)); // Grab area specific data memmove(area_data, (iter).offset, (iter).len); // Need this to get respective DBUS objects const char *area_name = NULL; if(area_type == IPMI_FRU_AREA_CHASSIS_INFO) { area_name = "CHASSIS_"; } else if(area_type == IPMI_FRU_AREA_BOARD_INFO) { area_name = "BOARD_"; } else if(area_type == IPMI_FRU_AREA_PRODUCT_INFO) { area_name = "PRODUCT_"; } else { fprintf(stderr, "ERROR: Invalid Area type :[%d]",area_type); break; } // What we need is BOARD_1, PRODUCT_1, CHASSIS_1 etc.. char fru_area_name[16] = {0}; sprintf(fru_area_name,"%s%d",area_name, fruid); #ifdef __IPMI_DEBUG__ printf("Updating Inventory with :[%s]\n",fru_area_name); #endif // Each area needs a clean set. sd_bus_error_free(&bus_error); sd_bus_message_unref(response); sd_bus_message_unref(fru_dict); // We want to call a method "getObjectFromId" on System Bus that is // made available over OpenBmc system services. rc = sd_bus_call_method(bus_type, // On the System Bus bus_name, // Service to contact object_name, // Object path intf_name, // Interface name "getObjectFromId", // Method to be called &bus_error, // object to return error &response, // Response message on success "ss", // input message (string,byte) "FRU_STR", // First argument to getObjectFromId fru_area_name); // Second Argument if(rc < 0) { fprintf(stderr, "Failed to issue method call: %s\n", bus_error.message); break; } // Method getObjectFromId returns 3 parameters and all are strings, namely // bus_name , object_path and interface name for accessing that particular // FRU over Inventory SDBUS manager. 'sss' here mentions that format. char *inv_bus_name, *inv_obj_path, *inv_intf_name; rc = sd_bus_message_read(response, "(sss)", &inv_bus_name, &inv_obj_path, &inv_intf_name); if(rc < 0) { fprintf(stderr, "Failed to parse response message:[%s]\n", strerror(-rc)); break; } #ifdef __IPMI_DEBUG__ printf("fru_area=[%s], inv_bus_name=[%s], inv_obj_path=[%s],inv_intf_name=[%s]\n", fru_area_name, inv_bus_name, inv_obj_path, inv_intf_name); #endif // Constructor to allow further initializations and customization. rc = sd_bus_message_new_method_call(bus_type, &fru_dict, inv_bus_name, inv_obj_path, inv_intf_name, "update"); if(rc < 0) { fprintf(stderr,"ERROR: creating a update method call\n"); break; } // A Dictionary ({}) having (string, variant) rc = sd_bus_message_open_container(fru_dict, 'a', "{sv}"); if(rc < 0) { fprintf(stderr,"ERROR:[%d] creating a dict container:\n",errno); break; } // Fill the container with information rc = parse_fru_area((iter).type, (void *)area_data, (iter).len, fru_dict); if(rc < 0) { fprintf(stderr,"ERROR parsing FRU records\n"); break; } sd_bus_message_close_container(fru_dict); // Now, Make the actual call to update the FRU inventory database with the // dictionary given by FRU Parser. There is no response message expected for // this. rc = sd_bus_call(bus_type, // On the System Bus fru_dict, // With the Name:value dictionary array 0, // &bus_error, // Object to return error. &response); // Response message if any. if(rc < 0) { fprintf(stderr, "ERROR:[%s] updating FRU inventory for ID:[0x%X]\n", bus_error.message, fruid); } else { printf("SUCCESS: Updated:[%s] successfully\n",fru_area_name); } } // END walking the vector of areas and updating sd_bus_error_free(&bus_error); sd_bus_message_unref(response); sd_bus_message_unref(fru_dict); sd_bus_unref(bus_type); return rc; }