Beispiel #1
0
_public_ int sd_bus_get_property_strv(
                sd_bus *bus,
                const char *destination,
                const char *path,
                const char *interface,
                const char *member,
                sd_bus_error *error,
                char ***ret) {

        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
        int r;

        assert_return(bus, -EINVAL);
        assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
        assert_return(member_name_is_valid(member), -EINVAL);
        assert_return(ret, -EINVAL);
        assert_return(!bus_pid_changed(bus), -ECHILD);

        if (!BUS_IS_OPEN(bus->state))
                return -ENOTCONN;

        r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
        if (r < 0)
                return r;

        r = sd_bus_message_enter_container(reply, 'v', NULL);
        if (r < 0)
                return r;

        r = sd_bus_message_read_strv(reply, ret);
        if (r < 0)
                return r;

        return 0;
}
Beispiel #2
0
static int list_timezones(int argc, char **argv, void *userdata) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        sd_bus *bus = userdata;
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
        int r;
        char** zones;

        r = sd_bus_call_method(bus,
                               "org.freedesktop.timedate1",
                               "/org/freedesktop/timedate1",
                               "org.freedesktop.timedate1",
                               "ListTimezones",
                               &error,
                               &reply,
                               NULL);
        if (r < 0)
                return log_error_errno(r, "Failed to request list of time zones: %s",
                                       bus_error_message(&error, r));

        r = sd_bus_message_read_strv(reply, &zones);
        if (r < 0)
                return bus_log_parse_error(r);

        (void) pager_open(arg_pager_flags);
        strv_print(zones);

        return 0;
}
Beispiel #3
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;
}
Beispiel #4
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);
}
Beispiel #5
0
static int method_notify(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
{
    printf("D-BUS Notify\n");

    const char *app_name;
    const uint32_t replaces_id;
    const char *app_icon;
    const char *summary;
    const char *body;

    int r = sd_bus_message_read(m, "susss", &app_name, &replaces_id, &app_icon, &summary, &body);
    if (r < 0) {
        fprintf(stderr, "Failed to parse parameters: %s\n", strerror(-r));
        return r;
    }

    printf("  Summary: %s\n", summary);

    // Read actions.
    char **actions;
    r = sd_bus_message_read_strv(m, &actions); // TODO: free the result!
    if (r < 0) {
        fprintf(stderr, "Failed to parse array: %s\n", strerror(-r));
        return r;
    }
    for (char **i = actions; i && *actions; i++) {
        printf("  ACTION: %s\n", *i);
    }

    // Read hints.
    r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
    if (r < 0) {
        fprintf(stderr, "Failed to parse dict: %s\n", strerror(-r));
        return r;
    }
    while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
        const char *hint;
        r = sd_bus_message_read(m, "s", &hint);
        if (r < 0) {
            fprintf(stderr, "Failed to parse hint: %s\n", strerror(-r));
            return r;
        }
        printf("  Hint: %s\n", hint);

        // For now skip values...
        r = sd_bus_message_skip(m, "v");
        if (r < 0) {
            fprintf(stderr, "Failed to skip hint value: %s\n", strerror(-r));
            return r;
        }

        r = sd_bus_message_exit_container(m);
        if (r < 0) {
            fprintf(stderr, "Failed to exit hint value container: %s\n", strerror(-r));
            return r;
        }
    }
    if (r < 0) {
        fprintf(stderr, "Failed to parse dict values: %s\n", strerror(-r));
        return r;
    }

    r = sd_bus_message_exit_container(m);
    if (r < 0) {
        fprintf(stderr, "Failed to exit hint container: %s\n", strerror(-r));
        return r;
    }

    // Read expire timeout.
    const int32_t expire_timeout;
    r = sd_bus_message_read(m, "i", &expire_timeout);
    if (r < 0) {
        fprintf(stderr, "Failed to parse expire timeout: %s\n", strerror(-r));
        return r;
    }
    printf("  Expire timeout: %d\n", expire_timeout);

    // Create notification.
    KirstuNotification *notification = kirstu_notification_new();
    notification->summary = strdup(summary);
    notification->timeout = (expire_timeout > 0) ? expire_timeout : 5000;

    return sd_bus_reply_method_return(m, "u", notification->id);
}