예제 #1
0
파일: localed.c 프로젝트: Keruspe/systemd
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);
}
예제 #3
0
파일: localed.c 프로젝트: Keruspe/systemd
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;
}
예제 #4
0
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);
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
파일: bus-util.c 프로젝트: ChALkeR/systemd
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;
}
예제 #9
0
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;
}
예제 #10
0
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));
}
예제 #11
0
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;
}
예제 #12
0
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));
}
예제 #13
0
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;
}
예제 #14
0
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);
}
예제 #15
0
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, &copy_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;
}
예제 #16
0
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;
}
예제 #17
0
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;
}