sd-varlink: add sd_varlink_server_set_info

Fixes https://github.com/systemd/systemd/issues/35508.

As reported in the bug, the values were hardcoded for the systemd project.
https://varlink.org/Service lists vendor, product, version, url, and interfaces
as the mandatory parameters, so add an interface to set the first four. The
last field is set automatically based on the registered interfaces as before.

If the values are not filled in, we return empty strings. With NULL,
'varlinkctl info' would say:
  (string):1:25: Object field 'vendor' has wrong type null, expected string.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2024-12-10 10:43:14 +01:00
parent fbee22c237
commit 29f63c67b0
5 changed files with 49 additions and 11 deletions
+1
View File
@@ -1037,6 +1037,7 @@ global:
sd_varlink_server_set_connections_max;
sd_varlink_server_set_connections_per_uid_max;
sd_varlink_server_set_description;
sd_varlink_server_set_info;
sd_varlink_server_set_exit_on_idle;
sd_varlink_server_set_userdata;
sd_varlink_server_shutdown;
+35 -11
View File
@@ -31,7 +31,6 @@
#include "varlink-internal.h"
#include "varlink-io.systemd.h"
#include "varlink-org.varlink.service.h"
#include "version.h"
#define VARLINK_DEFAULT_CONNECTIONS_MAX 4096U
#define VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX 1024U
@@ -1193,20 +1192,16 @@ static int generic_method_get_info(
void *userdata) {
_cleanup_strv_free_ char **interfaces = NULL;
_cleanup_free_ char *product = NULL;
int r;
assert(link);
assert(link->server);
if (sd_json_variant_elements(parameters) != 0)
return sd_varlink_error_invalid_parameter(link, parameters);
product = strjoin("systemd (", program_invocation_short_name, ")");
if (!product)
return -ENOMEM;
sd_varlink_interface *interface;
HASHMAP_FOREACH(interface, ASSERT_PTR(link->server)->interfaces) {
HASHMAP_FOREACH(interface, link->server->interfaces) {
r = strv_extend(&interfaces, interface->name);
if (r < 0)
return r;
@@ -1216,10 +1211,10 @@ static int generic_method_get_info(
return sd_varlink_replybo(
link,
SD_JSON_BUILD_PAIR_STRING("vendor", "The systemd Project"),
SD_JSON_BUILD_PAIR_STRING("product", product),
SD_JSON_BUILD_PAIR_STRING("version", PROJECT_VERSION_FULL " (" GIT_VERSION ")"),
SD_JSON_BUILD_PAIR_STRING("url", "https://systemd.io/"),
SD_JSON_BUILD_PAIR_STRING("vendor", strempty(link->server->vendor)),
SD_JSON_BUILD_PAIR_STRING("product", strempty(link->server->product)),
SD_JSON_BUILD_PAIR_STRING("version", strempty(link->server->version)),
SD_JSON_BUILD_PAIR_STRING("url", strempty(link->server->url)),
SD_JSON_BUILD_PAIR_STRV("interfaces", interfaces));
}
@@ -3262,12 +3257,41 @@ static sd_varlink_server* varlink_server_destroy(sd_varlink_server *s) {
sd_event_unref(s->event);
free(s->description);
free(s->vendor);
free(s->product);
free(s->version);
free(s->url);
return mfree(s);
}
DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_varlink_server, sd_varlink_server, varlink_server_destroy);
_public_ int sd_varlink_server_set_info(
sd_varlink_server *s,
const char *vendor,
const char *product,
const char *version,
const char *url) {
assert_return(s, -EINVAL);
_cleanup_free_ char
*a = vendor ? strdup(vendor) : NULL,
*b = product ? strdup(product) : NULL,
*c = version ? strdup(version) : NULL,
*d = url ? strdup(url) : NULL;
if ((vendor && !a) || (product && !b) || (version && !c) || (url && !d))
return log_oom_debug();
free_and_replace(s->vendor, a);
free_and_replace(s->product, b);
free_and_replace(s->version, c);
free_and_replace(s->url, d);
return 0;
}
static int validate_connection(sd_varlink_server *server, const struct ucred *ucred) {
int allowed = -1;
@@ -222,7 +222,12 @@ struct sd_varlink_server {
Hashmap *by_uid; /* UID_TO_PTR(uid) → UINT_TO_PTR(n_connections) */
void *userdata;
char *description;
char *vendor;
char *product;
char *version;
char *url;
unsigned connections_max;
unsigned connections_per_uid_max;