static int x11_convert_to_vconsole_and_emit(Context *c, sd_bus_message *m) { int r; assert(m); r = vconsole_read_data(c, m); if (r < 0) return r; r = x11_convert_to_vconsole(c); if (r <= 0) return r; /* modified */ r = vconsole_write_data(c); if (r < 0) log_error_errno(r, "Failed to save virtual console keymap: %m"); sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/locale1", "org.freedesktop.locale1", "VConsoleKeymap", "VConsoleKeymapToggle", NULL); return vconsole_reload(sd_bus_message_get_bus(m)); }
static int method_echo(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { char *str; const char *intf = sd_bus_message_get_interface(m), *path = sd_bus_message_get_path(m); sd_bus *bus = sd_bus_message_get_bus(m); char response[512] = {0}; int r; /* Read the parameters */ r = sd_bus_message_read(m, "s", &str); if (r < 0) { fprintf(stderr, "Failed to parse parameters: %s\n", strerror(-r)); return r; } r = sd_bus_emit_signal(bus, path, intf, "MethodInvoked", "ss", "Echo method was invoked", path); if (r < 0) { fprintf(stderr, "Failed to emit signal: %s\n", strerror(-r)); return r; } strncat(response, path, 128); strcat(response, " says "); strncat(response, str, 128); /* Reply with the response */ return sd_bus_reply_method_return(m, "s", &response); }
static int vconsole_convert_to_x11_and_emit(Context *c, sd_bus_message *m) { int r; assert(m); r = x11_read_data(c, m); if (r < 0) return r; r = vconsole_convert_to_x11(c); if (r <= 0) return r; /* modified */ r = x11_write_data(c); if (r < 0) return log_error_errno(r, "Failed to write X11 keyboard layout: %m"); sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/locale1", "org.freedesktop.locale1", "X11Layout", "X11Model", "X11Variant", "X11Options", NULL); return 1; }
static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) { Context *c = userdata; const char *name; int interactive; char *h; int r; assert(m); assert(c); r = sd_bus_message_read(m, "sb", &name, &interactive); if (r < 0) return r; if (isempty(name)) name = c->data[PROP_STATIC_HOSTNAME]; if (isempty(name)) name = "localhost"; if (!hostname_is_valid(name, false)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", name); if (streq_ptr(name, c->data[PROP_HOSTNAME])) return sd_bus_reply_method_return(m, NULL); r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-hostname", NULL, interactive, UID_INVALID, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ h = strdup(name); if (!h) return -ENOMEM; free(c->data[PROP_HOSTNAME]); c->data[PROP_HOSTNAME] = h; r = context_update_kernel_hostname(c); if (r < 0) { log_error_errno(r, "Failed to set host name: %m"); return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r)); } log_info("Changed host name to '%s'", strna(c->data[PROP_HOSTNAME])); (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "Hostname", NULL); return sd_bus_reply_method_return(m, NULL); }
static int notify_test2(sd_bus_message *m, void *userdata, sd_bus_error *error) { int r; assert_se(sd_bus_emit_properties_changed_strv(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.ValueTest", NULL) >= 0); r = sd_bus_reply_method_return(m, NULL); assert_se(r >= 0); return 1; }
static int emit_interfaces_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) { int r; assert_se(sd_bus_emit_interfaces_removed(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL) >= 0); r = sd_bus_reply_method_return(m, NULL); assert_se(r >= 0); return 1; }
static int emit_object_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) { int r; assert_se(sd_bus_emit_object_removed(sd_bus_message_get_bus(m), "/value/a/x") >= 0); r = sd_bus_reply_method_return(m, NULL); assert_se(r >= 0); return 1; }
static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { sd_event *e = userdata; assert(m); assert(e); sd_bus_close(sd_bus_message_get_bus(m)); sd_event_exit(e, 0); return 1; }
static int bus_image_method_detach( sd_bus_message *message, void *userdata, sd_bus_error *error) { PortableChange *changes = NULL; Image *image = userdata; Manager *m = image->userdata; size_t n_changes = 0; int r, runtime; assert(message); assert(image); assert(m); r = sd_bus_message_read(message, "b", &runtime); if (r < 0) return r; r = bus_verify_polkit_async( message, CAP_SYS_ADMIN, "org.freedesktop.portable1.attach-images", NULL, false, UID_INVALID, &m->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* Will call us back */ r = portable_detach( sd_bus_message_get_bus(message), image->path, runtime ? PORTABLE_RUNTIME : 0, &changes, &n_changes, error); if (r < 0) goto finish; r = reply_portable_changes(message, changes, n_changes); finish: portable_changes_free(changes, n_changes); return r; }
static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *error) { const char *name; int r; assert(m); r = sd_bus_message_read(m, "s", &name); if (r < 0) return log_error_errno(r, "Failed to read interface name: %m"); if (!streq_ptr(name, "org.freedesktop.timesync1.Manager")) return 0; return show_timesync_status_once(sd_bus_message_get_bus(m)); }
static int cc_Calculator_split_reply_thunk( CC_IGNORE_BUS_ARG sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { int result = 0; sd_bus *bus; struct cc_client_Calculator *ii = (struct cc_client_Calculator *) userdata; int32_t whole; int32_t fraction; (void) ret_error; CC_LOG_DEBUG("invoked cc_Calculator_split_reply_thunk()\n"); assert(message); bus = sd_bus_message_get_bus(message); assert(bus); assert(ii); assert(ii->split_reply_callback); assert(ii->split_reply_slot == sd_bus_get_current_slot(bus)); result = sd_bus_message_get_errno(message); if (result != 0) { CC_LOG_ERROR("failed to receive response: %s\n", strerror(result)); goto finish; } result = sd_bus_message_read(message, "ii", &whole, &fraction); if (result < 0) { CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result)); goto finish; } CC_LOG_DEBUG("invoking callback in cc_Calculator_split_reply_thunk()\n"); CC_LOG_DEBUG("with whole=%" PRId32 ", fraction=%" PRId32 "\n", whole, fraction); ii->split_reply_callback(ii, whole, fraction); result = 1; finish: ii->split_reply_callback = NULL; ii->split_reply_slot = sd_bus_slot_unref(ii->split_reply_slot); return result; }
static int bus_image_method_get_state( sd_bus_message *message, void *userdata, sd_bus_error *error) { Image *image = userdata; PortableState state; int r; assert(message); assert(image); r = portable_get_state( sd_bus_message_get_bus(message), image->path, 0, &state, error); if (r < 0) return r; return sd_bus_reply_method_return(message, "s", portable_state_to_string(state)); }
static int cc_Ball_grab_reply_thunk( CC_IGNORE_BUS_ARG sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { int result = 0; sd_bus *bus; struct cc_client_Ball *ii = (struct cc_client_Ball *) userdata; int success_int; CC_LOG_DEBUG("invoked cc_Ball_grab_reply_thunk()\n"); assert(message); bus = sd_bus_message_get_bus(message); assert(bus); assert(ii); assert(ii->grab_reply_callback); assert(ii->grab_reply_slot == sd_bus_get_current_slot(bus)); result = sd_bus_message_get_errno(message); if (result != 0) { CC_LOG_ERROR("failed to receive response: %s\n", strerror(result)); goto finish; } result = sd_bus_message_read(message, "b", &success_int); if (result < 0) { CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result)); goto finish; } CC_LOG_DEBUG("invoking callback in cc_Ball_grab_reply_thunk()\n"); CC_LOG_DEBUG("with success=%d\n", !!success_int); ii->grab_reply_callback(ii, !!success_int); result = 1; finish: ii->grab_reply_callback = NULL; ii->grab_reply_slot = sd_bus_slot_unref(ii->grab_reply_slot); return result; }
static int set_machine_info(Context *c, sd_bus_message *m, int prop, sd_bus_message_handler_t cb, sd_bus_error *error) { int interactive; const char *name; int r; assert(c); assert(m); r = sd_bus_message_read(m, "sb", &name, &interactive); if (r < 0) return r; if (isempty(name)) name = NULL; if (streq_ptr(name, c->data[prop])) return sd_bus_reply_method_return(m, NULL); /* Since the pretty hostname should always be changed at the * same time as the static one, use the same policy action for * both... */ r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, prop == PROP_PRETTY_HOSTNAME ? "org.freedesktop.hostname1.set-static-hostname" : "org.freedesktop.hostname1.set-machine-info", NULL, interactive, UID_INVALID, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ if (isempty(name)) { c->data[prop] = mfree(c->data[prop]); } else { char *h; /* The icon name might ultimately be used as file * name, so better be safe than sorry */ if (prop == PROP_ICON_NAME && !filename_is_valid(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name); if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name); if (prop == PROP_CHASSIS && !valid_chassis(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name); if (prop == PROP_DEPLOYMENT && !valid_deployment(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid deployment '%s'", name); if (prop == PROP_LOCATION && string_has_cc(name, NULL)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid location '%s'", name); h = strdup(name); if (!h) return -ENOMEM; free(c->data[prop]); c->data[prop] = h; } r = context_write_data_machine_info(c); if (r < 0) { log_error_errno(r, "Failed to write machine info: %m"); return sd_bus_error_set_errnof(error, r, "Failed to write machine info: %s", strerror(-r)); } log_info("Changed %s to '%s'", prop == PROP_PRETTY_HOSTNAME ? "pretty host name" : prop == PROP_DEPLOYMENT ? "deployment" : prop == PROP_LOCATION ? "location" : prop == PROP_CHASSIS ? "chassis" : "icon name", strna(c->data[prop])); (void) sd_bus_emit_properties_changed( sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", prop == PROP_PRETTY_HOSTNAME ? "PrettyHostname" : prop == PROP_DEPLOYMENT ? "Deployment" : prop == PROP_LOCATION ? "Location" : prop == PROP_CHASSIS ? "Chassis" : "IconName" , NULL); return sd_bus_reply_method_return(m, NULL); }
int bus_image_common_attach( Manager *m, sd_bus_message *message, const char *name_or_path, Image *image, sd_bus_error *error) { _cleanup_strv_free_ char **matches = NULL; PortableChange *changes = NULL; PortableFlags flags = 0; const char *profile, *copy_mode; size_t n_changes = 0; int runtime, r; assert(message); assert(name_or_path || image); if (!m) { assert(image); m = image->userdata; } r = sd_bus_message_read_strv(message, &matches); if (r < 0) return r; r = sd_bus_message_read(message, "sbs", &profile, &runtime, ©_mode); if (r < 0) return r; if (streq(copy_mode, "symlink")) flags |= PORTABLE_PREFER_SYMLINK; else if (streq(copy_mode, "copy")) flags |= PORTABLE_PREFER_COPY; else if (!isempty(copy_mode)) return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Unknown copy mode '%s'", copy_mode); if (runtime) flags |= PORTABLE_RUNTIME; r = bus_image_acquire(m, message, name_or_path, image, BUS_IMAGE_AUTHENTICATE_ALL, "org.freedesktop.portable1.attach-images", &image, error); if (r < 0) return r; if (r == 0) /* Will call us back */ return 1; r = portable_attach( sd_bus_message_get_bus(message), image->path, matches, profile, flags, &changes, &n_changes, error); if (r < 0) goto finish; r = reply_portable_changes(message, changes, n_changes); finish: portable_changes_free(changes, n_changes); return r; }
int bus_image_common_remove( Manager *m, sd_bus_message *message, const char *name_or_path, Image *image, sd_bus_error *error) { _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 }; _cleanup_(sigkill_waitp) pid_t child = 0; PortableState state; int r; assert(message); assert(name_or_path || image); if (!m) { assert(image); m = image->userdata; } if (m->n_operations >= OPERATIONS_MAX) return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations."); r = bus_image_acquire(m, message, name_or_path, image, BUS_IMAGE_AUTHENTICATE_ALL, "org.freedesktop.portable1.manage-images", &image, error); if (r < 0) return r; if (r == 0) return 1; /* Will call us back */ r = portable_get_state( sd_bus_message_get_bus(message), image->path, 0, &state, error); if (r < 0) return r; if (state != PORTABLE_DETACHED) return sd_bus_error_set_errnof(error, EBUSY, "Image '%s' is not detached, refusing.", image->path); if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m"); r = safe_fork("(sd-imgrm)", FORK_RESET_SIGNALS, &child); if (r < 0) return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); if (r == 0) { errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); r = image_remove(image); if (r < 0) { (void) write(errno_pipe_fd[1], &r, sizeof(r)); _exit(EXIT_FAILURE); } _exit(EXIT_SUCCESS); } errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); r = operation_new(m, child, message, errno_pipe_fd[0], NULL); if (r < 0) return r; child = 0; errno_pipe_fd[0] = -1; return 1; }
static int bus_scope_set_transient_property( Scope *s, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) { int r; assert(s); assert(name); assert(message); flags |= UNIT_PRIVATE; if (streq(name, "TimeoutStopUSec")) return bus_set_transient_usec(UNIT(s), name, &s->timeout_stop_usec, message, flags, error); if (streq(name, "PIDs")) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; unsigned n = 0; r = sd_bus_message_enter_container(message, 'a', "u"); if (r < 0) return r; for (;;) { uint32_t upid; pid_t pid; r = sd_bus_message_read(message, "u", &upid); if (r < 0) return r; if (r == 0) break; if (upid == 0) { if (!creds) { r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds); if (r < 0) return r; } r = sd_bus_creds_get_pid(creds, &pid); if (r < 0) return r; } else pid = (uid_t) upid; r = unit_pid_attachable(UNIT(s), pid, error); if (r < 0) return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = unit_watch_pid(UNIT(s), pid); if (r < 0 && r != -EEXIST) return r; } n++; } r = sd_bus_message_exit_container(message); if (r < 0) return r; if (n <= 0) return -EINVAL; return 1; } else if (streq(name, "Controller")) { const char *controller; /* We can't support direct connections with this, as direct connections know no service or unique name * concept, but the Controller field stores exactly that. */ if (sd_bus_message_get_bus(message) != UNIT(s)->manager->api_bus) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Sorry, Controller= logic only supported via the bus."); r = sd_bus_message_read(message, "s", &controller); if (r < 0) return r; if (!isempty(controller) && !service_name_is_valid(controller)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller); if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = free_and_strdup(&s->controller, empty_to_null(controller)); if (r < 0) return r; } return 1; } return 0; }