Beispiel #1
0
static int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
        bool modified = false;

        assert(bus);

        if (isempty(c->vc_keymap)) {

                modified =
                        !isempty(c->x11_layout) ||
                        !isempty(c->x11_model) ||
                        !isempty(c->x11_variant) ||
                        !isempty(c->x11_options);

                context_free_x11(c);
        } else {
                _cleanup_fclose_ FILE *f = NULL;
                unsigned n = 0;

                f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
                if (!f)
                        return -errno;

                for (;;) {
                        _cleanup_strv_free_ char **a = NULL;
                        int r;

                        r = read_next_mapping(f, &n, &a);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                break;

                        if (!streq(c->vc_keymap, a[0]))
                                continue;

                        if (!streq_ptr(c->x11_layout, strnulldash(a[1])) ||
                            !streq_ptr(c->x11_model, strnulldash(a[2])) ||
                            !streq_ptr(c->x11_variant, strnulldash(a[3])) ||
                            !streq_ptr(c->x11_options, strnulldash(a[4]))) {

                                if (free_and_copy(&c->x11_layout, strnulldash(a[1])) < 0 ||
                                    free_and_copy(&c->x11_model, strnulldash(a[2])) < 0 ||
                                    free_and_copy(&c->x11_variant, strnulldash(a[3])) < 0 ||
                                    free_and_copy(&c->x11_options, strnulldash(a[4])) < 0)
                                        return -ENOMEM;

                                modified = true;
                        }

                        break;
                }
        }

        if (modified) {
                int r;

                r = write_data_x11(c);
                if (r < 0)
                        log_error("Failed to set X11 keyboard layout: %s", strerror(-r));

                sd_bus_emit_properties_changed(bus,
                                "/org/freedesktop/locale1",
                                "org.freedesktop.locale1",
                                "X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
        }

        return 0;
}
Beispiel #2
0
static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) {
        Context *c = userdata;
        const char *name;
        int interactive;
        int r;

        assert(m);
        assert(c);

        r = sd_bus_message_read(m, "sb", &name, &interactive);
        if (r < 0)
                return r;

        name = empty_to_null(name);

        if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME]))
                return sd_bus_reply_method_return(m, NULL);

        r = bus_verify_polkit_async(
                        m,
                        CAP_SYS_ADMIN,
                        "org.freedesktop.hostname1.set-static-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 */

        if (isempty(name))
                c->data[PROP_STATIC_HOSTNAME] = mfree(c->data[PROP_STATIC_HOSTNAME]);
        else {
                char *h;

                if (!hostname_is_valid(name, false))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid static hostname '%s'", name);

                h = strdup(name);
                if (!h)
                        return -ENOMEM;

                free(c->data[PROP_STATIC_HOSTNAME]);
                c->data[PROP_STATIC_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: %m");
        }

        r = context_write_data_static_hostname(c);
        if (r < 0) {
                log_error_errno(r, "Failed to write static host name: %m");
                return sd_bus_error_set_errnof(error, r, "Failed to set static hostname: %m");
        }

        log_info("Changed static host name to '%s'", strna(c->data[PROP_STATIC_HOSTNAME]));

        (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "StaticHostname", NULL);

        return sd_bus_reply_method_return(m, NULL);
}
Beispiel #3
0
static int set_machine_info(Context *c, sd_bus *bus, 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(bus);
        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", interactive, &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)) {
                free(c->data[prop]);
                c->data[prop] = NULL;
        } 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]));

        sd_bus_emit_properties_changed(bus, "/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);
}
SOL_API int
sol_gatt_pending_reply(struct sol_gatt_pending *pending, int error,
    struct sol_buffer *buf)
{
    sd_bus_message *reply = NULL;
    struct context *ctx = bluetooth_get_context();
    const struct sol_gatt_attr *attr;
    const char *interface;
    int r;

    SOL_NULL_CHECK(pending, -EINVAL);

    attr = pending->attr;

    if (error) {
        r = error;
        goto done;
    }

    switch (pending->type) {
    case PENDING_READ:
    case PENDING_WRITE:
        r = sd_bus_message_new_method_return(pending->m, &reply);
        SOL_INT_CHECK(r, < 0, r);

        if (pending->type == PENDING_READ) {
            r = -EINVAL;
            SOL_NULL_CHECK_GOTO(buf, done);

            r = sd_bus_message_append_array(reply, 'y', buf->data, buf->used);
            SOL_INT_CHECK_GOTO(r, < 0, done);
        }
        break;

    case PENDING_INDICATE:
    case PENDING_NOTIFY:
        r = -EINVAL;
        pending->buf = buf;
        SOL_NULL_CHECK_GOTO(pending->buf, done);

        if (attr->type == SOL_GATT_ATTR_TYPE_DESCRIPTOR)
            interface = "org.bluez.GattDescriptor1";
        else
            interface = "org.bluez.GattCharacteristic1";

        r = sd_bus_emit_properties_changed(sol_bus_client_get_bus(ctx->bluez),
            attr->_priv, interface, "Value", NULL);
        SOL_INT_CHECK_GOTO(r, < 0, done);
        break;
    case PENDING_REMOTE_READ:
        pending->read((void *)pending->user_data, true, pending->attr, buf);
        pending->read = NULL;
        destroy_pending(pending);
        break;

    case PENDING_REMOTE_WRITE:
        pending->write((void *)pending->user_data, true, pending->attr);
        pending->write = NULL;
        destroy_pending(pending);
        break;
    }