diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2024-07-17 12:58:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-17 12:58:50 +0200 |
commit | d9b1ec27f7c22a6f55af9b979a57fa0c1101ddd0 (patch) | |
tree | 93f08b5f274755e0abc05563eb18350bea95f97f /src/shared | |
parent | docs: update mkosi version mentioned in HACKING.md (#33723) (diff) | |
parent | update TODO (diff) | |
download | systemd-d9b1ec27f7c22a6f55af9b979a57fa0c1101ddd0.tar.xz systemd-d9b1ec27f7c22a6f55af9b979a57fa0c1101ddd0.zip |
Merge pull request #33714 from poettering/make-varlink-public
varlink: make API public as "sd-varlink.h"
Diffstat (limited to 'src/shared')
54 files changed, 961 insertions, 7855 deletions
diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c index 00c55463c8..ed884c3001 100644 --- a/src/shared/bus-polkit.c +++ b/src/shared/bus-polkit.c @@ -7,6 +7,7 @@ #include "process-util.h" #include "strv.h" #include "user-util.h" +#include "varlink-util.h" static int bus_message_check_good_user(sd_bus_message *m, uid_t good_user) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; @@ -190,7 +191,7 @@ typedef struct AsyncPolkitQuery { sd_bus *bus; sd_bus_message *request; /* the original bus method call that triggered the polkit auth, NULL in case of varlink */ sd_bus_slot *slot; - Varlink *link; /* the original varlink method call that triggered the polkit auth, NULL in case of bus */ + sd_varlink *link; /* the original varlink method call that triggered the polkit auth, NULL in case of bus */ Hashmap *registry; sd_event_source *defer_event_source; @@ -218,7 +219,7 @@ static AsyncPolkitQuery *async_polkit_query_free(AsyncPolkitQuery *q) { sd_bus_message_unref(q->request); sd_bus_unref(q->bus); - varlink_unref(q->link); + sd_varlink_unref(q->link); async_polkit_query_action_free(q->action); @@ -374,7 +375,7 @@ static int async_polkit_process_reply(sd_bus_message *reply, AsyncPolkitQuery *q } if (q->link) { - r = varlink_dispatch_again(q->link); + r = sd_varlink_dispatch_again(q->link); if (r < 0) return r; } @@ -394,7 +395,7 @@ static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_e if (q->request) (void) sd_bus_reply_method_errno(q->request, r, NULL); if (q->link) - (void) varlink_error_errno(q->link, r); + (void) sd_varlink_error_errno(q->link, r); async_polkit_query_unref(q); } return r; @@ -625,7 +626,7 @@ int bus_verify_polkit_async_full( #endif } -static int varlink_check_good_user(Varlink *link, uid_t good_user) { +static int varlink_check_good_user(sd_varlink *link, uid_t good_user) { int r; assert(link); @@ -634,20 +635,20 @@ static int varlink_check_good_user(Varlink *link, uid_t good_user) { return false; uid_t peer_uid; - r = varlink_get_peer_uid(link, &peer_uid); + r = sd_varlink_get_peer_uid(link, &peer_uid); if (r < 0) return r; return good_user == peer_uid; } -static int varlink_check_peer_privilege(Varlink *link) { +static int varlink_check_peer_privilege(sd_varlink *link) { int r; assert(link); uid_t peer_uid; - r = varlink_get_peer_uid(link, &peer_uid); + r = sd_varlink_get_peer_uid(link, &peer_uid); if (r < 0) return r; @@ -659,7 +660,7 @@ static int varlink_check_peer_privilege(Varlink *link) { #if ENABLE_POLKIT static int bus_message_new_polkit_auth_call_for_varlink( sd_bus *bus, - Varlink *link, + sd_varlink *link, const char *action, const char **details, bool interactive, @@ -681,7 +682,7 @@ static int bus_message_new_polkit_auth_call_for_varlink( return log_debug_errno(SYNTHETIC_ERRNO(EPERM), "Failed to get peer pidfd, cannot securely authenticate."); uid_t uid; - r = varlink_get_peer_uid(link, &uid); + r = sd_varlink_get_peer_uid(link, &uid); if (r < 0) return r; @@ -717,7 +718,7 @@ static int bus_message_new_polkit_auth_call_for_varlink( return 0; } -static bool varlink_allow_interactive_authentication(Varlink *link) { +static bool varlink_allow_interactive_authentication(sd_varlink *link) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; int r; @@ -726,7 +727,7 @@ static bool varlink_allow_interactive_authentication(Varlink *link) { /* We look for the allowInteractiveAuthentication field in the message currently being dispatched, * always under the same name. */ - r = varlink_get_current_parameters(link, &v); + r = sd_varlink_get_current_parameters(link, &v); if (r < 0) { log_debug_errno(r, "Unable to query current parameters: %m"); return false; @@ -746,7 +747,7 @@ static bool varlink_allow_interactive_authentication(Varlink *link) { #endif int varlink_verify_polkit_async_full( - Varlink *link, + sd_varlink *link, sd_bus *bus, const char *action, const char **details, @@ -789,9 +790,9 @@ int varlink_verify_polkit_async_full( if (!FLAGS_SET(flags, POLKIT_DONT_REPLY)) { /* Reply with a nice error */ if (sd_bus_error_has_name(&error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED)) - (void) varlink_error(link, VARLINK_ERROR_INTERACTIVE_AUTHENTICATION_REQUIRED, NULL); + (void) sd_varlink_error(link, SD_VARLINK_ERROR_INTERACTIVE_AUTHENTICATION_REQUIRED, NULL); else if (ERRNO_IS_NEG_PRIVILEGE(r)) - (void) varlink_error(link, VARLINK_ERROR_PERMISSION_DENIED, NULL); + (void) sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, NULL); } return r; @@ -806,7 +807,7 @@ int varlink_verify_polkit_async_full( if (r < 0) return r; - r = sd_bus_attach_event(mybus, varlink_get_event(link), 0); + r = sd_bus_attach_event(mybus, sd_varlink_get_event(link), 0); if (r < 0) return r; @@ -829,7 +830,7 @@ int varlink_verify_polkit_async_full( *q = (AsyncPolkitQuery) { .n_ref = 1, - .link = varlink_ref(link), + .link = sd_varlink_ref(link), .bus = sd_bus_ref(bus), }; } @@ -866,7 +867,7 @@ int varlink_verify_polkit_async_full( #endif } -bool varlink_has_polkit_action(Varlink *link, const char *action, const char **details, Hashmap **registry) { +bool varlink_has_polkit_action(sd_varlink *link, const char *action, const char **details, Hashmap **registry) { assert(link); assert(action); assert(registry); diff --git a/src/shared/bus-polkit.h b/src/shared/bus-polkit.h index ba83cedbe1..3ee9a41d39 100644 --- a/src/shared/bus-polkit.h +++ b/src/shared/bus-polkit.h @@ -2,10 +2,10 @@ #pragma once #include "sd-bus.h" +#include "sd-varlink.h" #include "hashmap.h" #include "user-util.h" -#include "varlink.h" typedef enum PolkitFLags { POLKIT_ALLOW_INTERACTIVE = 1 << 0, /* Allow interactive auth (typically not required, because can be derived from bus message/link automatically) */ @@ -21,8 +21,8 @@ static inline int bus_verify_polkit_async(sd_bus_message *call, const char *acti return bus_verify_polkit_async_full(call, action, details, UID_INVALID, 0, registry, error); } -int varlink_verify_polkit_async_full(Varlink *link, sd_bus *bus, const char *action, const char **details, uid_t good_user, PolkitFlags flags, Hashmap **registry); -static inline int varlink_verify_polkit_async(Varlink *link, sd_bus *bus, const char *action, const char **details, Hashmap **registry) { +int varlink_verify_polkit_async_full(sd_varlink *link, sd_bus *bus, const char *action, const char **details, uid_t good_user, PolkitFlags flags, Hashmap **registry); +static inline int varlink_verify_polkit_async(sd_varlink *link, sd_bus *bus, const char *action, const char **details, Hashmap **registry) { return varlink_verify_polkit_async_full(link, bus, action, details, UID_INVALID, 0, registry); } @@ -34,4 +34,4 @@ static inline int varlink_verify_polkit_async(Varlink *link, sd_bus *bus, const .type = SD_JSON_VARIANT_BOOLEAN, \ } -bool varlink_has_polkit_action(Varlink *link, const char *action, const char **details, Hashmap **registry); +bool varlink_has_polkit_action(sd_varlink *link, const char *action, const char **details, Hashmap **registry); diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c index ba3c448db0..cdfadf3a09 100644 --- a/src/shared/creds-util.c +++ b/src/shared/creds-util.c @@ -8,6 +8,7 @@ #include "sd-id128.h" #include "sd-json.h" +#include "sd-varlink.h" #include "blockdev-util.h" #include "capability-util.h" @@ -36,7 +37,6 @@ #include "tmpfile-util.h" #include "tpm2-util.h" #include "user-util.h" -#include "varlink.h" #define PUBLIC_KEY_MAX (UINT32_C(1024) * UINT32_C(1024)) @@ -1526,18 +1526,18 @@ int decrypt_credential_and_warn(const char *validate_name, usec_t validate_times #endif int ipc_encrypt_credential(const char *name, usec_t timestamp, usec_t not_after, uid_t uid, const struct iovec *input, CredentialFlags flags, struct iovec *ret) { - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; assert(input && iovec_is_valid(input)); assert(ret); - r = varlink_connect_address(&vl, "/run/systemd/io.systemd.Credentials"); + r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.Credentials"); if (r < 0) return log_error_errno(r, "Failed to connect to io.systemd.Credentials: %m"); /* Mark anything we get from the service as sensitive, given that it might use a NULL cypher, at least in theory */ - r = varlink_set_input_sensitive(vl); + r = sd_varlink_set_input_sensitive(vl); if (r < 0) return log_error_errno(r, "Failed to enable sensitive Varlink input: %m"); @@ -1551,7 +1551,7 @@ int ipc_encrypt_credential(const char *name, usec_t timestamp, usec_t not_after, _cleanup_(sd_json_variant_unrefp) sd_json_variant *reply = NULL; const char *error_id = NULL; - r = varlink_callbo( + r = sd_varlink_callbo( vl, "io.systemd.Credentials.Encrypt", &reply, @@ -1568,7 +1568,7 @@ int ipc_encrypt_credential(const char *name, usec_t timestamp, usec_t not_after, if (streq(error_id, "io.systemd.Credentials.NoSuchUser")) return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "No such user."); - return log_error_errno(varlink_error_to_errno(error_id, reply), "Failed to encrypt: %s", error_id); + return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to encrypt: %s", error_id); } r = sd_json_dispatch( @@ -1586,17 +1586,17 @@ int ipc_encrypt_credential(const char *name, usec_t timestamp, usec_t not_after, } int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp, uid_t uid, const struct iovec *input, CredentialFlags flags, struct iovec *ret) { - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; assert(input && iovec_is_valid(input)); assert(ret); - r = varlink_connect_address(&vl, "/run/systemd/io.systemd.Credentials"); + r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.Credentials"); if (r < 0) return log_error_errno(r, "Failed to connect to io.systemd.Credentials: %m"); - r = varlink_set_input_sensitive(vl); + r = sd_varlink_set_input_sensitive(vl); if (r < 0) return log_error_errno(r, "Failed to enable sensitive Varlink input: %m"); @@ -1611,7 +1611,7 @@ int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp, _cleanup_(sd_json_variant_unrefp) sd_json_variant *reply = NULL; const char *error_id = NULL; - r = varlink_callbo( + r = sd_varlink_callbo( vl, "io.systemd.Credentials.Decrypt", &reply, @@ -1635,7 +1635,7 @@ int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp, if (streq(error_id, "io.systemd.Credentials.BadScope")) return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Scope mismtach."); - return log_error_errno(varlink_error_to_errno(error_id, reply), "Failed to decrypt: %s", error_id); + return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to decrypt: %s", error_id); } r = sd_json_dispatch( diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 28c2d7dbc0..ef730103b5 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -21,6 +21,7 @@ #include "sd-device.h" #include "sd-id128.h" #include "sd-json.h" +#include "sd-varlink.h" #include "architecture.h" #include "ask-password-api.h" @@ -77,7 +78,6 @@ #include "tmpfile-util.h" #include "udev-util.h" #include "user-util.h" -#include "varlink.h" #include "xattr-util.h" /* how many times to wait for the device nodes to appear */ @@ -4269,7 +4269,7 @@ int mountfsd_mount_image( _cleanup_(dissected_image_unrefp) DissectedImage *di = NULL; _cleanup_close_ int image_fd = -EBADF; - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; _cleanup_free_ char *ps = NULL; unsigned max_fd = UINT_MAX; const char *error_id; @@ -4278,15 +4278,15 @@ int mountfsd_mount_image( assert(path); assert(ret); - r = varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem"); + r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem"); if (r < 0) return log_error_errno(r, "Failed to connect to mountfsd: %m"); - r = varlink_set_allow_fd_passing_input(vl, true); + r = sd_varlink_set_allow_fd_passing_input(vl, true); if (r < 0) return log_error_errno(r, "Failed to enable varlink fd passing for read: %m"); - r = varlink_set_allow_fd_passing_output(vl, true); + r = sd_varlink_set_allow_fd_passing_output(vl, true); if (r < 0) return log_error_errno(r, "Failed to enable varlink fd passing for write: %m"); @@ -4294,12 +4294,12 @@ int mountfsd_mount_image( if (image_fd < 0) return log_error_errno(errno, "Failed to open '%s': %m", path); - r = varlink_push_dup_fd(vl, image_fd); + r = sd_varlink_push_dup_fd(vl, image_fd); if (r < 0) return log_error_errno(r, "Failed to push image fd into varlink connection: %m"); if (userns_fd >= 0) { - r = varlink_push_dup_fd(vl, userns_fd); + r = sd_varlink_push_dup_fd(vl, userns_fd); if (r < 0) return log_error_errno(r, "Failed to push image fd into varlink connection: %m"); } @@ -4311,7 +4311,7 @@ int mountfsd_mount_image( } sd_json_variant *reply = NULL; - r = varlink_callbo( + r = sd_varlink_callbo( vl, "io.systemd.MountFileSystem.MountImage", &reply, @@ -4325,7 +4325,7 @@ int mountfsd_mount_image( if (r < 0) return log_error_errno(r, "Failed to call MountImage() varlink call: %m"); if (!isempty(error_id)) - return log_error_errno(varlink_error_to_errno(error_id, reply), "Failed to call MountImage() varlink call: %s", error_id); + return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to call MountImage() varlink call: %s", error_id); r = sd_json_dispatch(reply, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &p); if (r < 0) @@ -4368,7 +4368,7 @@ int mountfsd_mount_image( if (max_fd == UINT_MAX || pp.fsmount_fd_idx > max_fd) max_fd = pp.fsmount_fd_idx; - fsmount_fd = varlink_take_fd(vl, pp.fsmount_fd_idx); + fsmount_fd = sd_varlink_take_fd(vl, pp.fsmount_fd_idx); if (fsmount_fd < 0) return fsmount_fd; } diff --git a/src/shared/meson.build b/src/shared/meson.build index 2250af703a..8fc39429e5 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -175,9 +175,6 @@ shared_sources = files( 'user-record.c', 'userdb-dropin.c', 'userdb.c', - 'varlink.c', - 'varlink-idl.c', - 'varlink-io.systemd.c', 'varlink-io.systemd.BootControl.c', 'varlink-io.systemd.Credentials.c', 'varlink-io.systemd.Hostname.c', @@ -196,7 +193,7 @@ shared_sources = files( 'varlink-io.systemd.oom.c', 'varlink-io.systemd.service.c', 'varlink-io.systemd.sysext.c', - 'varlink-org.varlink.service.c', + 'varlink-serialize.c', 'verb-log-control.c', 'verbs.c', 'vlan-util.c', diff --git a/src/shared/nsresource.c b/src/shared/nsresource.c index 5a34301377..4a2a9d2e41 100644 --- a/src/shared/nsresource.c +++ b/src/shared/nsresource.c @@ -2,6 +2,8 @@ #include <sys/prctl.h> +#include "sd-varlink.h" + #include "fd-util.h" #include "format-util.h" #include "json-util.h" @@ -9,7 +11,6 @@ #include "namespace-util.h" #include "nsresource.h" #include "process-util.h" -#include "varlink.h" static int make_pid_name(char **ret) { char comm[TASK_COMM_LEN]; @@ -40,7 +41,7 @@ static int make_pid_name(char **ret) { } int nsresource_allocate_userns(const char *name, uint64_t size) { - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; _cleanup_close_ int userns_fd = -EBADF; _cleanup_free_ char *_name = NULL; const char *error_id; @@ -59,11 +60,11 @@ int nsresource_allocate_userns(const char *name, uint64_t size) { if (size <= 0 || size > UINT64_C(0x100000000)) /* Note: the server actually only allows allocating 1 or 64K right now */ return -EINVAL; - r = varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); + r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); if (r < 0) return log_debug_errno(r, "Failed to connect to namespace resource manager: %m"); - r = varlink_set_allow_fd_passing_output(vl, true); + r = sd_varlink_set_allow_fd_passing_output(vl, true); if (r < 0) return log_debug_errno(r, "Failed to enable varlink fd passing for write: %m"); @@ -71,12 +72,12 @@ int nsresource_allocate_userns(const char *name, uint64_t size) { if (userns_fd < 0) return log_debug_errno(userns_fd, "Failed to acquire empty user namespace: %m"); - userns_fd_idx = varlink_push_dup_fd(vl, userns_fd); + userns_fd_idx = sd_varlink_push_dup_fd(vl, userns_fd); if (userns_fd_idx < 0) return log_debug_errno(userns_fd_idx, "Failed to push userns fd into varlink connection: %m"); sd_json_variant *reply = NULL; - r = varlink_callbo( + r = sd_varlink_callbo( vl, "io.systemd.NamespaceResource.AllocateUserRange", &reply, @@ -87,13 +88,13 @@ int nsresource_allocate_userns(const char *name, uint64_t size) { if (r < 0) return log_debug_errno(r, "Failed to call AllocateUserRange() varlink call: %m"); if (error_id) - return log_debug_errno(varlink_error_to_errno(error_id, reply), "Failed to allocate user namespace with %" PRIu64 " users: %s", size, error_id); + return log_debug_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to allocate user namespace with %" PRIu64 " users: %s", size, error_id); return TAKE_FD(userns_fd); } int nsresource_register_userns(const char *name, int userns_fd) { - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; _cleanup_close_ int _userns_fd = -EBADF; _cleanup_free_ char *_name = NULL; const char *error_id; @@ -117,20 +118,20 @@ int nsresource_register_userns(const char *name, int userns_fd) { userns_fd = _userns_fd; } - r = varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); + r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); if (r < 0) return log_debug_errno(r, "Failed to connect to namespace resource manager: %m"); - r = varlink_set_allow_fd_passing_output(vl, true); + r = sd_varlink_set_allow_fd_passing_output(vl, true); if (r < 0) return log_debug_errno(r, "Failed to enable varlink fd passing for write: %m"); - userns_fd_idx = varlink_push_dup_fd(vl, userns_fd); + userns_fd_idx = sd_varlink_push_dup_fd(vl, userns_fd); if (userns_fd_idx < 0) return log_debug_errno(userns_fd_idx, "Failed to push userns fd into varlink connection: %m"); sd_json_variant *reply = NULL; - r = varlink_callbo( + r = sd_varlink_callbo( vl, "io.systemd.NamespaceResource.RegisterUserNamespace", &reply, @@ -140,13 +141,13 @@ int nsresource_register_userns(const char *name, int userns_fd) { if (r < 0) return log_debug_errno(r, "Failed to call RegisterUserNamespace() varlink call: %m"); if (error_id) - return log_debug_errno(varlink_error_to_errno(error_id, reply), "Failed to register user namespace: %s", error_id); + return log_debug_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to register user namespace: %s", error_id); return 0; } int nsresource_add_mount(int userns_fd, int mount_fd) { - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; _cleanup_close_ int _userns_fd = -EBADF; int r, userns_fd_idx, mount_fd_idx; const char *error_id; @@ -161,24 +162,24 @@ int nsresource_add_mount(int userns_fd, int mount_fd) { userns_fd = _userns_fd; } - r = varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); + r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); if (r < 0) return log_error_errno(r, "Failed to connect to namespace resource manager: %m"); - r = varlink_set_allow_fd_passing_output(vl, true); + r = sd_varlink_set_allow_fd_passing_output(vl, true); if (r < 0) return log_error_errno(r, "Failed to enable varlink fd passing for write: %m"); - userns_fd_idx = varlink_push_dup_fd(vl, userns_fd); + userns_fd_idx = sd_varlink_push_dup_fd(vl, userns_fd); if (userns_fd_idx < 0) return log_error_errno(userns_fd_idx, "Failed to push userns fd into varlink connection: %m"); - mount_fd_idx = varlink_push_dup_fd(vl, mount_fd); + mount_fd_idx = sd_varlink_push_dup_fd(vl, mount_fd); if (mount_fd_idx < 0) return log_error_errno(mount_fd_idx, "Failed to push mount fd into varlink connection: %m"); sd_json_variant *reply = NULL; - r = varlink_callbo( + r = sd_varlink_callbo( vl, "io.systemd.NamespaceResource.AddMountToUserNamespace", &reply, @@ -192,13 +193,13 @@ int nsresource_add_mount(int userns_fd, int mount_fd) { return 0; } if (error_id) - return log_error_errno(varlink_error_to_errno(error_id, reply), "Failed to mount image: %s", error_id); + return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to mount image: %s", error_id); return 1; } int nsresource_add_cgroup(int userns_fd, int cgroup_fd) { - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; _cleanup_close_ int _userns_fd = -EBADF; int r, userns_fd_idx, cgroup_fd_idx; const char *error_id; @@ -213,24 +214,24 @@ int nsresource_add_cgroup(int userns_fd, int cgroup_fd) { userns_fd = _userns_fd; } - r = varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); + r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); if (r < 0) return log_debug_errno(r, "Failed to connect to namespace resource manager: %m"); - r = varlink_set_allow_fd_passing_output(vl, true); + r = sd_varlink_set_allow_fd_passing_output(vl, true); if (r < 0) return log_debug_errno(r, "Failed to enable varlink fd passing for write: %m"); - userns_fd_idx = varlink_push_dup_fd(vl, userns_fd); + userns_fd_idx = sd_varlink_push_dup_fd(vl, userns_fd); if (userns_fd_idx < 0) return log_debug_errno(userns_fd_idx, "Failed to push userns fd into varlink connection: %m"); - cgroup_fd_idx = varlink_push_dup_fd(vl, cgroup_fd); + cgroup_fd_idx = sd_varlink_push_dup_fd(vl, cgroup_fd); if (cgroup_fd_idx < 0) return log_debug_errno(userns_fd_idx, "Failed to push cgroup fd into varlink connection: %m"); sd_json_variant *reply = NULL; - r = varlink_callbo( + r = sd_varlink_callbo( vl, "io.systemd.NamespaceResource.AddControlGroupToUserNamespace", &reply, @@ -244,7 +245,7 @@ int nsresource_add_cgroup(int userns_fd, int cgroup_fd) { return 0; } if (error_id) - return log_debug_errno(varlink_error_to_errno(error_id, reply), "Failed to add cgroup to user namespace: %s", error_id); + return log_debug_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to add cgroup to user namespace: %s", error_id); return 1; } @@ -257,7 +258,7 @@ int nsresource_add_netif( char **ret_namespace_ifname) { _cleanup_close_ int _userns_fd = -EBADF, _netns_fd = -EBADF; - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r, userns_fd_idx, netns_fd_idx; const char *error_id; @@ -277,24 +278,24 @@ int nsresource_add_netif( netns_fd = _netns_fd; } - r = varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); + r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource"); if (r < 0) return log_debug_errno(r, "Failed to connect to namespace resource manager: %m"); - r = varlink_set_allow_fd_passing_output(vl, true); + r = sd_varlink_set_allow_fd_passing_output(vl, true); if (r < 0) return log_debug_errno(r, "Failed to enable varlink fd passing for write: %m"); - userns_fd_idx = varlink_push_dup_fd(vl, userns_fd); + userns_fd_idx = sd_varlink_push_dup_fd(vl, userns_fd); if (userns_fd_idx < 0) return log_debug_errno(userns_fd_idx, "Failed to push userns fd into varlink connection: %m"); - netns_fd_idx = varlink_push_dup_fd(vl, netns_fd); + netns_fd_idx = sd_varlink_push_dup_fd(vl, netns_fd); if (netns_fd_idx < 0) return log_debug_errno(netns_fd_idx, "Failed to push netns fd into varlink connection: %m"); sd_json_variant *reply = NULL; - r = varlink_callbo( + r = sd_varlink_callbo( vl, "io.systemd.NamespaceResource.AddNetworkToUserNamespace", &reply, @@ -310,7 +311,7 @@ int nsresource_add_netif( return 0; } if (error_id) - return log_debug_errno(varlink_error_to_errno(error_id, reply), "Failed to add network to user namespace: %s", error_id); + return log_debug_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to add network to user namespace: %s", error_id); _cleanup_free_ char *host_interface_name = NULL, *namespace_interface_name = NULL; r = sd_json_dispatch( diff --git a/src/shared/userdb.c b/src/shared/userdb.c index 2eff470ec9..c893876eaf 100644 --- a/src/shared/userdb.c +++ b/src/shared/userdb.c @@ -2,6 +2,8 @@ #include <sys/auxv.h> +#include "sd-varlink.h" + #include "conf-files.h" #include "dirent-util.h" #include "dlfcn-util.h" @@ -18,9 +20,8 @@ #include "user-util.h" #include "userdb-dropin.h" #include "userdb.h" -#include "varlink.h" -DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(link_hash_ops, void, trivial_hash_func, trivial_compare_func, Varlink, varlink_unref); +DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(link_hash_ops, void, trivial_hash_func, trivial_compare_func, sd_varlink, sd_varlink_unref); typedef enum LookupWhat { LOOKUP_USER, @@ -158,10 +159,10 @@ static void membership_data_done(struct membership_data *d) { } static int userdb_on_query_reply( - Varlink *link, + sd_varlink *link, sd_json_variant *parameters, const char *error_id, - VarlinkReplyFlags flags, + sd_varlink_reply_flags_t flags, void *userdata) { UserDBIterator *iterator = ASSERT_PTR(userdata); @@ -178,7 +179,7 @@ static int userdb_on_query_reply( r = -EHOSTDOWN; else if (streq(error_id, "io.systemd.UserDatabase.EnumerationNotSupported")) r = -EOPNOTSUPP; - else if (streq(error_id, VARLINK_ERROR_TIMEOUT)) + else if (streq(error_id, SD_VARLINK_ERROR_TIMEOUT)) r = -ETIMEDOUT; else r = -EIO; @@ -237,7 +238,7 @@ static int userdb_on_query_reply( iterator->n_found++; /* More stuff coming? then let's just exit cleanly here */ - if (FLAGS_SET(flags, VARLINK_REPLY_CONTINUES)) + if (FLAGS_SET(flags, SD_VARLINK_REPLY_CONTINUES)) return 0; /* Otherwise, let's remove this link and exit cleanly then */ @@ -291,7 +292,7 @@ static int userdb_on_query_reply( iterator->found_group = TAKE_PTR(g); iterator->n_found++; - if (FLAGS_SET(flags, VARLINK_REPLY_CONTINUES)) + if (FLAGS_SET(flags, SD_VARLINK_REPLY_CONTINUES)) return 0; r = 0; @@ -318,7 +319,7 @@ static int userdb_on_query_reply( iterator->found_group_name = TAKE_PTR(membership_data.group_name); iterator->n_found++; - if (FLAGS_SET(flags, VARLINK_REPLY_CONTINUES)) + if (FLAGS_SET(flags, SD_VARLINK_REPLY_CONTINUES)) return 0; r = 0; @@ -336,7 +337,7 @@ finish: iterator->error = -r; assert_se(set_remove(iterator->links, link) == link); - link = varlink_unref(link); + link = sd_varlink_unref(link); return 0; } @@ -347,18 +348,18 @@ static int userdb_connect( bool more, sd_json_variant *query) { - _cleanup_(varlink_unrefp) Varlink *vl = NULL; + _cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL; int r; assert(iterator); assert(path); assert(method); - r = varlink_connect_address(&vl, path); + r = sd_varlink_connect_address(&vl, path); if (r < 0) return log_debug_errno(r, "Unable to connect to %s: %m", path); - varlink_set_userdata(vl, iterator); + sd_varlink_set_userdata(vl, iterator); if (!iterator->event) { r = sd_event_new(&iterator->event); @@ -366,20 +367,20 @@ static int userdb_connect( return log_debug_errno(r, "Unable to allocate event loop: %m"); } - r = varlink_attach_event(vl, iterator->event, SD_EVENT_PRIORITY_NORMAL); + r = sd_varlink_attach_event(vl, iterator->event, SD_EVENT_PRIORITY_NORMAL); if (r < 0) return log_debug_errno(r, "Failed to attach varlink connection to event loop: %m"); - (void) varlink_set_description(vl, path); + (void) sd_varlink_set_description(vl, path); - r = varlink_bind_reply(vl, userdb_on_query_reply); + r = sd_varlink_bind_reply(vl, userdb_on_query_reply); if (r < 0) return log_debug_errno(r, "Failed to bind reply callback: %m"); if (more) - r = varlink_observe(vl, method, query); + r = sd_varlink_observe(vl, method, query); else - r = varlink_invoke(vl, method, query); + r = sd_varlink_invoke(vl, method, query); if (r < 0) return log_debug_errno(r, "Failed to invoke varlink method: %m"); diff --git a/src/shared/varlink-idl.c b/src/shared/varlink-idl.c deleted file mode 100644 index e6a4942ad8..0000000000 --- a/src/shared/varlink-idl.c +++ /dev/null @@ -1,1923 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include "json-util.h" -#include "memstream-util.h" -#include "set.h" -#include "strv.h" -#include "terminal-util.h" -#include "utf8.h" -#include "varlink-idl.h" - -#define DEPTH_MAX 64U - -enum { - COLOR_SYMBOL_TYPE, /* interface, method, type, error */ - COLOR_FIELD_TYPE, /* string, bool, … */ - COLOR_IDENTIFIER, - COLOR_MARKS, /* [], ->, ?, … */ - COLOR_RESET, - COLOR_COMMENT, - _COLOR_MAX, -}; - -#define varlink_idl_log(error, format, ...) log_debug_errno(error, "Varlink-IDL: " format, ##__VA_ARGS__) -#define varlink_idl_log_full(level, error, format, ...) log_full_errno(level, error, "Varlink-IDL: " format, ##__VA_ARGS__) - -static int varlink_idl_format_all_fields(FILE *f, const VarlinkSymbol *symbol, VarlinkFieldDirection direction, const char *indent, const char *const colors[static _COLOR_MAX], size_t cols); - -static int varlink_idl_format_comment( - FILE *f, - const char *text, - const char *indent, - const char *const colors[static _COLOR_MAX], - size_t cols) { - - int r; - - assert(f); - assert(colors); - - if (!text) { - /* If text is NULL, output an empty but commented line */ - fputs(strempty(indent), f); - fputs(colors[COLOR_COMMENT], f); - fputs("#", f); - fputs(colors[COLOR_RESET], f); - fputs("\n", f); - return 0; - } - - _cleanup_strv_free_ char **l = NULL; - r = strv_split_full(&l, text, NEWLINE, EXTRACT_RELAX); - if (r < 0) - return log_error_errno(r, "Failed to split comment string: %m"); - - size_t indent_width = utf8_console_width(indent); - size_t max_width = indent_width < cols ? cols - indent_width : 0; - if (max_width < 10) - max_width = 10; - - _cleanup_strv_free_ char **broken = NULL; - r = strv_rebreak_lines(l, max_width, &broken); - if (r < 0) - return log_error_errno(r, "Failed to rebreak lines in comment: %m"); - - STRV_FOREACH(i, broken) { - fputs(strempty(indent), f); - fputs(colors[COLOR_COMMENT], f); - fputs("# ", f); - fputs(*i, f); - fputs(colors[COLOR_RESET], f); - fputs("\n", f); - } - - return 0; -} - -static int varlink_idl_format_comment_fields( - FILE *f, - const VarlinkField *start, - size_t n, - const char *indent, - const char *const colors[static _COLOR_MAX], - size_t cols) { - - int r; - - if (n == 0) - return 0; - - assert(start); - - for (const VarlinkField *c = start; n > 0; c++, n--) { - r = varlink_idl_format_comment(f, ASSERT_PTR(c->name), indent, colors, cols); - if (r < 0) - return r; - } - - return 0; -} - -static const VarlinkField *varlink_idl_symbol_find_start_comment( - const VarlinkSymbol *symbol, - const VarlinkField *field) { - - assert(symbol); - assert(field); - assert(field >= symbol->fields); - - const VarlinkField *start = NULL; - - for (const VarlinkField *c1 = field; c1 > symbol->fields; c1--) { - const VarlinkField *c0 = c1 - 1; - - if (c0->field_type != _VARLINK_FIELD_COMMENT) - break; - - start = c0; - } - - return start; -} - -static int varlink_idl_format_enum_values( - FILE *f, - const VarlinkSymbol *symbol, - const char *indent, - const char *const colors[static _COLOR_MAX], - size_t cols) { - - _cleanup_free_ char *indent2 = NULL; - bool first = true; - int r; - - assert(f); - assert(symbol); - assert(symbol->symbol_type == VARLINK_ENUM_TYPE); - - indent2 = strjoin(strempty(indent), "\t"); - if (!indent2) - return -ENOMEM; - - for (const VarlinkField *field = symbol->fields; field->field_type != _VARLINK_FIELD_TYPE_END_MARKER; field++) { - - if (field->field_type == _VARLINK_FIELD_COMMENT) /* skip comments at first */ - continue; - - if (first) { - first = false; - fputs("(\n", f); - } else - fputs(",\n", f); - - /* We found an enum value we want to output. In this case, start by outputting all - * immediately preceding comments. For that find the first comment in the series before the - * enum value, so that we can start printing from there. */ - const VarlinkField *start_comment = varlink_idl_symbol_find_start_comment(symbol, field); - - if (start_comment) { - r = varlink_idl_format_comment_fields(f, start_comment, field - start_comment, indent2, colors, cols); - if (r < 0) - return r; - } - - fputs(indent2, f); - fputs(colors[COLOR_IDENTIFIER], f); - fputs(field->name, f); - fputs(colors[COLOR_RESET], f); - } - - if (first) - fputs("()", f); - else { - fputs("\n", f); - fputs(strempty(indent), f); - fputs(")", f); - } - - return 0; -} - -static int varlink_idl_format_field( - FILE *f, - const VarlinkField *field, - const char *indent, - const char *const colors[static _COLOR_MAX], - size_t cols) { - - assert(f); - assert(field); - assert(field->field_type != _VARLINK_FIELD_COMMENT); - - fputs(strempty(indent), f); - fputs(colors[COLOR_IDENTIFIER], f); - fputs(field->name, f); - fputs(colors[COLOR_RESET], f); - fputs(": ", f); - - if (FLAGS_SET(field->field_flags, VARLINK_NULLABLE)) { - fputs(colors[COLOR_MARKS], f); - fputs("?", f); - fputs(colors[COLOR_RESET], f); - } - - switch (field->field_flags & (VARLINK_MAP|VARLINK_ARRAY)) { - - case VARLINK_MAP: - fputs(colors[COLOR_MARKS], f); - fputs("[", f); - fputs(colors[COLOR_FIELD_TYPE], f); - fputs("string", f); - fputs(colors[COLOR_MARKS], f); - fputs("]", f); - fputs(colors[COLOR_RESET], f); - break; - - case VARLINK_ARRAY: - fputs(colors[COLOR_MARKS], f); - fputs("[]", f); - fputs(colors[COLOR_RESET], f); - break; - - case 0: - break; - - default: - assert_not_reached(); - } - - switch (field->field_type) { - - case VARLINK_BOOL: - fputs(colors[COLOR_FIELD_TYPE], f); - fputs("bool", f); - fputs(colors[COLOR_RESET], f); - break; - - case VARLINK_INT: - fputs(colors[COLOR_FIELD_TYPE], f); - fputs("int", f); - fputs(colors[COLOR_RESET], f); - break; - - case VARLINK_FLOAT: - fputs(colors[COLOR_FIELD_TYPE], f); - fputs("float", f); - fputs(colors[COLOR_RESET], f); - break; - - case VARLINK_STRING: - fputs(colors[COLOR_FIELD_TYPE], f); - fputs("string", f); - fputs(colors[COLOR_RESET], f); - break; - - case VARLINK_OBJECT: - fputs(colors[COLOR_FIELD_TYPE], f); - fputs("object", f); - fputs(colors[COLOR_RESET], f); - break; - - case VARLINK_NAMED_TYPE: - fputs(colors[COLOR_IDENTIFIER], f); - fputs(ASSERT_PTR(field->named_type), f); - fputs(colors[COLOR_RESET], f); - break; - - case VARLINK_STRUCT: - return varlink_idl_format_all_fields(f, ASSERT_PTR(field->symbol), VARLINK_REGULAR, indent, colors, cols); - - case VARLINK_ENUM: - return varlink_idl_format_enum_values(f, ASSERT_PTR(field->symbol), indent, colors, cols); - - default: - assert_not_reached(); - } - - return 0; -} - -static int varlink_idl_format_all_fields( - FILE *f, - const VarlinkSymbol *symbol, - VarlinkFieldDirection filter_direction, - const char *indent, - const char *const colors[static _COLOR_MAX], - size_t cols) { - - _cleanup_free_ char *indent2 = NULL; - bool first = true; - int r; - - assert(f); - assert(symbol); - assert(IN_SET(symbol->symbol_type, VARLINK_STRUCT_TYPE, VARLINK_METHOD, VARLINK_ERROR)); - - indent2 = strjoin(strempty(indent), "\t"); - if (!indent2) - return -ENOMEM; - - for (const VarlinkField *field = symbol->fields; field->field_type != _VARLINK_FIELD_TYPE_END_MARKER; field++) { - - if (field->field_type == _VARLINK_FIELD_COMMENT) /* skip comments at first */ - continue; - - if (field->field_direction != filter_direction) - continue; - - if (first) { - first = false; - fputs("(\n", f); - } else - fputs(",\n", f); - - /* We found a field we want to output. In this case, start by outputting all immediately - * preceding comments. For that find the first comment in the series before the field, so - * that we can start printing from there. */ - const VarlinkField *start_comment = varlink_idl_symbol_find_start_comment(symbol, field); - - if (start_comment) { - r = varlink_idl_format_comment_fields(f, start_comment, field - start_comment, indent2, colors, cols); - if (r < 0) - return r; - } - - r = varlink_idl_format_field(f, field, indent2, colors, cols); - if (r < 0) - return r; - } - - if (first) - fputs("()", f); - else { - fputs("\n", f); - fputs(strempty(indent), f); - fputs(")", f); - } - - return 0; -} - -static int varlink_idl_format_symbol( - FILE *f, - const VarlinkSymbol *symbol, - const char *const colors[static _COLOR_MAX], - size_t cols) { - int r; - - assert(f); - assert(symbol); - - switch (symbol->symbol_type) { - - case VARLINK_ENUM_TYPE: - fputs(colors[COLOR_SYMBOL_TYPE], f); - fputs("type ", f); - fputs(colors[COLOR_IDENTIFIER], f); - fputs(symbol->name, f); - fputs(colors[COLOR_RESET], f); - - r = varlink_idl_format_enum_values(f, symbol, /* indent= */ NULL, colors, cols); - break; - - case VARLINK_STRUCT_TYPE: - fputs(colors[COLOR_SYMBOL_TYPE], f); - fputs("type ", f); - fputs(colors[COLOR_IDENTIFIER], f); - fputs(symbol->name, f); - fputs(colors[COLOR_RESET], f); - - r = varlink_idl_format_all_fields(f, symbol, VARLINK_REGULAR, /* indent= */ NULL, colors, cols); - break; - - case VARLINK_METHOD: - fputs(colors[COLOR_SYMBOL_TYPE], f); - fputs("method ", f); - fputs(colors[COLOR_IDENTIFIER], f); - fputs(symbol->name, f); - fputs(colors[COLOR_RESET], f); - - r = varlink_idl_format_all_fields(f, symbol, VARLINK_INPUT, /* indent= */ NULL, colors, cols); - if (r < 0) - return r; - - fputs(colors[COLOR_MARKS], f); - fputs(" -> ", f); - fputs(colors[COLOR_RESET], f); - - r = varlink_idl_format_all_fields(f, symbol, VARLINK_OUTPUT, /* indent= */ NULL, colors, cols); - break; - - case VARLINK_ERROR: - fputs(colors[COLOR_SYMBOL_TYPE], f); - fputs("error ", f); - fputs(colors[COLOR_IDENTIFIER], f); - fputs(symbol->name, f); - fputs(colors[COLOR_RESET], f); - - r = varlink_idl_format_all_fields(f, symbol, VARLINK_REGULAR, /* indent= */ NULL, colors, cols); - break; - - default: - assert_not_reached(); - } - if (r < 0) - return r; - - fputs("\n", f); - return 0; -} - -static int varlink_idl_format_all_symbols( - FILE *f, - const VarlinkInterface *interface, - VarlinkSymbolType filter_type, - const char *const colors[static _COLOR_MAX], - size_t cols) { - - int r; - - assert(f); - assert(interface); - - for (const VarlinkSymbol *const*symbol = interface->symbols; *symbol; symbol++) { - - if ((*symbol)->symbol_type != filter_type) - continue; - - if ((*symbol)->symbol_type == _VARLINK_INTERFACE_COMMENT) { - /* Interface comments we'll output directly. */ - r = varlink_idl_format_comment(f, ASSERT_PTR((*symbol)->name), /* indent= */ NULL, colors, cols); - if (r < 0) - return r; - - continue; - } - - fputs("\n", f); - - /* Symbol comments we'll only output if we are outputting the symbol they belong to. Scan - * backwards for symbol comments. */ - const VarlinkSymbol *const*start_comment = NULL; - for (const VarlinkSymbol *const*c1 = symbol; c1 > interface->symbols; c1--) { - const VarlinkSymbol *const *c0 = c1 - 1; - - if ((*c0)->symbol_type != _VARLINK_SYMBOL_COMMENT) - break; - - start_comment = c0; - } - - /* Found one or more comments, output them now */ - if (start_comment) - for (const VarlinkSymbol *const*c = start_comment; c < symbol; c++) { - r = varlink_idl_format_comment(f, ASSERT_PTR((*c)->name), /* indent= */ NULL, colors, cols); - if (r < 0) - return r; - } - - r = varlink_idl_format_symbol(f, *symbol, colors, cols); - if (r < 0) - return r; - } - - return 0; -} - -int varlink_idl_dump(FILE *f, int use_colors, size_t cols, const VarlinkInterface *interface) { - static const char* const color_table[_COLOR_MAX] = { - [COLOR_SYMBOL_TYPE] = ANSI_HIGHLIGHT_GREEN, - [COLOR_FIELD_TYPE] = ANSI_HIGHLIGHT_BLUE, - [COLOR_IDENTIFIER] = ANSI_NORMAL, - [COLOR_MARKS] = ANSI_HIGHLIGHT_MAGENTA, - [COLOR_RESET] = ANSI_NORMAL, - [COLOR_COMMENT] = ANSI_GREY, - }; - - static const char* const color_off[_COLOR_MAX] = { - "", "", "", "", "", "", - }; - - int r; - - assert(interface); - - if (!f) - f = stdout; - - if (use_colors < 0) - use_colors = colors_enabled(); - - const char *const *colors = use_colors ? color_table : color_off; - - /* First output interface comments */ - r = varlink_idl_format_all_symbols(f, interface, _VARLINK_INTERFACE_COMMENT, colors, cols); - if (r < 0) - return r; - - fputs(colors[COLOR_SYMBOL_TYPE], f); - fputs("interface ", f); - fputs(colors[COLOR_IDENTIFIER], f); - fputs(ASSERT_PTR(interface->name), f); - fputs(colors[COLOR_RESET], f); - fputs("\n", f); - - /* Then output all symbols, ordered by symbol type */ - for (VarlinkSymbolType t = 0; t < _VARLINK_SYMBOL_TYPE_MAX; t++) { - - /* Interface comments we already have output above. Symbol comments are output when the - * symbol they belong to are output, hence filter both here. */ - if (IN_SET(t, _VARLINK_SYMBOL_COMMENT, _VARLINK_INTERFACE_COMMENT)) - continue; - - r = varlink_idl_format_all_symbols(f, interface, t, colors, cols); - if (r < 0) - return r; - } - - return 0; -} - -int varlink_idl_format_full(const VarlinkInterface *interface, size_t cols, char **ret) { - _cleanup_(memstream_done) MemStream memstream = {}; - int r; - - if (!memstream_init(&memstream)) - return -errno; - - r = varlink_idl_dump(memstream.f, /* use_colors= */ false, cols, interface); - if (r < 0) - return r; - - return memstream_finalize(&memstream, ret, NULL); -} - -static VarlinkSymbol *varlink_symbol_free(VarlinkSymbol *symbol) { - if (!symbol) - return NULL; - - /* See comment in varlink_interface_free() regarding the casting away of `const` */ - - free((char*) symbol->name); - - for (size_t i = 0; symbol->fields[i].field_type != _VARLINK_FIELD_TYPE_END_MARKER; i++) { - VarlinkField *field = symbol->fields + i; - - free((void*) field->name); - free((void*) field->named_type); - - /* The symbol pointer might either point to a named symbol, in which case that symbol is - * owned by the interface, or by an anomyous symbol, in which case it is owned by us, and we - * need to free it */ - if (field->symbol && field->field_type != VARLINK_NAMED_TYPE) - varlink_symbol_free((VarlinkSymbol*) field->symbol); - } - - return mfree(symbol); -} - -VarlinkInterface* varlink_interface_free(VarlinkInterface *interface) { - if (!interface) - return NULL; - - /* So here's the thing: in most cases we want that users of this define their interface descriptions - * in C code, and hence the definitions are constant and immutable during the lifecycle of the - * system. Because of that we define all structs with const* pointers. It makes it very nice and - * straight-forward to populate these structs with literal C strings. However, in some not so common - * cases we also want to allocate these structures dynamically on the heap, when parsing interface - * descriptions. But given this should be the exceptional and not the common case, we decided to - * simple cast away the 'const' where needed, even if it is ugly. */ - - free((char*) interface->name); - - for (size_t i = 0; interface->symbols[i]; i++) - varlink_symbol_free((VarlinkSymbol*) interface->symbols[i]); - - return mfree(interface); -} - -DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkSymbol*, varlink_symbol_free); - -static int varlink_interface_realloc(VarlinkInterface **interface, size_t n_symbols) { - VarlinkInterface *n; - - assert(interface); - - n_symbols++; /* Space for trailing NULL end marker symbol */ - - /* Overflow check */ - if (n_symbols > (SIZE_MAX - offsetof(VarlinkInterface, symbols)) / sizeof(VarlinkSymbol*)) - return -ENOMEM; - - n = realloc0(*interface, offsetof(VarlinkInterface, symbols) + sizeof(VarlinkSymbol*) * n_symbols); - if (!n) - return -ENOMEM; - - *interface = n; - return 0; -} - -static int varlink_symbol_realloc(VarlinkSymbol **symbol, size_t n_fields) { - VarlinkSymbol *n; - - assert(symbol); - - n_fields++; /* Space for trailing end marker field */ - - /* Overflow check */ - if (n_fields > (SIZE_MAX - offsetof(VarlinkSymbol, fields)) / sizeof(VarlinkField)) - return -ENOMEM; - - n = realloc0(*symbol, offsetof(VarlinkSymbol, fields) + sizeof(VarlinkField) * n_fields); - if (!n) - return -ENOMEM; - - *symbol = n; - return 0; -} - -#define VALID_CHARS_IDENTIFIER ALPHANUMERICAL "_" -#define VALID_CHARS_RESERVED LOWERCASE_LETTERS -#define VALID_CHARS_INTERFACE_NAME ALPHANUMERICAL ".-" - -static void advance_line_column(const char *p, size_t n, unsigned *line, unsigned *column) { - - assert(p); - assert(line); - assert(column); - - for (; n > 0; p++, n--) { - - if (*p == '\n') { - (*line)++; - *column = 1; - } else - (*column)++; - } -} - -static size_t token_match( - const char *p, - const char *allowed_delimiters, - const char *allowed_chars) { - - /* Checks if the string p begins either with one of the token characters in allowed_delimiters or - * with a string consisting of allowed_chars. */ - - assert(p); - - if (allowed_delimiters && strchr(allowed_delimiters, *p)) - return 1; - - if (!allowed_chars) - return 0; - - return strspn(p, allowed_chars); -} - -static int varlink_idl_subparse_token( - const char **p, - unsigned *line, - unsigned *column, - const char *allowed_delimiters, - const char *allowed_chars, - char **ret_token) { - - _cleanup_free_ char *t = NULL; - size_t l; - - assert(p); - assert(*p); - assert(line); - assert(column); - assert(ret_token); - - if (**p == '\0') { /* eof */ - *ret_token = NULL; - return 0; - } - - l = token_match(*p, allowed_delimiters, allowed_chars); - - /* No token of the permitted character set found? Then let's try to skip over whitespace and try again */ - if (l == 0) { - size_t ll; - - ll = strspn(*p, WHITESPACE); - advance_line_column(*p, ll, line, column); - *p += ll; - - if (**p == '\0') { /* eof */ - *ret_token = NULL; - return 0; - } - - l = token_match(*p, allowed_delimiters, allowed_chars); - if (l == 0) - return varlink_idl_log( - SYNTHETIC_ERRNO(EBADMSG), - "%u:%u: Couldn't find token of allowed chars '%s' or allowed delimiters '%s'.", - *line, *column, strempty(allowed_chars), strempty(allowed_delimiters)); - } - - t = strndup(*p, l); - if (!t) - return -ENOMEM; - - advance_line_column(*p, l, line, column); - *p += l; - - *ret_token = TAKE_PTR(t); - return 1; -} - -static int varlink_idl_subparse_comment( - const char **p, - unsigned *line, - unsigned *column, - char **ret) { - - _cleanup_free_ char *comment = NULL; - size_t l; - - assert(p); - assert(*p); - assert(line); - assert(column); - - l = strcspn(*p, NEWLINE); - - if (!utf8_is_valid_n(*p, l)) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Comment is not valid UTF-8.", *line, *column); - - if (ret) { - /* Remove a single space as prefix of a comment, if one is specified. This is because we - * generally expect comments to be formatted as "# foobar" rather than "#foobar", and will - * ourselves format them that way. We accept the comments without the space too however. We - * will not strip more than one space, to allow indented comment blocks. */ - - if (**p == ' ') - comment = strndup(*p + 1, l - 1); - else - comment = strndup(*p, l); - if (!comment) - return -ENOMEM; - } - - advance_line_column(*p, l + 1, line, column); - *p += l; - - if (ret) - *ret = TAKE_PTR(comment); - - return 1; -} - -static int varlink_idl_subparse_whitespace( - const char **p, - unsigned *line, - unsigned *column) { - - size_t l; - - assert(p); - assert(*p); - assert(line); - assert(column); - - l = strspn(*p, WHITESPACE); - advance_line_column(*p, l, line, column); - *p += l; - - return 1; -} - -static int varlink_idl_subparse_struct_or_enum(const char **p, unsigned *line, unsigned *column, VarlinkSymbol **symbol, size_t *n_fields, VarlinkFieldDirection direction, unsigned depth); - -static int varlink_idl_subparse_field_type( - const char **p, - unsigned *line, - unsigned *column, - VarlinkField *field, - unsigned depth) { - - size_t l; - int r; - - assert(p); - assert(*p); - assert(line); - assert(field); - - r = varlink_idl_subparse_whitespace(p, line, column); - if (r < 0) - return r; - - if (startswith(*p, "?")) { - field->field_flags |= VARLINK_NULLABLE; - l = 1; - } else { - field->field_flags &= ~VARLINK_NULLABLE; - l = 0; - } - - advance_line_column(*p, l, line, column); - *p += l; - - if (startswith(*p, "[]")) { - l = 2; - field->field_flags = (field->field_flags & ~VARLINK_MAP) | VARLINK_ARRAY; - } else if (startswith(*p, "[string]")) { - l = 8; - field->field_flags = (field->field_flags & ~VARLINK_ARRAY) | VARLINK_MAP; - } else { - l = 0; - field->field_flags = field->field_flags & ~(VARLINK_MAP | VARLINK_ARRAY); - } - - advance_line_column(*p, l, line, column); - *p += l; - - if (startswith(*p, "bool")) { - l = 4; - field->field_type = VARLINK_BOOL; - } else if (startswith(*p, "int")) { - l = 3; - field->field_type = VARLINK_INT; - } else if (startswith(*p, "float")) { - l = 5; - field->field_type = VARLINK_FLOAT; - } else if (startswith(*p, "string")) { - l = 6; - field->field_type = VARLINK_STRING; - } else if (startswith(*p, "object")) { - l = 6; - field->field_type = VARLINK_OBJECT; - } else if (**p == '(') { - _cleanup_(varlink_symbol_freep) VarlinkSymbol *symbol = NULL; - size_t n_fields = 0; - - r = varlink_symbol_realloc(&symbol, n_fields); - if (r < 0) - return r; - - symbol->symbol_type = _VARLINK_SYMBOL_TYPE_INVALID; - - r = varlink_idl_subparse_struct_or_enum( - p, - line, - column, - &symbol, - &n_fields, - VARLINK_REGULAR, - depth + 1); - if (r < 0) - return r; - - if (symbol->symbol_type == VARLINK_STRUCT_TYPE) - field->field_type = VARLINK_STRUCT; - else { - assert(symbol->symbol_type == VARLINK_ENUM_TYPE); - field->field_type = VARLINK_ENUM; - } - - field->symbol = TAKE_PTR(symbol); - l = 0; - } else { - _cleanup_free_ char *token = NULL; - - r = varlink_idl_subparse_token(p, line, column, /* valid_tokens= */ NULL, VALID_CHARS_IDENTIFIER, &token); - if (r < 0) - return r; - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - - field->named_type = TAKE_PTR(token); - field->field_type = VARLINK_NAMED_TYPE; - l = 0; - } - - advance_line_column(*p, l, line, column); - *p += l; - - return 0; -} - -static int varlink_idl_subparse_struct_or_enum( - const char **p, - unsigned *line, - unsigned *column, - VarlinkSymbol **symbol, - size_t *n_fields, - VarlinkFieldDirection direction, - unsigned depth) { - - enum { - STATE_OPEN, - STATE_NAME, - STATE_COLON, - STATE_COMMA, - STATE_DONE, - } state = STATE_OPEN; - _cleanup_free_ char *field_name = NULL; - const char *allowed_delimiters = "(", *allowed_chars = NULL; - int r; - - assert(p); - assert(*p); - assert(line); - assert(column); - assert(symbol); - assert(*symbol); - assert(n_fields); - - if (depth > DEPTH_MAX) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Maximum nesting depth reached (%u).", *line, *column, DEPTH_MAX); - - while (state != STATE_DONE) { - _cleanup_free_ char *token = NULL; - - r = varlink_idl_subparse_token( - p, - line, - column, - allowed_delimiters, - allowed_chars, - &token); - if (r < 0) - return r; - - switch (state) { - - case STATE_OPEN: - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - if (!streq(token, "(")) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Unexpected token '%s'.", *line, *column, token); - - state = STATE_NAME; - allowed_delimiters = ")#"; - allowed_chars = VALID_CHARS_IDENTIFIER; - break; - - case STATE_NAME: - assert(!field_name); - - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - else if (streq(token, "#")) { - _cleanup_free_ char *comment = NULL; - - r = varlink_idl_subparse_comment(p, line, column, &comment); - if (r < 0) - return r; - - r = varlink_symbol_realloc(symbol, *n_fields + 1); - if (r < 0) - return r; - - VarlinkField *field = (*symbol)->fields + (*n_fields)++; - *field = (VarlinkField) { - .name = TAKE_PTR(comment), - .field_type = _VARLINK_FIELD_COMMENT, - }; - } else if (streq(token, ")")) - state = STATE_DONE; - else { - field_name = TAKE_PTR(token); - state = STATE_COLON; - allowed_delimiters = ":,)"; - allowed_chars = NULL; - } - - break; - - case STATE_COLON: - assert(field_name); - - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - - if (streq(token, ":")) { - VarlinkField *field; - - if ((*symbol)->symbol_type < 0) - (*symbol)->symbol_type = VARLINK_STRUCT_TYPE; - if ((*symbol)->symbol_type == VARLINK_ENUM_TYPE) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Enum with struct fields, refusing.", *line, *column); - - r = varlink_symbol_realloc(symbol, *n_fields + 1); - if (r < 0) - return r; - - field = (*symbol)->fields + (*n_fields)++; - *field = (VarlinkField) { - .name = TAKE_PTR(field_name), - .field_type = _VARLINK_FIELD_TYPE_INVALID, - .field_direction = direction, - }; - - r = varlink_idl_subparse_field_type(p, line, column, field, depth); - if (r < 0) - return r; - - state = STATE_COMMA; - allowed_delimiters = ",)"; - allowed_chars = NULL; - - } else if (STR_IN_SET(token, ",", ")")) { - VarlinkField *field; - - if ((*symbol)->symbol_type < 0) - (*symbol)->symbol_type = VARLINK_ENUM_TYPE; - if ((*symbol)->symbol_type != VARLINK_ENUM_TYPE) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Struct with enum fields, refusing.", *line, *column); - - r = varlink_symbol_realloc(symbol, *n_fields + 1); - if (r < 0) - return r; - - field = (*symbol)->fields + (*n_fields)++; - *field = (VarlinkField) { - .name = TAKE_PTR(field_name), - .field_type = VARLINK_ENUM_VALUE, - }; - - if (streq(token, ",")) { - state = STATE_NAME; - allowed_delimiters = "#"; - allowed_chars = VALID_CHARS_IDENTIFIER; - } else { - assert(streq(token, ")")); - state = STATE_DONE; - } - } else - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Unexpected token '%s'.", *line, *column, token); - - break; - - case STATE_COMMA: - assert(!field_name); - - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - if (streq(token, ",")) { - state = STATE_NAME; - allowed_delimiters = "#"; - allowed_chars = VALID_CHARS_IDENTIFIER; - } else if (streq(token, ")")) - state = STATE_DONE; - else - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Unexpected token '%s'.", *line, *column, token); - break; - - default: - assert_not_reached(); - } - } - - /* If we don't know the type of the symbol by now it was an empty () which doesn't allow us to - * determine if we look at an enum or a struct */ - if ((*symbol)->symbol_type < 0) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Ambiguous empty () enum/struct is not permitted.", *line, *column); - - return 0; -} - -static int varlink_idl_resolve_symbol_types(VarlinkInterface *interface, VarlinkSymbol *symbol) { - assert(interface); - assert(symbol); - - for (VarlinkField *field = symbol->fields; field->field_type != _VARLINK_FIELD_TYPE_END_MARKER; field++) { - const VarlinkSymbol *found; - - if (field->field_type != VARLINK_NAMED_TYPE) - continue; - - if (field->symbol) /* Already resolved */ - continue; - - if (!field->named_type) - return varlink_idl_log(SYNTHETIC_ERRNO(ENETUNREACH), "Named type field lacking a type name."); - - found = varlink_idl_find_symbol(interface, _VARLINK_SYMBOL_TYPE_INVALID, field->named_type); - if (!found) - return varlink_idl_log(SYNTHETIC_ERRNO(ENETUNREACH), "Failed to find type '%s'.", field->named_type); - - if (!IN_SET(found->symbol_type, VARLINK_STRUCT_TYPE, VARLINK_ENUM_TYPE)) - return varlink_idl_log(SYNTHETIC_ERRNO(ENETUNREACH), "Symbol '%s' is referenced as type but is not a type.", field->named_type); - - field->symbol = found; - } - - return 0; -} - -static int varlink_idl_resolve_types(VarlinkInterface *interface) { - int r; - - assert(interface); - - for (VarlinkSymbol **symbol = (VarlinkSymbol**) interface->symbols; *symbol; symbol++) { - r = varlink_idl_resolve_symbol_types(interface, *symbol); - if (r < 0) - return r; - } - - return 0; -} - -int varlink_idl_parse( - const char *text, - unsigned *line, - unsigned *column, - VarlinkInterface **ret) { - - _cleanup_(varlink_interface_freep) VarlinkInterface *interface = NULL; - _cleanup_(varlink_symbol_freep) VarlinkSymbol *symbol = NULL; - enum { - STATE_PRE_INTERFACE, - STATE_INTERFACE, - STATE_PRE_SYMBOL, - STATE_METHOD, - STATE_METHOD_NAME, - STATE_METHOD_ARROW, - STATE_TYPE, - STATE_TYPE_NAME, - STATE_ERROR, - STATE_ERROR_NAME, - STATE_DONE, - } state = STATE_PRE_INTERFACE; - const char *allowed_delimiters = "#", *allowed_chars = VALID_CHARS_RESERVED; - size_t n_symbols = 0, n_fields = 1; - unsigned _line = 0, _column = 1; - const char **p = &text; - int r; - - if (!line) - line = &_line; - if (!column) - column = &_column; - - while (state != STATE_DONE) { - _cleanup_free_ char *token = NULL; - - r = varlink_idl_subparse_token( - p, - line, - column, - allowed_delimiters, - allowed_chars, - &token); - if (r < 0) - return r; - - switch (state) { - - case STATE_PRE_INTERFACE: - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - if (streq(token, "#")) { - _cleanup_free_ char *comment = NULL; - - r = varlink_idl_subparse_comment(&text, line, column, &comment); - if (r < 0) - return r; - - r = varlink_interface_realloc(&interface, n_symbols + 1); - if (r < 0) - return r; - - r = varlink_symbol_realloc(&symbol, 0); - if (r < 0) - return r; - - symbol->symbol_type = _VARLINK_INTERFACE_COMMENT; - symbol->name = TAKE_PTR(comment); - - interface->symbols[n_symbols++] = TAKE_PTR(symbol); - } else if (streq(token, "interface")) { - state = STATE_INTERFACE; - allowed_delimiters = NULL; - allowed_chars = VALID_CHARS_INTERFACE_NAME; - } else - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Unexpected token '%s'.", *line, *column, token); - break; - - case STATE_INTERFACE: - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - - r = varlink_interface_realloc(&interface, n_symbols); - if (r < 0) - return r; - - assert(!interface->name); - interface->name = TAKE_PTR(token); - - state = STATE_PRE_SYMBOL; - allowed_delimiters = "#"; - allowed_chars = VALID_CHARS_RESERVED; - break; - - case STATE_PRE_SYMBOL: - if (!token) { - state = STATE_DONE; - break; - } - - if (streq(token, "#")) { - _cleanup_free_ char *comment = NULL; - - r = varlink_idl_subparse_comment(&text, line, column, &comment); - if (r < 0) - return r; - - r = varlink_interface_realloc(&interface, n_symbols + 1); - if (r < 0) - return r; - - assert(!symbol); - r = varlink_symbol_realloc(&symbol, 0); - if (r < 0) - return r; - - symbol->symbol_type = _VARLINK_SYMBOL_COMMENT; - symbol->name = TAKE_PTR(comment); - - interface->symbols[n_symbols++] = TAKE_PTR(symbol); - } else if (streq(token, "method")) { - state = STATE_METHOD; - allowed_chars = VALID_CHARS_IDENTIFIER; - } else if (streq(token, "type")) { - state = STATE_TYPE; - allowed_chars = VALID_CHARS_IDENTIFIER; - } else if (streq(token, "error")) { - state = STATE_ERROR; - allowed_chars = VALID_CHARS_IDENTIFIER; - } else - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Unexpected token '%s'.", *line, *column, token); - - break; - - case STATE_METHOD: - assert(!symbol); - n_fields = 0; - - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - - r = varlink_symbol_realloc(&symbol, n_fields); - if (r < 0) - return r; - - symbol->symbol_type = VARLINK_METHOD; - symbol->name = TAKE_PTR(token); - - r = varlink_idl_subparse_struct_or_enum(&text, line, column, &symbol, &n_fields, VARLINK_INPUT, 0); - if (r < 0) - return r; - - state = STATE_METHOD_ARROW; - allowed_chars = "->"; - break; - - case STATE_METHOD_ARROW: - assert(symbol); - - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - - if (!streq(token, "->")) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Unexpected token '%s'.", *line, *column, token); - - r = varlink_idl_subparse_struct_or_enum(&text, line, column, &symbol, &n_fields, VARLINK_OUTPUT, 0); - if (r < 0) - return r; - - r = varlink_interface_realloc(&interface, n_symbols + 1); - if (r < 0) - return r; - - interface->symbols[n_symbols++] = TAKE_PTR(symbol); - - state = STATE_PRE_SYMBOL; - allowed_chars = VALID_CHARS_RESERVED "#"; - break; - - case STATE_TYPE: - assert(!symbol); - n_fields = 0; - - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - - r = varlink_symbol_realloc(&symbol, n_fields); - if (r < 0) - return r; - - symbol->symbol_type = _VARLINK_SYMBOL_TYPE_INVALID; /* don't know yet if enum or struct, will be field in by varlink_idl_subparse_struct_or_enum() */ - symbol->name = TAKE_PTR(token); - - r = varlink_idl_subparse_struct_or_enum(&text, line, column, &symbol, &n_fields, VARLINK_REGULAR, 0); - if (r < 0) - return r; - - r = varlink_interface_realloc(&interface, n_symbols + 1); - if (r < 0) - return r; - - interface->symbols[n_symbols++] = TAKE_PTR(symbol); - - state = STATE_PRE_SYMBOL; - allowed_chars = VALID_CHARS_RESERVED "#"; - break; - - case STATE_ERROR: - assert(!symbol); - n_fields = 0; - - if (!token) - return varlink_idl_log(SYNTHETIC_ERRNO(EBADMSG), "%u:%u: Premature EOF.", *line, *column); - - r = varlink_symbol_realloc(&symbol, n_fields); - if (r < 0) - return r; - - symbol->symbol_type = VARLINK_ERROR; - symbol->name = TAKE_PTR(token); - - r = varlink_idl_subparse_struct_or_enum(&text, line, column, &symbol, &n_fields, VARLINK_REGULAR, 0); - if (r < 0) - return r; - - r = varlink_interface_realloc(&interface, n_symbols + 1); - if (r < 0) - return r; - - interface->symbols[n_symbols++] = TAKE_PTR(symbol); - - state = STATE_PRE_SYMBOL; - allowed_chars = VALID_CHARS_RESERVED "#"; - break; - - default: - assert_not_reached(); - } - } - - r = varlink_idl_resolve_types(interface); - if (r < 0) - return r; - - *ret = TAKE_PTR(interface); - return 0; -} - -bool varlink_idl_field_name_is_valid(const char *name) { - if (isempty(name)) - return false; - - /* Field names may start with lower or uppercase char, but no numerals or underscore */ - if (!strchr(LETTERS, name[0])) - return false; - - /* Otherwise fields may be alphanumerical or underscore, but no two underscore may immediately follow - * each other or be trailing */ - bool underscore = false; - for (const char *c = name + 1; *c; c++) { - if (*c == '_') { - if (underscore) - return false; - - underscore = true; - continue; - } - - if (!strchr(ALPHANUMERICAL, *c)) - return false; - - underscore = false; - } - - if (underscore) - return false; - - return true; -} - -bool varlink_idl_symbol_name_is_valid(const char *name) { - if (isempty(name)) - return false; - - /* We might want to reference VARLINK_STRUCT_TYPE and VARLINK_ENUM_TYPE symbols where we also - * reference native types, hence make sure the native type names are refused as symbol names. */ - if (STR_IN_SET(name, "bool", "int", "float", "string", "object")) - return false; - - /* Symbols must be named with an uppercase letter as first character */ - if (!strchr(UPPERCASE_LETTERS, name[0])) - return false; - - for (const char *c = name + 1; *c; c++) - if (!strchr(ALPHANUMERICAL, *c)) - return false; - - return true; -} - -bool varlink_idl_interface_name_is_valid(const char *name) { - if (isempty(name)) - return false; - - /* Interface names must start with a letter, uppercase or lower case, but nothing else */ - if (!strchr(LETTERS, name[0])) - return false; - - /* Otherwise it may be a series of non-empty dot separated labels, which are alphanumerical and may - * contain single dashes in the middle */ - bool dot = false, dash = false; - for (const char *c = name + 1; *c; c++) { - switch (*c) { - - case '.': - if (dot || dash) - return false; - - dot = true; - break; - - case '-': - if (dot || dash) - return false; - - dash = true; - break; - - default: - if (!strchr(ALPHANUMERICAL, *c)) - return false; - - dot = dash = false; - } - } - - if (dot || dash) - return false; - - return true; -} - -static bool varlink_idl_comment_is_valid(const char *comment) { - return utf8_is_valid(comment); -} - -int varlink_idl_qualified_symbol_name_is_valid(const char *name) { - const char *dot; - - /* Validates a qualified symbol name (i.e. interface name, followed by a dot, followed by a symbol name) */ - - if (!name) - return false; - - dot = strrchr(name, '.'); - if (!dot) - return false; - - if (!varlink_idl_symbol_name_is_valid(dot + 1)) - return false; - - _cleanup_free_ char *iface = strndup(name, dot - name); - if (!iface) - return -ENOMEM; - - return varlink_idl_interface_name_is_valid(iface); -} - -static int varlink_idl_symbol_consistent(const VarlinkInterface *interface, const VarlinkSymbol *symbol, int level); - -static int varlink_idl_field_consistent( - const VarlinkInterface *interface, - const VarlinkSymbol *symbol, - const VarlinkField *field, - int level) { - - const char *symbol_name; - int r; - - assert(interface); - assert(symbol); - assert(field); - assert(field->name); - - symbol_name = symbol->name ?: "<anonymous>"; - - if (field->field_type <= 0 || field->field_type >= _VARLINK_FIELD_TYPE_MAX) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Field type for '%s' in symbol '%s' is not valid, refusing.", field->name, symbol_name); - - if (field->field_type == VARLINK_ENUM_VALUE) { - - if (symbol->symbol_type != VARLINK_ENUM_TYPE) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Enum field type for '%s' in non-enum symbol '%s', refusing.", field->name, symbol_name); - - if (field->field_flags != 0) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Enum field '%s' in symbol '%s' has non-zero flags set, refusing.", field->name, symbol_name); - } else { - if (symbol->symbol_type == VARLINK_ENUM_TYPE) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Non-enum field type for '%s' in enum symbol '%s', refusing.", field->name, symbol_name); - - if (!IN_SET(field->field_flags & ~VARLINK_NULLABLE, 0, VARLINK_ARRAY, VARLINK_MAP)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Flags of field '%s' in symbol '%s' is invalid, refusing.", field->name, symbol_name); - } - - if (symbol->symbol_type != VARLINK_METHOD) { - if (field->field_direction != VARLINK_REGULAR) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Direction of '%s' in non-method symbol '%s' not regular, refusing.", field->name, symbol_name); - } else { - if (!IN_SET(field->field_direction, VARLINK_INPUT, VARLINK_OUTPUT)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Direction of '%s' in method symbol '%s' is not input or output, refusing.", field->name, symbol_name); - } - - if (field->symbol) { - if (!IN_SET(field->field_type, VARLINK_STRUCT, VARLINK_ENUM, VARLINK_NAMED_TYPE)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Target symbol for field '%s' in symbol '%s' defined for elemental field, refusing.", field->name, symbol_name); - - if (field->field_type == VARLINK_NAMED_TYPE) { - const VarlinkSymbol *found; - - if (!field->symbol->name || !field->named_type || !streq(field->symbol->name, field->named_type)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Resolved symbol name and named type of field '%s' in symbol '%s' do not match, refusing.", field->name, symbol_name); - - /* If this is a named type, then check if it's properly part of the interface */ - found = varlink_idl_find_symbol(interface, _VARLINK_SYMBOL_TYPE_INVALID, field->symbol->name); - if (!found) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Resolved symbol of named type of field '%s' in symbol '%s' is not part of the interface, refusing.", field->name, symbol_name); - - if (!IN_SET(found->symbol_type, VARLINK_ENUM_TYPE, VARLINK_STRUCT_TYPE)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Resolved symbol of named type of field '%s' in symbol '%s' is not a type, refusing.", field->name, symbol_name); - } else { - /* If this is an anonymous type, then we recursively check if it's consistent, since - * it's not part of the interface, and hence we won't validate it from there. */ - - r = varlink_idl_symbol_consistent(interface, field->symbol, level); - if (r < 0) - return r; - } - - } else { - if (IN_SET(field->field_type, VARLINK_STRUCT, VARLINK_ENUM, VARLINK_NAMED_TYPE)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "No target symbol for field '%s' in symbol '%s' defined for elemental field, refusing.", field->name, symbol_name); - - if (field->named_type) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Unresolved symbol in field '%s' in symbol '%s', refusing.", field->name, symbol_name); - } - - if (field->named_type) { - if (field->field_type != VARLINK_NAMED_TYPE) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Named type set for field '%s' in symbol '%s' but not a named type field, refusing.", field->name, symbol_name); - } else { - if (field->field_type == VARLINK_NAMED_TYPE) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "No named type set for field '%s' in symbol '%s' but field is a named type field, refusing.", field->name, symbol_name); - } - - return 0; -} - -static bool varlink_symbol_is_empty(const VarlinkSymbol *symbol) { - assert(symbol); - - if (IN_SET(symbol->symbol_type, _VARLINK_SYMBOL_COMMENT, _VARLINK_INTERFACE_COMMENT)) - return true; - - return symbol->fields[0].field_type == _VARLINK_FIELD_TYPE_END_MARKER; -} - -static int varlink_idl_symbol_consistent( - const VarlinkInterface *interface, - const VarlinkSymbol *symbol, - int level) { - - _cleanup_(set_freep) Set *input_set = NULL, *output_set = NULL; - const char *symbol_name; - int r; - - assert(interface); - assert(symbol); - - symbol_name = symbol->name ?: "<anonymous>"; - - if (symbol->symbol_type < 0 || symbol->symbol_type >= _VARLINK_SYMBOL_TYPE_MAX) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Symbol type for '%s' is not valid, refusing.", symbol_name); - - if (IN_SET(symbol->symbol_type, VARLINK_STRUCT_TYPE, VARLINK_ENUM_TYPE) && varlink_symbol_is_empty(symbol)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Symbol '%s' is empty, refusing.", symbol_name); - - if (IN_SET(symbol->symbol_type, _VARLINK_SYMBOL_COMMENT, _VARLINK_INTERFACE_COMMENT)) - return 0; - - for (const VarlinkField *field = symbol->fields; field->field_type != _VARLINK_FIELD_TYPE_END_MARKER; field++) { - - if (field->field_type == _VARLINK_FIELD_COMMENT) { - if (!varlink_idl_comment_is_valid(field->name)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Comment in symbol '%s' not valid, refusing.", symbol_name); - - continue; - } - - Set **name_set = field->field_direction == VARLINK_OUTPUT ? &output_set : &input_set; /* for the method case we need two separate sets, otherwise we use the same */ - - if (!varlink_idl_field_name_is_valid(field->name)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Field name '%s' in symbol '%s' not valid, refusing.", field->name, symbol_name); - - if (set_contains(*name_set, field->name)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(ENOTUNIQ), "Field '%s' defined twice in symbol '%s', refusing.", field->name, symbol_name); - - if (set_ensure_put(name_set, &string_hash_ops, field->name) < 0) - return log_oom(); - - r = varlink_idl_field_consistent(interface, symbol, field, level); - if (r < 0) - return r; - } - - return 0; -} - -int varlink_idl_consistent(const VarlinkInterface *interface, int level) { - _cleanup_(set_freep) Set *name_set = NULL; - int r; - - assert(interface); - - if (!varlink_idl_interface_name_is_valid(interface->name)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Interface name '%s' is not valid, refusing.", interface->name); - - for (const VarlinkSymbol *const *symbol = interface->symbols; *symbol; symbol++) { - - if (IN_SET((*symbol)->symbol_type, _VARLINK_SYMBOL_COMMENT, _VARLINK_INTERFACE_COMMENT)) { - if (!varlink_idl_comment_is_valid((*symbol)->name)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Comment in interface '%s' not valid, refusing.", interface->name); - continue; - } - - if (!varlink_idl_symbol_name_is_valid((*symbol)->name)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(EUCLEAN), "Symbol name '%s' is not valid, refusing.", strempty((*symbol)->name)); - - if (set_contains(name_set, (*symbol)->name)) - return varlink_idl_log_full(level, SYNTHETIC_ERRNO(ENOTUNIQ), "Symbol '%s' defined twice in interface, refusing.", (*symbol)->name); - - if (set_ensure_put(&name_set, &string_hash_ops, (*symbol)->name) < 0) - return log_oom(); - - r = varlink_idl_symbol_consistent(interface, *symbol, level); - if (r < 0) - return r; - } - - return 0; -} - -static int varlink_idl_validate_symbol(const VarlinkSymbol *symbol, sd_json_variant *v, VarlinkFieldDirection direction, const char **bad_field); - -static int varlink_idl_validate_field_element_type(const VarlinkField *field, sd_json_variant *v) { - assert(field); - - switch (field->field_type) { - - case VARLINK_STRUCT: - case VARLINK_ENUM: - case VARLINK_NAMED_TYPE: - return varlink_idl_validate_symbol(field->symbol, v, VARLINK_REGULAR, NULL); - - case VARLINK_BOOL: - if (!sd_json_variant_is_boolean(v)) - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Field '%s' should be a bool, but it is not, refusing.", strna(field->name)); - - break; - - case VARLINK_INT: - /* Allow strings here too, since integers with > 53 bits are often passed in as strings */ - if (!sd_json_variant_is_integer(v) && !sd_json_variant_is_unsigned(v) && !sd_json_variant_is_string(v)) - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Field '%s' should be an int, but it is not, refusing.", strna(field->name)); - - break; - - case VARLINK_FLOAT: - if (!sd_json_variant_is_number(v)) - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Field '%s' should be a float, but it is not, refusing.", strna(field->name)); - - break; - - case VARLINK_STRING: - if (!sd_json_variant_is_string(v)) - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Field '%s' should be a string, but it is not, refusing.", strna(field->name)); - - break; - - case VARLINK_OBJECT: - if (!sd_json_variant_is_object(v)) - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Field '%s' should be an object, but it is not, refusing.", strna(field->name)); - - break; - - case _VARLINK_FIELD_COMMENT: - break; - - default: - assert_not_reached(); - } - - return 0; -} - -static int varlink_idl_validate_field(const VarlinkField *field, sd_json_variant *v) { - int r; - - assert(field); - assert(field->field_type != _VARLINK_FIELD_COMMENT); - - if (!v || sd_json_variant_is_null(v)) { - - if (!FLAGS_SET(field->field_flags, VARLINK_NULLABLE)) - return varlink_idl_log(SYNTHETIC_ERRNO(ENOANO), "Mandatory field '%s' is null or missing on object, refusing.", strna(field->name)); - - } else if (FLAGS_SET(field->field_flags, VARLINK_ARRAY)) { - sd_json_variant *i; - - if (!sd_json_variant_is_array(v)) - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Field '%s' should be an array, but it is not, refusing.", strna(field->name)); - - JSON_VARIANT_ARRAY_FOREACH(i, v) { - r = varlink_idl_validate_field_element_type(field, i); - if (r < 0) - return r; - } - - } else if (FLAGS_SET(field->field_flags, VARLINK_MAP)) { - _unused_ const char *k; - sd_json_variant *e; - - if (!sd_json_variant_is_object(v)) - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Field '%s' should be an object, but it is not, refusing.", strna(field->name)); - - JSON_VARIANT_OBJECT_FOREACH(k, e, v) { - r = varlink_idl_validate_field_element_type(field, e); - if (r < 0) - return r; - } - } else { - r = varlink_idl_validate_field_element_type(field, v); - if (r < 0) - return r; - } - - return 0; -} - -static int varlink_idl_validate_symbol(const VarlinkSymbol *symbol, sd_json_variant *v, VarlinkFieldDirection direction, const char **bad_field) { - int r; - - assert(symbol); - assert(!IN_SET(symbol->symbol_type, _VARLINK_SYMBOL_COMMENT, _VARLINK_INTERFACE_COMMENT)); - - if (!v) { - if (bad_field) - *bad_field = NULL; - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Null object passed, refusing."); - } - - switch (symbol->symbol_type) { - - case VARLINK_ENUM_TYPE: { - bool found = false; - const char *s; - - if (!sd_json_variant_is_string(v)) { - if (bad_field) - *bad_field = symbol->name; - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Passed non-string to enum field '%s', refusing.", strna(symbol->name)); - } - - assert_se(s = sd_json_variant_string(v)); - - for (const VarlinkField *field = symbol->fields; field->field_type != _VARLINK_FIELD_TYPE_END_MARKER; field++) { - - if (field->field_type == _VARLINK_FIELD_COMMENT) - continue; - - assert(field->field_type == VARLINK_ENUM_VALUE); - - if (streq_ptr(field->name, s)) { - found = true; - break; - } - } - - if (!found) { - if (bad_field) - *bad_field = s; - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Passed unrecognized string '%s' to enum field '%s', refusing.", s, strna(symbol->name)); - } - - break; - } - - case VARLINK_STRUCT_TYPE: - case VARLINK_METHOD: - case VARLINK_ERROR: { - if (!sd_json_variant_is_object(v)) { - if (bad_field) - *bad_field = symbol->name; - return varlink_idl_log(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Passed non-object to field '%s', refusing.", strna(symbol->name)); - } - - for (const VarlinkField *field = symbol->fields; field->field_type != _VARLINK_FIELD_TYPE_END_MARKER; field++) { - - if (field->field_type == _VARLINK_FIELD_COMMENT) - continue; - - if (field->field_direction != direction) - continue; - - r = varlink_idl_validate_field(field, sd_json_variant_by_key(v, field->name)); - if (r < 0) { - if (bad_field) - *bad_field = field->name; - return r; - } - } - - _unused_ sd_json_variant *e; - const char *name; - JSON_VARIANT_OBJECT_FOREACH(name, e, v) { - if (!varlink_idl_find_field(symbol, name)) { - if (bad_field) - *bad_field = name; - return varlink_idl_log(SYNTHETIC_ERRNO(EBUSY), "Field '%s' not defined for object, refusing.", name); - } - } - - break; - } - - case _VARLINK_SYMBOL_COMMENT: - case _VARLINK_INTERFACE_COMMENT: - break; - - default: - assert_not_reached(); - } - - return 1; /* validated */ -} - -static int varlink_idl_validate_method(const VarlinkSymbol *method, sd_json_variant *v, VarlinkFieldDirection direction, const char **bad_field) { - assert(IN_SET(direction, VARLINK_INPUT, VARLINK_OUTPUT)); - - if (!method) - return 0; /* Can't validate */ - if (method->symbol_type != VARLINK_METHOD) - return -EBADMSG; - - return varlink_idl_validate_symbol(method, v, direction, bad_field); -} - -int varlink_idl_validate_method_call(const VarlinkSymbol *method, sd_json_variant *v, const char **bad_field) { - return varlink_idl_validate_method(method, v, VARLINK_INPUT, bad_field); -} - -int varlink_idl_validate_method_reply(const VarlinkSymbol *method, sd_json_variant *v, const char **bad_field) { - return varlink_idl_validate_method(method, v, VARLINK_OUTPUT, bad_field); -} - -int varlink_idl_validate_error(const VarlinkSymbol *error, sd_json_variant *v, const char **bad_field) { - if (!error) - return 0; /* Can't validate */ - if (error->symbol_type != VARLINK_ERROR) - return -EBADMSG; - - return varlink_idl_validate_symbol(error, v, VARLINK_REGULAR, bad_field); -} - -const VarlinkSymbol* varlink_idl_find_symbol( - const VarlinkInterface *interface, - VarlinkSymbolType type, - const char *name) { - - assert(interface); - assert(type < _VARLINK_SYMBOL_TYPE_MAX); - assert(!IN_SET(type, _VARLINK_SYMBOL_COMMENT, _VARLINK_INTERFACE_COMMENT)); - - if (isempty(name)) - return NULL; - - for (const VarlinkSymbol *const*symbol = interface->symbols; *symbol; symbol++) { - if (type >= 0 && (*symbol)->symbol_type != type) - continue; - - if (streq_ptr((*symbol)->name, name)) - return *symbol; - } - - return NULL; -} - -const VarlinkField* varlink_idl_find_field( - const VarlinkSymbol *symbol, - const char *name) { - - assert(symbol); - - if (isempty(name)) - return NULL; - - for (const VarlinkField *field = symbol->fields; field->field_type != _VARLINK_FIELD_TYPE_END_MARKER; field++) { - if (field->field_type == _VARLINK_FIELD_COMMENT) - continue; - - if (streq_ptr(field->name, name)) - return field; - } - - return NULL; -} diff --git a/src/shared/varlink-idl.h b/src/shared/varlink-idl.h deleted file mode 100644 index ffb55f3066..0000000000 --- a/src/shared/varlink-idl.h +++ /dev/null @@ -1,182 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> - -#include "sd-json.h" -#include "macro.h" - -/* This implements the Varlink Interface Definition Language ("Varlink IDL"), - * i.e. https://varlink.org/Interface-Definition - * - * Primarily allows encoding static interface definitions in C code, that can be converted to the textual IDL - * format on-the-fly. Can also parse the textual format back to C structures. Validates the interface - * definitions for internal consistency and validates JSON objects against the interface definitions. */ - -typedef enum VarlinkSymbolType { - VARLINK_ENUM_TYPE, - VARLINK_STRUCT_TYPE, - VARLINK_METHOD, - VARLINK_ERROR, - _VARLINK_INTERFACE_COMMENT, /* Not really a symbol, just a comment about the interface */ - _VARLINK_SYMBOL_COMMENT, /* Not really a symbol, just a comment about a symbol */ - _VARLINK_SYMBOL_TYPE_MAX, - _VARLINK_SYMBOL_TYPE_INVALID = -EINVAL, -} VarlinkSymbolType; - -typedef enum VarlinkFieldType { - _VARLINK_FIELD_TYPE_END_MARKER = 0, /* zero type means: this is the last entry in the fields[] array of VarlinkSymbol */ - VARLINK_STRUCT, - VARLINK_ENUM, - VARLINK_NAMED_TYPE, - VARLINK_BOOL, - VARLINK_INT, - VARLINK_FLOAT, - VARLINK_STRING, - VARLINK_OBJECT, - VARLINK_ENUM_VALUE, - _VARLINK_FIELD_COMMENT, /* Not really a field, just a comment about a field*/ - _VARLINK_FIELD_TYPE_MAX, - _VARLINK_FIELD_TYPE_INVALID = -EINVAL, -} VarlinkFieldType; - -typedef enum VarlinkFieldDirection { - VARLINK_REGULAR, - VARLINK_INPUT, - VARLINK_OUTPUT, - _VARLINK_FIELD_DIRECTION_MAX, - _VARLINK_FIELD_DIRECTION_INVALID = -EINVAL, -} VarlinkFieldDirection; - -typedef enum VarlinkFieldFlags { - VARLINK_ARRAY = 1 << 0, - VARLINK_MAP = 1 << 1, - VARLINK_NULLABLE = 1 << 2, - _VARLINK_FIELD_FLAGS_MAX = (1 << 3) - 1, - _VARLINK_FIELD_FLAGS_INVALID = -EINVAL, -} VarlinkFieldFlags; - -typedef struct VarlinkField VarlinkField; -typedef struct VarlinkSymbol VarlinkSymbol; -typedef struct VarlinkInterface VarlinkInterface; - -/* Fields are the components making up symbols */ -struct VarlinkField { - const char *name; - VarlinkFieldType field_type; - VarlinkFieldFlags field_flags; - VarlinkFieldDirection field_direction; /* in case of method call fields: whether input or output argument */ - const VarlinkSymbol *symbol; /* VARLINK_STRUCT, VARLINK_ENUM: anonymous symbol that carries the definitions, VARLINK_NAMED_TYPE: resolved symbol */ - const char *named_type; /* VARLINK_NAMED_TYPE */ -}; - -/* Symbols are primary named concepts in an interface, and are methods, errors or named types (either enum or struct). */ -struct VarlinkSymbol { - const char *name; /* most symbols have a name, but sometimes they are created on-the-fly for fields, in which case they are anonymous */ - VarlinkSymbolType symbol_type; - VarlinkField fields[]; -}; - -/* An interface definition has a name and consist of symbols */ -struct VarlinkInterface { - const char *name; - const VarlinkSymbol *symbols[]; -}; - -#define VARLINK_DEFINE_FIELD(_name, _field_type, _field_flags) \ - { .name = #_name, .field_type = (_field_type), .field_flags = (_field_flags) } - -#define VARLINK_DEFINE_FIELD_BY_TYPE(_name, _named_type, _field_flags) \ - { .name = #_name, .field_type = VARLINK_NAMED_TYPE, .named_type = #_named_type, .symbol = &vl_type_ ## _named_type, .field_flags = (_field_flags) } - -#define VARLINK_DEFINE_INPUT(_name, _field_type, _field_flags) \ - { .name = #_name, .field_type = (_field_type), .field_flags = (_field_flags), .field_direction = VARLINK_INPUT } - -#define VARLINK_DEFINE_INPUT_BY_TYPE(_name, _named_type, _field_flags) \ - { .name = #_name, .field_type = VARLINK_NAMED_TYPE, .named_type = #_named_type, .symbol = &vl_type_ ## _named_type, .field_flags = (_field_flags), .field_direction = VARLINK_INPUT } - -#define VARLINK_DEFINE_OUTPUT(_name, _field_type, _field_flags) \ - { .name = #_name, .field_type = (_field_type), .field_flags = (_field_flags), .field_direction = VARLINK_OUTPUT } - -#define VARLINK_DEFINE_OUTPUT_BY_TYPE(_name, _named_type, _field_flags) \ - { .name = #_name, .field_type = VARLINK_NAMED_TYPE, .named_type = #_named_type, .symbol = &vl_type_ ## _named_type, .field_flags = (_field_flags), .field_direction = VARLINK_OUTPUT } - -#define VARLINK_DEFINE_ENUM_VALUE(_name) \ - { .name = #_name, .field_type = VARLINK_ENUM_VALUE } - -#define VARLINK_FIELD_COMMENT(text) \ - { .name = "" text, .field_type = _VARLINK_FIELD_COMMENT } - -#define VARLINK_DEFINE_METHOD(_name, ...) \ - const VarlinkSymbol vl_method_ ## _name = { \ - .name = #_name, \ - .symbol_type = VARLINK_METHOD, \ - .fields = { __VA_ARGS__ __VA_OPT__(,) {}}, \ - } - -#define VARLINK_DEFINE_ERROR(_name, ...) \ - const VarlinkSymbol vl_error_ ## _name = { \ - .name = #_name, \ - .symbol_type = VARLINK_ERROR, \ - .fields = { __VA_ARGS__ __VA_OPT__(,) {}}, \ - } - -#define VARLINK_DEFINE_STRUCT_TYPE(_name, ...) \ - const VarlinkSymbol vl_type_ ## _name = { \ - .name = #_name, \ - .symbol_type = VARLINK_STRUCT_TYPE, \ - .fields = { __VA_ARGS__ __VA_OPT__(,) {}}, \ - } - -#define VARLINK_DEFINE_ENUM_TYPE(_name, ...) \ - const VarlinkSymbol vl_type_ ## _name = { \ - .name = #_name, \ - .symbol_type = VARLINK_ENUM_TYPE, \ - .fields = { __VA_ARGS__ __VA_OPT__(,) {}}, \ - } - -#define VARLINK_DEFINE_INTERFACE(_name, _full_name, ...) \ - const VarlinkInterface vl_interface_ ## _name = { \ - .name = (_full_name), \ - .symbols = { __VA_ARGS__ __VA_OPT__(,) NULL}, \ - } - -#define VARLINK_SYMBOL_COMMENT(text) \ - &(const VarlinkSymbol) { \ - .name = "" text, \ - .symbol_type = _VARLINK_SYMBOL_COMMENT, \ - } - -#define VARLINK_INTERFACE_COMMENT(text) \ - &(const VarlinkSymbol) { \ - .name = "" text, \ - .symbol_type = _VARLINK_INTERFACE_COMMENT, \ - } - -int varlink_idl_dump(FILE *f, int use_colors, size_t cols, const VarlinkInterface *interface); -int varlink_idl_format_full(const VarlinkInterface *interface, size_t cols, char **ret); - -static inline int varlink_idl_format(const VarlinkInterface *interface, char **ret) { - return varlink_idl_format_full(interface, SIZE_MAX, ret); -} - -int varlink_idl_parse(const char *text, unsigned *ret_line, unsigned *ret_column, VarlinkInterface **ret); -VarlinkInterface* varlink_interface_free(VarlinkInterface *interface); -DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkInterface*, varlink_interface_free); - -bool varlink_idl_field_name_is_valid(const char *name); -bool varlink_idl_symbol_name_is_valid(const char *name); -bool varlink_idl_interface_name_is_valid(const char *name); - -int varlink_idl_qualified_symbol_name_is_valid(const char *name); - -int varlink_idl_consistent(const VarlinkInterface *interface, int level); - -const VarlinkSymbol* varlink_idl_find_symbol(const VarlinkInterface *interface, VarlinkSymbolType type, const char *name); -const VarlinkField* varlink_idl_find_field(const VarlinkSymbol *symbol, const char *name); - -int varlink_idl_validate_method_call(const VarlinkSymbol *method, sd_json_variant *v, const char **bad_field); -int varlink_idl_validate_method_reply(const VarlinkSymbol *method, sd_json_variant *v, const char **bad_field); -int varlink_idl_validate_error(const VarlinkSymbol *error, sd_json_variant *v, const char **bad_field); diff --git a/src/shared/varlink-internal.h b/src/shared/varlink-internal.h deleted file mode 100644 index 715202a49e..0000000000 --- a/src/shared/varlink-internal.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include <stdio.h> - -#include "fdset.h" -#include "varlink.h" - -int varlink_server_serialize(VarlinkServer *s, FILE *f, FDSet *fds); -int varlink_server_deserialize_one(VarlinkServer *s, const char *value, FDSet *fds); diff --git a/src/shared/varlink-io.systemd.BootControl.c b/src/shared/varlink-io.systemd.BootControl.c index 110d4b7be7..449cc98bb4 100644 --- a/src/shared/varlink-io.systemd.BootControl.c +++ b/src/shared/varlink-io.systemd.BootControl.c @@ -2,83 +2,83 @@ #include "varlink-io.systemd.BootControl.h" -static VARLINK_DEFINE_ENUM_TYPE( +static SD_VARLINK_DEFINE_ENUM_TYPE( BootEntryType, - VARLINK_FIELD_COMMENT("Boot Loader Specification Type #1 entries (.conf files)"), - VARLINK_DEFINE_ENUM_VALUE(type1), - VARLINK_FIELD_COMMENT("Boot Loader Specification Type #2 entries (UKIs)"), - VARLINK_DEFINE_ENUM_VALUE(type2), - VARLINK_FIELD_COMMENT("Additional entries reported by boot loader"), - VARLINK_DEFINE_ENUM_VALUE(loader), - VARLINK_FIELD_COMMENT("Automatically generated entries"), - VARLINK_DEFINE_ENUM_VALUE(auto)); + SD_VARLINK_FIELD_COMMENT("Boot Loader Specification Type #1 entries (.conf files)"), + SD_VARLINK_DEFINE_ENUM_VALUE(type1), + SD_VARLINK_FIELD_COMMENT("Boot Loader Specification Type #2 entries (UKIs)"), + SD_VARLINK_DEFINE_ENUM_VALUE(type2), + SD_VARLINK_FIELD_COMMENT("Additional entries reported by boot loader"), + SD_VARLINK_DEFINE_ENUM_VALUE(loader), + SD_VARLINK_FIELD_COMMENT("Automatically generated entries"), + SD_VARLINK_DEFINE_ENUM_VALUE(auto)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( BootEntry, - VARLINK_DEFINE_FIELD_BY_TYPE(type, BootEntryType, 0), - VARLINK_FIELD_COMMENT("The string identifier of the entry"), - VARLINK_DEFINE_FIELD(id, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(path, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(root, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(title, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(showTitle, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(sortKey, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(version, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(machineId, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(architecture, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(options, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(linux, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(efi, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(initrd, VARLINK_STRING, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_FIELD(devicetree, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(devicetreeOverlay, VARLINK_STRING, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_FIELD_COMMENT("Indicates whether the boot loader reported this entry on the current boot"), - VARLINK_DEFINE_FIELD(isReported, VARLINK_BOOL, 0), - VARLINK_FIELD_COMMENT("Indicates the number of tries left for this boot entry before it is assumed to be not working."), - VARLINK_DEFINE_FIELD(triesLeft, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Indicates the number of unsuccessful tries already made for this boot entry."), - VARLINK_DEFINE_FIELD(triesDone, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Indicates whether this entry is the default entry."), - VARLINK_DEFINE_FIELD(isDefault, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Indicates whether this entry has been booted."), - VARLINK_DEFINE_FIELD(isSelected, VARLINK_BOOL, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(type, BootEntryType, 0), + SD_VARLINK_FIELD_COMMENT("The string identifier of the entry"), + SD_VARLINK_DEFINE_FIELD(id, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(root, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(title, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(showTitle, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(sortKey, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(version, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(machineId, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(architecture, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(options, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(linux, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(efi, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(initrd, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_FIELD(devicetree, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(devicetreeOverlay, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_FIELD_COMMENT("Indicates whether the boot loader reported this entry on the current boot"), + SD_VARLINK_DEFINE_FIELD(isReported, SD_VARLINK_BOOL, 0), + SD_VARLINK_FIELD_COMMENT("Indicates the number of tries left for this boot entry before it is assumed to be not working."), + SD_VARLINK_DEFINE_FIELD(triesLeft, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Indicates the number of unsuccessful tries already made for this boot entry."), + SD_VARLINK_DEFINE_FIELD(triesDone, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Indicates whether this entry is the default entry."), + SD_VARLINK_DEFINE_FIELD(isDefault, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Indicates whether this entry has been booted."), + SD_VARLINK_DEFINE_FIELD(isSelected, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( ListBootEntries, - VARLINK_FIELD_COMMENT("A boot menu entry structure"), - VARLINK_DEFINE_OUTPUT_BY_TYPE(entry, BootEntry, VARLINK_NULLABLE)); + SD_VARLINK_FIELD_COMMENT("A boot menu entry structure"), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(entry, BootEntry, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( SetRebootToFirmware, - VARLINK_FIELD_COMMENT("The new value of the reboot-to-firmware-UI flag"), - VARLINK_DEFINE_INPUT(state, VARLINK_BOOL, 0)); + SD_VARLINK_FIELD_COMMENT("The new value of the reboot-to-firmware-UI flag"), + SD_VARLINK_DEFINE_INPUT(state, SD_VARLINK_BOOL, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( GetRebootToFirmware, - VARLINK_FIELD_COMMENT("The current state of the reboot-to-firmware-UI flag"), - VARLINK_DEFINE_OUTPUT(state, VARLINK_BOOL, 0)); + SD_VARLINK_FIELD_COMMENT("The current state of the reboot-to-firmware-UI flag"), + SD_VARLINK_DEFINE_OUTPUT(state, SD_VARLINK_BOOL, 0)); -static VARLINK_DEFINE_ERROR( +static SD_VARLINK_DEFINE_ERROR( RebootToFirmwareNotSupported); -static VARLINK_DEFINE_ERROR( +static SD_VARLINK_DEFINE_ERROR( NoSuchBootEntry); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_BootControl, "io.systemd.BootControl", - VARLINK_INTERFACE_COMMENT("Boot Loader control APIs"), - VARLINK_SYMBOL_COMMENT("The type of a boot entry"), + SD_VARLINK_INTERFACE_COMMENT("Boot Loader control APIs"), + SD_VARLINK_SYMBOL_COMMENT("The type of a boot entry"), &vl_type_BootEntryType, - VARLINK_SYMBOL_COMMENT("A structure encapsulating a boot entry"), + SD_VARLINK_SYMBOL_COMMENT("A structure encapsulating a boot entry"), &vl_type_BootEntry, - VARLINK_SYMBOL_COMMENT("Enumerates boot entries. Method call must be called with 'more' flag set. Each response returns one entry. If no entries are defined returns the NoSuchBootEntry error."), + SD_VARLINK_SYMBOL_COMMENT("Enumerates boot entries. Method call must be called with 'more' flag set. Each response returns one entry. If no entries are defined returns the NoSuchBootEntry error."), &vl_method_ListBootEntries, - VARLINK_SYMBOL_COMMENT("Sets the reboot-to-firmware-UI flag of the firmware, if this concept exists. Returns the RebootToFirmwareNotSupported error if not."), + SD_VARLINK_SYMBOL_COMMENT("Sets the reboot-to-firmware-UI flag of the firmware, if this concept exists. Returns the RebootToFirmwareNotSupported error if not."), &vl_method_SetRebootToFirmware, - VARLINK_SYMBOL_COMMENT("Gets the current state of the reboot-to-firmware-UI flag of the firmware, if this concept exists. Returns the RebootToFirmwareNotSupported error if not."), + SD_VARLINK_SYMBOL_COMMENT("Gets the current state of the reboot-to-firmware-UI flag of the firmware, if this concept exists. Returns the RebootToFirmwareNotSupported error if not."), &vl_method_GetRebootToFirmware, - VARLINK_SYMBOL_COMMENT("SetRebootToFirmware() and GetRebootToFirmware() return this if the firmware does not actually support the reboot-to-firmware-UI concept."), + SD_VARLINK_SYMBOL_COMMENT("SetRebootToFirmware() and GetRebootToFirmware() return this if the firmware does not actually support the reboot-to-firmware-UI concept."), &vl_error_RebootToFirmwareNotSupported, - VARLINK_SYMBOL_COMMENT("No boot entry defined."), + SD_VARLINK_SYMBOL_COMMENT("No boot entry defined."), &vl_error_NoSuchBootEntry); diff --git a/src/shared/varlink-io.systemd.BootControl.h b/src/shared/varlink-io.systemd.BootControl.h index fa72b703d1..2c1fecf446 100644 --- a/src/shared/varlink-io.systemd.BootControl.h +++ b/src/shared/varlink-io.systemd.BootControl.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_BootControl; +extern const sd_varlink_interface vl_interface_io_systemd_BootControl; diff --git a/src/shared/varlink-io.systemd.Credentials.c b/src/shared/varlink-io.systemd.Credentials.c index aafdfcb410..4c4f222ec5 100644 --- a/src/shared/varlink-io.systemd.Credentials.c +++ b/src/shared/varlink-io.systemd.Credentials.c @@ -2,65 +2,65 @@ #include "varlink-io.systemd.Credentials.h" -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Encrypt, - VARLINK_FIELD_COMMENT("The name for the encrypted credential, a string suitable for inclusion in a file name. If not specified no name is encoded in the credential. Typically, if this credential is stored on disk, this is how the file should be called, and permits authentication of the filename."), - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Plaintext to encrypt. Suitable only for textual data. Either this field or 'data' (below) must be provided."), - VARLINK_DEFINE_INPUT(text, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Plaintext to encrypt, encoded in Base64. Suitable for binary data. Either this field or 'text' (above) must be provided."), - VARLINK_DEFINE_INPUT(data, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Timestamp to store in the credential. In µs since the UNIX epoch, i.e. Jan 1st 1970. If not specified the current time is used."), - VARLINK_DEFINE_INPUT(timestamp, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Timestamp when to the credential should be considered invalid. In µs since the UNIX epoch. If not specified, the credential remains valid forever."), - VARLINK_DEFINE_INPUT(notAfter, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The intended scope for the credential. One of 'system' or 'user'. If not specified defaults to 'system', unless an uid is specified (see below), in which case it default to 'user'."), - VARLINK_DEFINE_INPUT(scope, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The numeric UNIX UID of the user the credential shall be scoped to. Only relevant if 'user' scope is selected (see above). If not specified and 'user' scope is selected defaults to the UID of the calling user, if that can be determined."), - VARLINK_DEFINE_INPUT(uid, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Controls whether interactive authentication (via polkit) shall be allowed. If unspecified defaults to false."), - VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Encrypted credential in Base64 encoding. This can be stored in a credential file, for consumption in LoadEncryptedCredential= and similar calls. Note that the Base64 encoding should be retained when copied into a file."), - VARLINK_DEFINE_OUTPUT(blob, VARLINK_STRING, 0)); + SD_VARLINK_FIELD_COMMENT("The name for the encrypted credential, a string suitable for inclusion in a file name. If not specified no name is encoded in the credential. Typically, if this credential is stored on disk, this is how the file should be called, and permits authentication of the filename."), + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Plaintext to encrypt. Suitable only for textual data. Either this field or 'data' (below) must be provided."), + SD_VARLINK_DEFINE_INPUT(text, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Plaintext to encrypt, encoded in Base64. Suitable for binary data. Either this field or 'text' (above) must be provided."), + SD_VARLINK_DEFINE_INPUT(data, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Timestamp to store in the credential. In µs since the UNIX epoch, i.e. Jan 1st 1970. If not specified the current time is used."), + SD_VARLINK_DEFINE_INPUT(timestamp, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Timestamp when to the credential should be considered invalid. In µs since the UNIX epoch. If not specified, the credential remains valid forever."), + SD_VARLINK_DEFINE_INPUT(notAfter, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The intended scope for the credential. One of 'system' or 'user'. If not specified defaults to 'system', unless an uid is specified (see below), in which case it default to 'user'."), + SD_VARLINK_DEFINE_INPUT(scope, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The numeric UNIX UID of the user the credential shall be scoped to. Only relevant if 'user' scope is selected (see above). If not specified and 'user' scope is selected defaults to the UID of the calling user, if that can be determined."), + SD_VARLINK_DEFINE_INPUT(uid, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Controls whether interactive authentication (via polkit) shall be allowed. If unspecified defaults to false."), + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Encrypted credential in Base64 encoding. This can be stored in a credential file, for consumption in LoadEncryptedCredential= and similar calls. Note that the Base64 encoding should be retained when copied into a file."), + SD_VARLINK_DEFINE_OUTPUT(blob, SD_VARLINK_STRING, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Decrypt, - VARLINK_FIELD_COMMENT("The name of the encrypted credential. Must the same string specified when the credential was encrypted, in order to authenticate this. If not specified authentication of the credential name is not done."), - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The encrypted credential in Base64 encoding. This corresponds of the 'blob' field returned by the 'Encrypt' method."), - VARLINK_DEFINE_INPUT(blob, VARLINK_STRING, 0), - VARLINK_FIELD_COMMENT("The timestamp to use when validating the credential's time validity range. If not specified the current time is used."), - VARLINK_DEFINE_INPUT(timestamp, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The scope for this credential. If not specified no restrictions on the credential scope are made."), - VARLINK_DEFINE_INPUT(scope, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("If the 'user' scope is selected, specifies the numeric UNIX UID of the user the credential is associated with. If not specified this is automatically derived from the UID of the calling user, if that can be determined."), - VARLINK_DEFINE_INPUT(uid, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Controls whether interactive authentication (via polkit) shall be allowed. If unspecified defaults to false."), - VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The decrypted plaintext data in Base64 encoding."), - VARLINK_DEFINE_OUTPUT(data, VARLINK_STRING, 0)); + SD_VARLINK_FIELD_COMMENT("The name of the encrypted credential. Must the same string specified when the credential was encrypted, in order to authenticate this. If not specified authentication of the credential name is not done."), + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The encrypted credential in Base64 encoding. This corresponds of the 'blob' field returned by the 'Encrypt' method."), + SD_VARLINK_DEFINE_INPUT(blob, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("The timestamp to use when validating the credential's time validity range. If not specified the current time is used."), + SD_VARLINK_DEFINE_INPUT(timestamp, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The scope for this credential. If not specified no restrictions on the credential scope are made."), + SD_VARLINK_DEFINE_INPUT(scope, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("If the 'user' scope is selected, specifies the numeric UNIX UID of the user the credential is associated with. If not specified this is automatically derived from the UID of the calling user, if that can be determined."), + SD_VARLINK_DEFINE_INPUT(uid, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Controls whether interactive authentication (via polkit) shall be allowed. If unspecified defaults to false."), + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The decrypted plaintext data in Base64 encoding."), + SD_VARLINK_DEFINE_OUTPUT(data, SD_VARLINK_STRING, 0)); -static VARLINK_DEFINE_ERROR(BadFormat); -static VARLINK_DEFINE_ERROR(NameMismatch); -static VARLINK_DEFINE_ERROR(TimeMismatch); -static VARLINK_DEFINE_ERROR(NoSuchUser); -static VARLINK_DEFINE_ERROR(BadScope); +static SD_VARLINK_DEFINE_ERROR(BadFormat); +static SD_VARLINK_DEFINE_ERROR(NameMismatch); +static SD_VARLINK_DEFINE_ERROR(TimeMismatch); +static SD_VARLINK_DEFINE_ERROR(NoSuchUser); +static SD_VARLINK_DEFINE_ERROR(BadScope); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_Credentials, "io.systemd.Credentials", - VARLINK_INTERFACE_COMMENT("APIs for encrypting and decrypting service credentials."), - VARLINK_SYMBOL_COMMENT("Encrypts some plaintext data, returns an encrypted credential."), + SD_VARLINK_INTERFACE_COMMENT("APIs for encrypting and decrypting service credentials."), + SD_VARLINK_SYMBOL_COMMENT("Encrypts some plaintext data, returns an encrypted credential."), &vl_method_Encrypt, - VARLINK_SYMBOL_COMMENT("Decrypts an encrypted credential, returns plaintext data."), + SD_VARLINK_SYMBOL_COMMENT("Decrypts an encrypted credential, returns plaintext data."), &vl_method_Decrypt, - VARLINK_SYMBOL_COMMENT("Indicates that a corrupt and unsupported encrypted credential was provided."), + SD_VARLINK_SYMBOL_COMMENT("Indicates that a corrupt and unsupported encrypted credential was provided."), &vl_error_BadFormat, - VARLINK_SYMBOL_COMMENT("The specified name does not match the name stored in the credential."), + SD_VARLINK_SYMBOL_COMMENT("The specified name does not match the name stored in the credential."), &vl_error_NameMismatch, - VARLINK_SYMBOL_COMMENT("The credential's is no longer or not yet valid."), + SD_VARLINK_SYMBOL_COMMENT("The credential's is no longer or not yet valid."), &vl_error_TimeMismatch, - VARLINK_SYMBOL_COMMENT("The specified user does not exist."), + SD_VARLINK_SYMBOL_COMMENT("The specified user does not exist."), &vl_error_NoSuchUser, - VARLINK_SYMBOL_COMMENT("The credential does not match the selected scope."), + SD_VARLINK_SYMBOL_COMMENT("The credential does not match the selected scope."), &vl_error_BadScope); diff --git a/src/shared/varlink-io.systemd.Credentials.h b/src/shared/varlink-io.systemd.Credentials.h index c0ecc3d840..4f1842e238 100644 --- a/src/shared/varlink-io.systemd.Credentials.h +++ b/src/shared/varlink-io.systemd.Credentials.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_Credentials; +extern const sd_varlink_interface vl_interface_io_systemd_Credentials; diff --git a/src/shared/varlink-io.systemd.Hostname.c b/src/shared/varlink-io.systemd.Hostname.c index 247bca6da3..a41d7cb85f 100644 --- a/src/shared/varlink-io.systemd.Hostname.c +++ b/src/shared/varlink-io.systemd.Hostname.c @@ -2,39 +2,39 @@ #include "varlink-io.systemd.Credentials.h" -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Describe, - VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(Hostname, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(StaticHostname, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(PrettyHostname, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(DefaultHostname, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(HostnameSource, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(IconName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(Chassis, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(Deployment, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(Location, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(KernelName, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(KernelRelease, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(KernelVersion, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(OperatingSystemPrettyName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(OperatingSystemCPEName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(OperatingSystemHomeURL, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(OperatingSystemSupportEnd, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(OperatingSystemReleaseData, VARLINK_STRING, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT(MachineInformationData, VARLINK_STRING, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT(HardwareVendor, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(HardwareModel, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(HardwareSerial, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(FirmwareVersion, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(FirmwareVendor, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(FirmwareDate, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(MachineID, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(BootID, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(ProductUUID, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(VSockCID, VARLINK_INT, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(Hostname, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(StaticHostname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(PrettyHostname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(DefaultHostname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(HostnameSource, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(IconName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(Chassis, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(Deployment, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(Location, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(KernelName, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(KernelRelease, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(KernelVersion, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(OperatingSystemPrettyName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(OperatingSystemCPEName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(OperatingSystemHomeURL, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(OperatingSystemSupportEnd, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(OperatingSystemReleaseData, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT(MachineInformationData, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT(HardwareVendor, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(HardwareModel, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(HardwareSerial, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(FirmwareVersion, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(FirmwareVendor, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(FirmwareDate, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(MachineID, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(BootID, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(ProductUUID, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(VSockCID, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_Hostname, "io.systemd.Hostname", &vl_method_Describe); diff --git a/src/shared/varlink-io.systemd.Hostname.h b/src/shared/varlink-io.systemd.Hostname.h index 29bb20ef68..e390a7d0c0 100644 --- a/src/shared/varlink-io.systemd.Hostname.h +++ b/src/shared/varlink-io.systemd.Hostname.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_Hostname; +extern const sd_varlink_interface vl_interface_io_systemd_Hostname; diff --git a/src/shared/varlink-io.systemd.Import.c b/src/shared/varlink-io.systemd.Import.c index 4b2f3dcdea..622d571c20 100644 --- a/src/shared/varlink-io.systemd.Import.c +++ b/src/shared/varlink-io.systemd.Import.c @@ -2,128 +2,128 @@ #include "varlink-io.systemd.Import.h" -static VARLINK_DEFINE_ENUM_TYPE( +static SD_VARLINK_DEFINE_ENUM_TYPE( ImageClass, - VARLINK_FIELD_COMMENT("An image to boot as a system on baremetal, in a VM or as a container"), - VARLINK_DEFINE_ENUM_VALUE(machine), - VARLINK_FIELD_COMMENT("An portable service image"), - VARLINK_DEFINE_ENUM_VALUE(portable), - VARLINK_FIELD_COMMENT("A system extension image"), - VARLINK_DEFINE_ENUM_VALUE(sysext), - VARLINK_FIELD_COMMENT("A configuration extension image"), - VARLINK_DEFINE_ENUM_VALUE(confext)); + SD_VARLINK_FIELD_COMMENT("An image to boot as a system on baremetal, in a VM or as a container"), + SD_VARLINK_DEFINE_ENUM_VALUE(machine), + SD_VARLINK_FIELD_COMMENT("An portable service image"), + SD_VARLINK_DEFINE_ENUM_VALUE(portable), + SD_VARLINK_FIELD_COMMENT("A system extension image"), + SD_VARLINK_DEFINE_ENUM_VALUE(sysext), + SD_VARLINK_FIELD_COMMENT("A configuration extension image"), + SD_VARLINK_DEFINE_ENUM_VALUE(confext)); -static VARLINK_DEFINE_ENUM_TYPE( +static SD_VARLINK_DEFINE_ENUM_TYPE( RemoteType, - VARLINK_FIELD_COMMENT("Raw binary disk images, typically in a GPT envelope"), - VARLINK_DEFINE_ENUM_VALUE(raw), - VARLINK_FIELD_COMMENT("A tarball, optionally compressed"), - VARLINK_DEFINE_ENUM_VALUE(tar)); + SD_VARLINK_FIELD_COMMENT("Raw binary disk images, typically in a GPT envelope"), + SD_VARLINK_DEFINE_ENUM_VALUE(raw), + SD_VARLINK_FIELD_COMMENT("A tarball, optionally compressed"), + SD_VARLINK_DEFINE_ENUM_VALUE(tar)); -static VARLINK_DEFINE_ENUM_TYPE( +static SD_VARLINK_DEFINE_ENUM_TYPE( TransferType, - VARLINK_FIELD_COMMENT("A local import of a tarball"), - VARLINK_DEFINE_ENUM_VALUE(import_tar), - VARLINK_FIELD_COMMENT("A local import of a raw disk image"), - VARLINK_DEFINE_ENUM_VALUE(import_raw), - VARLINK_FIELD_COMMENT("A local import of a file system tree"), - VARLINK_DEFINE_ENUM_VALUE(import_fs), - VARLINK_FIELD_COMMENT("A local export of a tarball"), - VARLINK_DEFINE_ENUM_VALUE(export_tar), - VARLINK_FIELD_COMMENT("A local export of a raw disk image"), - VARLINK_DEFINE_ENUM_VALUE(export_raw), - VARLINK_FIELD_COMMENT("A download of a tarball"), - VARLINK_DEFINE_ENUM_VALUE(pull_tar), - VARLINK_FIELD_COMMENT("A download of a raw disk image"), - VARLINK_DEFINE_ENUM_VALUE(pull_raw)); + SD_VARLINK_FIELD_COMMENT("A local import of a tarball"), + SD_VARLINK_DEFINE_ENUM_VALUE(import_tar), + SD_VARLINK_FIELD_COMMENT("A local import of a raw disk image"), + SD_VARLINK_DEFINE_ENUM_VALUE(import_raw), + SD_VARLINK_FIELD_COMMENT("A local import of a file system tree"), + SD_VARLINK_DEFINE_ENUM_VALUE(import_fs), + SD_VARLINK_FIELD_COMMENT("A local export of a tarball"), + SD_VARLINK_DEFINE_ENUM_VALUE(export_tar), + SD_VARLINK_FIELD_COMMENT("A local export of a raw disk image"), + SD_VARLINK_DEFINE_ENUM_VALUE(export_raw), + SD_VARLINK_FIELD_COMMENT("A download of a tarball"), + SD_VARLINK_DEFINE_ENUM_VALUE(pull_tar), + SD_VARLINK_FIELD_COMMENT("A download of a raw disk image"), + SD_VARLINK_DEFINE_ENUM_VALUE(pull_raw)); -static VARLINK_DEFINE_ENUM_TYPE( +static SD_VARLINK_DEFINE_ENUM_TYPE( ImageVerify, - VARLINK_FIELD_COMMENT("No verification"), - VARLINK_DEFINE_ENUM_VALUE(no), - VARLINK_FIELD_COMMENT("Verify that downloads match checksum file (SHA256SUMS), but do not check signature of checksum file"), - VARLINK_DEFINE_ENUM_VALUE(checksum), - VARLINK_FIELD_COMMENT("Verify that downloads match checksum file (SHA256SUMS), and check signature of checksum file."), - VARLINK_DEFINE_ENUM_VALUE(signature)); + SD_VARLINK_FIELD_COMMENT("No verification"), + SD_VARLINK_DEFINE_ENUM_VALUE(no), + SD_VARLINK_FIELD_COMMENT("Verify that downloads match checksum file (SHA256SUMS), but do not check signature of checksum file"), + SD_VARLINK_DEFINE_ENUM_VALUE(checksum), + SD_VARLINK_FIELD_COMMENT("Verify that downloads match checksum file (SHA256SUMS), and check signature of checksum file."), + SD_VARLINK_DEFINE_ENUM_VALUE(signature)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( LogMessage, - VARLINK_FIELD_COMMENT("The log message"), - VARLINK_DEFINE_FIELD(message, VARLINK_STRING, 0), - VARLINK_FIELD_COMMENT("The priority of the log message, using the BSD syslog priority levels"), - VARLINK_DEFINE_FIELD(priority, VARLINK_INT, 0)); + SD_VARLINK_FIELD_COMMENT("The log message"), + SD_VARLINK_DEFINE_FIELD(message, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("The priority of the log message, using the BSD syslog priority levels"), + SD_VARLINK_DEFINE_FIELD(priority, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( ListTransfers, - VARLINK_FIELD_COMMENT("Image class to filter by"), - VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("A unique numeric identifier for the ongoing transfer"), - VARLINK_DEFINE_OUTPUT(id, VARLINK_INT, 0), - VARLINK_FIELD_COMMENT("The type of transfer"), - VARLINK_DEFINE_OUTPUT_BY_TYPE(type, TransferType, 0), - VARLINK_FIELD_COMMENT("The remote URL"), - VARLINK_DEFINE_OUTPUT(remote, VARLINK_STRING, 0), - VARLINK_FIELD_COMMENT("The local image name"), - VARLINK_DEFINE_OUTPUT(local, VARLINK_STRING, 0), - VARLINK_FIELD_COMMENT("The class of the image"), - VARLINK_DEFINE_OUTPUT_BY_TYPE(class, ImageClass, 0), - VARLINK_FIELD_COMMENT("Progress in percent"), - VARLINK_DEFINE_OUTPUT(percent, VARLINK_FLOAT, 0)); + SD_VARLINK_FIELD_COMMENT("Image class to filter by"), + SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("A unique numeric identifier for the ongoing transfer"), + SD_VARLINK_DEFINE_OUTPUT(id, SD_VARLINK_INT, 0), + SD_VARLINK_FIELD_COMMENT("The type of transfer"), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(type, TransferType, 0), + SD_VARLINK_FIELD_COMMENT("The remote URL"), + SD_VARLINK_DEFINE_OUTPUT(remote, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("The local image name"), + SD_VARLINK_DEFINE_OUTPUT(local, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("The class of the image"), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(class, ImageClass, 0), + SD_VARLINK_FIELD_COMMENT("Progress in percent"), + SD_VARLINK_DEFINE_OUTPUT(percent, SD_VARLINK_FLOAT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Pull, - VARLINK_FIELD_COMMENT("The remote URL to download from"), - VARLINK_DEFINE_INPUT(remote, VARLINK_STRING, 0), - VARLINK_FIELD_COMMENT("The local image name to download to"), - VARLINK_DEFINE_INPUT(local, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The type of the resource"), - VARLINK_DEFINE_INPUT_BY_TYPE(type, RemoteType, 0), - VARLINK_FIELD_COMMENT("The image class"), - VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, 0), - VARLINK_FIELD_COMMENT("The whether and how thoroughly to verify the download before installing it locally. Defauts to 'signature'."), - VARLINK_DEFINE_INPUT_BY_TYPE(verify, ImageVerify, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("If true, an existing image by the local name is deleted. Defaults to false."), - VARLINK_DEFINE_INPUT(force, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Whether to make the image read-only after downloading. Defaults ot false."), - VARLINK_DEFINE_INPUT(readOnly, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Whether to keep a pristine copy of the download separate from the locally installed image. Defaults to false."), - VARLINK_DEFINE_INPUT(keepDownload, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Whether to permit interactive authentication. Defaults to false."), - VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("A progress update, as percent value"), - VARLINK_DEFINE_OUTPUT(progress, VARLINK_FLOAT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("A log message about the ongoing transfer"), - VARLINK_DEFINE_OUTPUT_BY_TYPE(log, LogMessage, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The numeric ID of this download"), - VARLINK_DEFINE_OUTPUT(id, VARLINK_INT, VARLINK_NULLABLE)); + SD_VARLINK_FIELD_COMMENT("The remote URL to download from"), + SD_VARLINK_DEFINE_INPUT(remote, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("The local image name to download to"), + SD_VARLINK_DEFINE_INPUT(local, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The type of the resource"), + SD_VARLINK_DEFINE_INPUT_BY_TYPE(type, RemoteType, 0), + SD_VARLINK_FIELD_COMMENT("The image class"), + SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, 0), + SD_VARLINK_FIELD_COMMENT("The whether and how thoroughly to verify the download before installing it locally. Defauts to 'signature'."), + SD_VARLINK_DEFINE_INPUT_BY_TYPE(verify, ImageVerify, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("If true, an existing image by the local name is deleted. Defaults to false."), + SD_VARLINK_DEFINE_INPUT(force, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Whether to make the image read-only after downloading. Defaults ot false."), + SD_VARLINK_DEFINE_INPUT(readOnly, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Whether to keep a pristine copy of the download separate from the locally installed image. Defaults to false."), + SD_VARLINK_DEFINE_INPUT(keepDownload, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Whether to permit interactive authentication. Defaults to false."), + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("A progress update, as percent value"), + SD_VARLINK_DEFINE_OUTPUT(progress, SD_VARLINK_FLOAT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("A log message about the ongoing transfer"), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(log, LogMessage, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The numeric ID of this download"), + SD_VARLINK_DEFINE_OUTPUT(id, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_ERROR(AlreadyInProgress); -static VARLINK_DEFINE_ERROR(TransferCancelled); -static VARLINK_DEFINE_ERROR(TransferFailed); -static VARLINK_DEFINE_ERROR(NoTransfers); +static SD_VARLINK_DEFINE_ERROR(AlreadyInProgress); +static SD_VARLINK_DEFINE_ERROR(TransferCancelled); +static SD_VARLINK_DEFINE_ERROR(TransferFailed); +static SD_VARLINK_DEFINE_ERROR(NoTransfers); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_Import, "io.systemd.Import", - VARLINK_SYMBOL_COMMENT("Describes the class of images"), + SD_VARLINK_SYMBOL_COMMENT("Describes the class of images"), &vl_type_ImageClass, - VARLINK_SYMBOL_COMMENT("Describes the type of a images to transfer"), + SD_VARLINK_SYMBOL_COMMENT("Describes the type of a images to transfer"), &vl_type_RemoteType, - VARLINK_SYMBOL_COMMENT("Describes the type of a transfer"), + SD_VARLINK_SYMBOL_COMMENT("Describes the type of a transfer"), &vl_type_TransferType, - VARLINK_SYMBOL_COMMENT("Describes whether and how thoroughly to verify the download before installing it locally"), + SD_VARLINK_SYMBOL_COMMENT("Describes whether and how thoroughly to verify the download before installing it locally"), &vl_type_ImageVerify, - VARLINK_SYMBOL_COMMENT("Structure for log messages associated with a transfer operation"), + SD_VARLINK_SYMBOL_COMMENT("Structure for log messages associated with a transfer operation"), &vl_type_LogMessage, - VARLINK_SYMBOL_COMMENT("List ongoing transfers, or query details about specific transfers"), + SD_VARLINK_SYMBOL_COMMENT("List ongoing transfers, or query details about specific transfers"), &vl_method_ListTransfers, - VARLINK_SYMBOL_COMMENT("Download a .tar or .raw file. This must be called with the 'more' flag enabled. It will immediately return the numeric ID of the transfer, and then follow up with progress and log message updates, until the transfer is complete."), + SD_VARLINK_SYMBOL_COMMENT("Download a .tar or .raw file. This must be called with the 'more' flag enabled. It will immediately return the numeric ID of the transfer, and then follow up with progress and log message updates, until the transfer is complete."), &vl_method_Pull, - VARLINK_SYMBOL_COMMENT("A transfer for the specified file is already ongoing"), + SD_VARLINK_SYMBOL_COMMENT("A transfer for the specified file is already ongoing"), &vl_error_AlreadyInProgress, - VARLINK_SYMBOL_COMMENT("The transfer has been cancelled on user request"), + SD_VARLINK_SYMBOL_COMMENT("The transfer has been cancelled on user request"), &vl_error_TransferCancelled, - VARLINK_SYMBOL_COMMENT("The transfer failed"), + SD_VARLINK_SYMBOL_COMMENT("The transfer failed"), &vl_error_TransferFailed, - VARLINK_SYMBOL_COMMENT("No currently ongoing transfer"), + SD_VARLINK_SYMBOL_COMMENT("No currently ongoing transfer"), &vl_error_NoTransfers); diff --git a/src/shared/varlink-io.systemd.Import.h b/src/shared/varlink-io.systemd.Import.h index 6579c29b39..22e85492fa 100644 --- a/src/shared/varlink-io.systemd.Import.h +++ b/src/shared/varlink-io.systemd.Import.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_Import; +extern const sd_varlink_interface vl_interface_io_systemd_Import; diff --git a/src/shared/varlink-io.systemd.Journal.c b/src/shared/varlink-io.systemd.Journal.c index b93fb72aca..66514a9d57 100644 --- a/src/shared/varlink-io.systemd.Journal.c +++ b/src/shared/varlink-io.systemd.Journal.c @@ -2,14 +2,14 @@ #include "varlink-io.systemd.Journal.h" -static VARLINK_DEFINE_METHOD(Synchronize); -static VARLINK_DEFINE_METHOD(Rotate); -static VARLINK_DEFINE_METHOD(FlushToVar); -static VARLINK_DEFINE_METHOD(RelinquishVar); +static SD_VARLINK_DEFINE_METHOD(Synchronize); +static SD_VARLINK_DEFINE_METHOD(Rotate); +static SD_VARLINK_DEFINE_METHOD(FlushToVar); +static SD_VARLINK_DEFINE_METHOD(RelinquishVar); -static VARLINK_DEFINE_ERROR(NotSupportedByNamespaces); +static SD_VARLINK_DEFINE_ERROR(NotSupportedByNamespaces); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_Journal, "io.systemd.Journal", &vl_method_Synchronize, diff --git a/src/shared/varlink-io.systemd.Journal.h b/src/shared/varlink-io.systemd.Journal.h index 0bc94a775c..a6a6050c44 100644 --- a/src/shared/varlink-io.systemd.Journal.h +++ b/src/shared/varlink-io.systemd.Journal.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_Journal; +extern const sd_varlink_interface vl_interface_io_systemd_Journal; diff --git a/src/shared/varlink-io.systemd.Machine.c b/src/shared/varlink-io.systemd.Machine.c index 4d93527273..1c8f39e3c7 100644 --- a/src/shared/varlink-io.systemd.Machine.c +++ b/src/shared/varlink-io.systemd.Machine.c @@ -1,68 +1,69 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "varlink-idl.h" +#include "sd-varlink-idl.h" + #include "varlink-io.systemd.Machine.h" -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Register, - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, 0), - VARLINK_DEFINE_INPUT(id, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(service, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(class, VARLINK_STRING, 0), - VARLINK_DEFINE_INPUT(leader, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(rootDirectory, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(ifIndices, VARLINK_INT, VARLINK_ARRAY|VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(vSockCid, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(sshAddress, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(sshPrivateKeyPath, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Controls whether to allocate a scope unit for the machine to register. If false, the client already took care of that and registered a service/scope specific to the machine."), - VARLINK_DEFINE_INPUT(allocateUnit, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Whether to allow interactive authentication on this operation."), - VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, VARLINK_BOOL, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_INPUT(id, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(service, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(class, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_INPUT(leader, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(rootDirectory, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(ifIndices, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(vSockCid, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(sshAddress, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(sshPrivateKeyPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Controls whether to allocate a scope unit for the machine to register. If false, the client already took care of that and registered a service/scope specific to the machine."), + SD_VARLINK_DEFINE_INPUT(allocateUnit, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Whether to allow interactive authentication on this operation."), + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( Timestamp, - VARLINK_FIELD_COMMENT("Timestamp in µs in the CLOCK_REALTIME clock (wallclock)"), - VARLINK_DEFINE_FIELD(realtime, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Timestamp in µs in the CLOCK_MONOTONIC clock"), - VARLINK_DEFINE_FIELD(monotonic, VARLINK_INT, VARLINK_NULLABLE)); + SD_VARLINK_FIELD_COMMENT("Timestamp in µs in the CLOCK_REALTIME clock (wallclock)"), + SD_VARLINK_DEFINE_FIELD(realtime, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Timestamp in µs in the CLOCK_MONOTONIC clock"), + SD_VARLINK_DEFINE_FIELD(monotonic, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( List, - VARLINK_FIELD_COMMENT("If non-null the name of a running machine to report details on. If null/unspecified enumerates all running machines."), - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Name of the machine"), - VARLINK_DEFINE_OUTPUT(name, VARLINK_STRING, 0), - VARLINK_FIELD_COMMENT("128bit ID identifying this machine, formatted in hexadecimal"), - VARLINK_DEFINE_OUTPUT(id, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Name of the software that registered this machine"), - VARLINK_DEFINE_OUTPUT(service, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The class of this machine"), - VARLINK_DEFINE_OUTPUT(class, VARLINK_STRING, 0), - VARLINK_FIELD_COMMENT("Leader process PID of this machine"), - VARLINK_DEFINE_OUTPUT(leader, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Root directory of this machine, if known, relative to host file system"), - VARLINK_DEFINE_OUTPUT(rootDirectory, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("The service manager unit this machine resides in"), - VARLINK_DEFINE_OUTPUT(unit, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("Timestamp when the machine was activated"), - VARLINK_DEFINE_OUTPUT_BY_TYPE(timestamp, Timestamp, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("AF_VSOCK CID of the machine if known and applicable"), - VARLINK_DEFINE_OUTPUT(vSockCid, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_FIELD_COMMENT("SSH address to connect to"), - VARLINK_DEFINE_OUTPUT(sshAddress, VARLINK_STRING, VARLINK_NULLABLE)); + SD_VARLINK_FIELD_COMMENT("If non-null the name of a running machine to report details on. If null/unspecified enumerates all running machines."), + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Name of the machine"), + SD_VARLINK_DEFINE_OUTPUT(name, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("128bit ID identifying this machine, formatted in hexadecimal"), + SD_VARLINK_DEFINE_OUTPUT(id, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Name of the software that registered this machine"), + SD_VARLINK_DEFINE_OUTPUT(service, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The class of this machine"), + SD_VARLINK_DEFINE_OUTPUT(class, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("Leader process PID of this machine"), + SD_VARLINK_DEFINE_OUTPUT(leader, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Root directory of this machine, if known, relative to host file system"), + SD_VARLINK_DEFINE_OUTPUT(rootDirectory, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("The service manager unit this machine resides in"), + SD_VARLINK_DEFINE_OUTPUT(unit, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("Timestamp when the machine was activated"), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(timestamp, Timestamp, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("AF_VSOCK CID of the machine if known and applicable"), + SD_VARLINK_DEFINE_OUTPUT(vSockCid, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_FIELD_COMMENT("SSH address to connect to"), + SD_VARLINK_DEFINE_OUTPUT(sshAddress, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_ERROR(NoSuchMachine); -static VARLINK_DEFINE_ERROR(MachineExists); +static SD_VARLINK_DEFINE_ERROR(NoSuchMachine); +static SD_VARLINK_DEFINE_ERROR(MachineExists); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_Machine, "io.systemd.Machine", - VARLINK_SYMBOL_COMMENT("A timestamp object consisting of both CLOCK_REALTIME and CLOCK_MONOTONIC timestamps"), + SD_VARLINK_SYMBOL_COMMENT("A timestamp object consisting of both CLOCK_REALTIME and CLOCK_MONOTONIC timestamps"), &vl_type_Timestamp, &vl_method_Register, - VARLINK_SYMBOL_COMMENT("List running machines"), + SD_VARLINK_SYMBOL_COMMENT("List running machines"), &vl_method_List, - VARLINK_SYMBOL_COMMENT("No matching machine currently running"), + SD_VARLINK_SYMBOL_COMMENT("No matching machine currently running"), &vl_error_NoSuchMachine, &vl_error_MachineExists); diff --git a/src/shared/varlink-io.systemd.Machine.h b/src/shared/varlink-io.systemd.Machine.h index c9fc85f150..605a314526 100644 --- a/src/shared/varlink-io.systemd.Machine.h +++ b/src/shared/varlink-io.systemd.Machine.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_Machine; +extern const sd_varlink_interface vl_interface_io_systemd_Machine; diff --git a/src/shared/varlink-io.systemd.ManagedOOM.c b/src/shared/varlink-io.systemd.ManagedOOM.c index d6414b3718..8fc329b707 100644 --- a/src/shared/varlink-io.systemd.ManagedOOM.c +++ b/src/shared/varlink-io.systemd.ManagedOOM.c @@ -9,13 +9,13 @@ * * Compare with io.systemd.oom where the client/server roles of oomd and the service manager are swapped! */ -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( SubscribeManagedOOMCGroups, - VARLINK_DEFINE_OUTPUT_BY_TYPE(cgroups, ControlGroup, VARLINK_ARRAY)); + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(cgroups, ControlGroup, SD_VARLINK_ARRAY)); -static VARLINK_DEFINE_ERROR(SubscriptionTaken); +static SD_VARLINK_DEFINE_ERROR(SubscriptionTaken); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_ManagedOOM, "io.systemd.ManagedOOM", &vl_method_SubscribeManagedOOMCGroups, diff --git a/src/shared/varlink-io.systemd.ManagedOOM.h b/src/shared/varlink-io.systemd.ManagedOOM.h index 2c8bf54c4e..ee095ee60d 100644 --- a/src/shared/varlink-io.systemd.ManagedOOM.h +++ b/src/shared/varlink-io.systemd.ManagedOOM.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_ManagedOOM; +extern const sd_varlink_interface vl_interface_io_systemd_ManagedOOM; diff --git a/src/shared/varlink-io.systemd.MountFileSystem.c b/src/shared/varlink-io.systemd.MountFileSystem.c index 4a33578a10..e735d9e2fc 100644 --- a/src/shared/varlink-io.systemd.MountFileSystem.c +++ b/src/shared/varlink-io.systemd.MountFileSystem.c @@ -2,60 +2,60 @@ #include "varlink-io.systemd.MountFileSystem.h" -static VARLINK_DEFINE_ENUM_TYPE( +static SD_VARLINK_DEFINE_ENUM_TYPE( PartitionDesignator, - VARLINK_DEFINE_ENUM_VALUE(root), - VARLINK_DEFINE_ENUM_VALUE(usr), - VARLINK_DEFINE_ENUM_VALUE(home), - VARLINK_DEFINE_ENUM_VALUE(srv), - VARLINK_DEFINE_ENUM_VALUE(esp), - VARLINK_DEFINE_ENUM_VALUE(xbootldr), - VARLINK_DEFINE_ENUM_VALUE(swap), - VARLINK_DEFINE_ENUM_VALUE(root_verity), - VARLINK_DEFINE_ENUM_VALUE(usr_verity), - VARLINK_DEFINE_ENUM_VALUE(root_verity_sig), - VARLINK_DEFINE_ENUM_VALUE(usr_verity_sig), - VARLINK_DEFINE_ENUM_VALUE(tmp), - VARLINK_DEFINE_ENUM_VALUE(var)); + SD_VARLINK_DEFINE_ENUM_VALUE(root), + SD_VARLINK_DEFINE_ENUM_VALUE(usr), + SD_VARLINK_DEFINE_ENUM_VALUE(home), + SD_VARLINK_DEFINE_ENUM_VALUE(srv), + SD_VARLINK_DEFINE_ENUM_VALUE(esp), + SD_VARLINK_DEFINE_ENUM_VALUE(xbootldr), + SD_VARLINK_DEFINE_ENUM_VALUE(swap), + SD_VARLINK_DEFINE_ENUM_VALUE(root_verity), + SD_VARLINK_DEFINE_ENUM_VALUE(usr_verity), + SD_VARLINK_DEFINE_ENUM_VALUE(root_verity_sig), + SD_VARLINK_DEFINE_ENUM_VALUE(usr_verity_sig), + SD_VARLINK_DEFINE_ENUM_VALUE(tmp), + SD_VARLINK_DEFINE_ENUM_VALUE(var)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( PartitionInfo, - VARLINK_DEFINE_FIELD(designator, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(writable, VARLINK_BOOL, 0), - VARLINK_DEFINE_FIELD(growFileSystem, VARLINK_BOOL, 0), - VARLINK_DEFINE_FIELD(partitionNumber, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(architecture, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(partitionUuid, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(fileSystemType, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(partitionLabel, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(size, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(offset, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(mountFileDescriptor, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_FIELD(designator, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(writable, SD_VARLINK_BOOL, 0), + SD_VARLINK_DEFINE_FIELD(growFileSystem, SD_VARLINK_BOOL, 0), + SD_VARLINK_DEFINE_FIELD(partitionNumber, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(architecture, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(partitionUuid, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(fileSystemType, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(partitionLabel, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(size, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(offset, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(mountFileDescriptor, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( MountImage, - VARLINK_DEFINE_INPUT(imageFileDescriptor, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(readOnly, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(growFileSystems, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(password, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(imagePolicy, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(partitions, PartitionInfo, VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT(imagePolicy, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(imageSize, VARLINK_INT, 0), - VARLINK_DEFINE_OUTPUT(sectorSize, VARLINK_INT, 0), - VARLINK_DEFINE_OUTPUT(imageName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(imageUuid, VARLINK_STRING, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT(imageFileDescriptor, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(readOnly, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(growFileSystems, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(password, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(imagePolicy, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(allowInteractiveAuthentication, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(partitions, PartitionInfo, SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT(imagePolicy, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(imageSize, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_OUTPUT(sectorSize, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_OUTPUT(imageName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(imageUuid, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_ERROR(IncompatibleImage); -static VARLINK_DEFINE_ERROR(MultipleRootPartitionsFound); -static VARLINK_DEFINE_ERROR(RootPartitionNotFound); -static VARLINK_DEFINE_ERROR(DeniedByImagePolicy); -static VARLINK_DEFINE_ERROR(KeyNotFound); -static VARLINK_DEFINE_ERROR(VerityFailure); +static SD_VARLINK_DEFINE_ERROR(IncompatibleImage); +static SD_VARLINK_DEFINE_ERROR(MultipleRootPartitionsFound); +static SD_VARLINK_DEFINE_ERROR(RootPartitionNotFound); +static SD_VARLINK_DEFINE_ERROR(DeniedByImagePolicy); +static SD_VARLINK_DEFINE_ERROR(KeyNotFound); +static SD_VARLINK_DEFINE_ERROR(VerityFailure); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_MountFileSystem, "io.systemd.MountFileSystem", &vl_type_PartitionDesignator, diff --git a/src/shared/varlink-io.systemd.MountFileSystem.h b/src/shared/varlink-io.systemd.MountFileSystem.h index dc75957df4..0e6ad51e64 100644 --- a/src/shared/varlink-io.systemd.MountFileSystem.h +++ b/src/shared/varlink-io.systemd.MountFileSystem.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_MountFileSystem; +extern const sd_varlink_interface vl_interface_io_systemd_MountFileSystem; diff --git a/src/shared/varlink-io.systemd.NamespaceResource.c b/src/shared/varlink-io.systemd.NamespaceResource.c index e98c6c6663..83419acba4 100644 --- a/src/shared/varlink-io.systemd.NamespaceResource.c +++ b/src/shared/varlink-io.systemd.NamespaceResource.c @@ -2,48 +2,48 @@ #include "varlink-io.systemd.NamespaceResource.h" -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( AllocateUserRange, - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, 0), - VARLINK_DEFINE_INPUT(size, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(target, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_INPUT(size, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(target, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( RegisterUserNamespace, - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, 0), - VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( AddMountToUserNamespace, - VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(mountFileDescriptor, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(mountFileDescriptor, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( AddControlGroupToUserNamespace, - VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(controlGroupFileDescriptor, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(controlGroupFileDescriptor, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( AddNetworkToUserNamespace, - VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(networkNamespaceFileDescriptor, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(namespaceInterfaceName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(mode, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(hostInterfaceName, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(namespaceInterfaceName, VARLINK_STRING, 0)); - -static VARLINK_DEFINE_ERROR(UserNamespaceInterfaceNotSupported); -static VARLINK_DEFINE_ERROR(NameExists); -static VARLINK_DEFINE_ERROR(UserNamespaceExists); -static VARLINK_DEFINE_ERROR(DynamicRangeUnavailable); -static VARLINK_DEFINE_ERROR(NoDynamicRange); -static VARLINK_DEFINE_ERROR(UserNamespaceNotRegistered); -static VARLINK_DEFINE_ERROR(UserNamespaceWithoutUserRange); -static VARLINK_DEFINE_ERROR(TooManyControlGroups); -static VARLINK_DEFINE_ERROR(ControlGroupAlreadyAdded); - -VARLINK_DEFINE_INTERFACE( + SD_VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(networkNamespaceFileDescriptor, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(namespaceInterfaceName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(mode, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(hostInterfaceName, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(namespaceInterfaceName, SD_VARLINK_STRING, 0)); + +static SD_VARLINK_DEFINE_ERROR(UserNamespaceInterfaceNotSupported); +static SD_VARLINK_DEFINE_ERROR(NameExists); +static SD_VARLINK_DEFINE_ERROR(UserNamespaceExists); +static SD_VARLINK_DEFINE_ERROR(DynamicRangeUnavailable); +static SD_VARLINK_DEFINE_ERROR(NoDynamicRange); +static SD_VARLINK_DEFINE_ERROR(UserNamespaceNotRegistered); +static SD_VARLINK_DEFINE_ERROR(UserNamespaceWithoutUserRange); +static SD_VARLINK_DEFINE_ERROR(TooManyControlGroups); +static SD_VARLINK_DEFINE_ERROR(ControlGroupAlreadyAdded); + +SD_VARLINK_DEFINE_INTERFACE( io_systemd_NamespaceResource, "io.systemd.NamespaceResource", &vl_method_AllocateUserRange, diff --git a/src/shared/varlink-io.systemd.NamespaceResource.h b/src/shared/varlink-io.systemd.NamespaceResource.h index 443cb97e48..b8137d48fc 100644 --- a/src/shared/varlink-io.systemd.NamespaceResource.h +++ b/src/shared/varlink-io.systemd.NamespaceResource.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_NamespaceResource; +extern const sd_varlink_interface vl_interface_io_systemd_NamespaceResource; diff --git a/src/shared/varlink-io.systemd.Network.c b/src/shared/varlink-io.systemd.Network.c index 394cc33ace..fe0aecf1f1 100644 --- a/src/shared/varlink-io.systemd.Network.c +++ b/src/shared/varlink-io.systemd.Network.c @@ -2,51 +2,51 @@ #include "varlink-io.systemd.Network.h" -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( GetStates, - VARLINK_DEFINE_OUTPUT(AddressState, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(IPv4AddressState, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(IPv6AddressState, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(CarrierState, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(OnlineState, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(OperationalState, VARLINK_STRING, 0)); - -static VARLINK_DEFINE_METHOD( + SD_VARLINK_DEFINE_OUTPUT(AddressState, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(IPv4AddressState, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(IPv6AddressState, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(CarrierState, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(OnlineState, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(OperationalState, SD_VARLINK_STRING, 0)); + +static SD_VARLINK_DEFINE_METHOD( GetNamespaceId, - VARLINK_DEFINE_OUTPUT(NamespaceId, VARLINK_INT, 0), - VARLINK_DEFINE_OUTPUT(NamespaceNSID, VARLINK_INT, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_OUTPUT(NamespaceId, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_OUTPUT(NamespaceNSID, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( LLDPNeighbor, - VARLINK_DEFINE_FIELD(ChassisID, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(RawChassisID, VARLINK_INT, VARLINK_ARRAY), - VARLINK_DEFINE_FIELD(PortID, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(RawPortID, VARLINK_INT, VARLINK_ARRAY), - VARLINK_DEFINE_FIELD(PortDescription, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(SystemName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(SystemDescription, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(EnabledCapabilities, VARLINK_INT, VARLINK_NULLABLE)); - -static VARLINK_DEFINE_STRUCT_TYPE( + SD_VARLINK_DEFINE_FIELD(ChassisID, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(RawChassisID, SD_VARLINK_INT, SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_FIELD(PortID, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(RawPortID, SD_VARLINK_INT, SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_FIELD(PortDescription, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(SystemName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(SystemDescription, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(EnabledCapabilities, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( LLDPNeighborsByInterface, - VARLINK_DEFINE_FIELD(InterfaceIndex, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(InterfaceName, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(InterfaceAlternativeNames, VARLINK_STRING, VARLINK_ARRAY|VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD_BY_TYPE(Neighbors, LLDPNeighbor, VARLINK_ARRAY)); + SD_VARLINK_DEFINE_FIELD(InterfaceIndex, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(InterfaceName, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(InterfaceAlternativeNames, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(Neighbors, LLDPNeighbor, SD_VARLINK_ARRAY)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( GetLLDPNeighbors, - VARLINK_DEFINE_INPUT(InterfaceIndex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(InterfaceName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(Neighbors, LLDPNeighborsByInterface, VARLINK_ARRAY)); + SD_VARLINK_DEFINE_INPUT(InterfaceIndex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(InterfaceName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(Neighbors, LLDPNeighborsByInterface, SD_VARLINK_ARRAY)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( SetPersistentStorage, - VARLINK_DEFINE_INPUT(Ready, VARLINK_BOOL, 0)); + SD_VARLINK_DEFINE_INPUT(Ready, SD_VARLINK_BOOL, 0)); -static VARLINK_DEFINE_ERROR(StorageReadOnly); +static SD_VARLINK_DEFINE_ERROR(StorageReadOnly); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_Network, "io.systemd.Network", &vl_method_GetStates, diff --git a/src/shared/varlink-io.systemd.Network.h b/src/shared/varlink-io.systemd.Network.h index 12d532ab32..1d2871636f 100644 --- a/src/shared/varlink-io.systemd.Network.h +++ b/src/shared/varlink-io.systemd.Network.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_Network; +extern const sd_varlink_interface vl_interface_io_systemd_Network; diff --git a/src/shared/varlink-io.systemd.PCRExtend.c b/src/shared/varlink-io.systemd.PCRExtend.c index 37d403f0ee..956a0eacca 100644 --- a/src/shared/varlink-io.systemd.PCRExtend.c +++ b/src/shared/varlink-io.systemd.PCRExtend.c @@ -2,13 +2,13 @@ #include "varlink-io.systemd.PCRExtend.h" -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Extend, - VARLINK_DEFINE_INPUT(pcr, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(text, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(data, VARLINK_STRING, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT(pcr, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(text, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(data, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_PCRExtend, "io.systemd.PCRExtend", &vl_method_Extend); diff --git a/src/shared/varlink-io.systemd.PCRExtend.h b/src/shared/varlink-io.systemd.PCRExtend.h index ffc075af2c..212edd59dd 100644 --- a/src/shared/varlink-io.systemd.PCRExtend.h +++ b/src/shared/varlink-io.systemd.PCRExtend.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_PCRExtend; +extern const sd_varlink_interface vl_interface_io_systemd_PCRExtend; diff --git a/src/shared/varlink-io.systemd.PCRLock.c b/src/shared/varlink-io.systemd.PCRLock.c index 22c653228c..f385eb31c3 100644 --- a/src/shared/varlink-io.systemd.PCRLock.c +++ b/src/shared/varlink-io.systemd.PCRLock.c @@ -2,21 +2,21 @@ #include "varlink-io.systemd.PCRLock.h" -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( ReadEventLog, - VARLINK_DEFINE_OUTPUT(record, VARLINK_OBJECT, 0)); + SD_VARLINK_DEFINE_OUTPUT(record, SD_VARLINK_OBJECT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( MakePolicy, - VARLINK_DEFINE_INPUT(force, VARLINK_BOOL, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT(force, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( RemovePolicy); -static VARLINK_DEFINE_ERROR( +static SD_VARLINK_DEFINE_ERROR( NoChange); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_PCRLock, "io.systemd.PCRLock", &vl_method_ReadEventLog, diff --git a/src/shared/varlink-io.systemd.PCRLock.h b/src/shared/varlink-io.systemd.PCRLock.h index 687f09ef84..b323892c71 100644 --- a/src/shared/varlink-io.systemd.PCRLock.h +++ b/src/shared/varlink-io.systemd.PCRLock.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_PCRLock; +extern const sd_varlink_interface vl_interface_io_systemd_PCRLock; diff --git a/src/shared/varlink-io.systemd.Resolve.Monitor.c b/src/shared/varlink-io.systemd.Resolve.Monitor.c index ba928fa2cf..36681f5ea0 100644 --- a/src/shared/varlink-io.systemd.Resolve.Monitor.c +++ b/src/shared/varlink-io.systemd.Resolve.Monitor.c @@ -6,105 +6,105 @@ * hence import them here. */ #include "varlink-io.systemd.Resolve.h" -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( ResourceRecordArray, - VARLINK_DEFINE_FIELD_BY_TYPE(rr, ResourceRecord, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(raw, VARLINK_STRING, 0)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(rr, ResourceRecord, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(raw, SD_VARLINK_STRING, 0)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( Answer, - VARLINK_DEFINE_FIELD_BY_TYPE(rr, ResourceRecord, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(raw, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(ifindex, VARLINK_INT, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(rr, ResourceRecord, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(raw, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( SubscribeQueryResults, /* First reply */ - VARLINK_DEFINE_OUTPUT(ready, VARLINK_BOOL, VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(ready, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), /* Subsequent replies */ - VARLINK_DEFINE_OUTPUT(state, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(result, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(rcode, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(errno, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(extendedDNSErrorCode, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(extendedDNSErrorMessage, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(question, ResourceKey, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT_BY_TYPE(collectedQuestions, ResourceKey, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT_BY_TYPE(answer, Answer, VARLINK_NULLABLE|VARLINK_ARRAY)); - -static VARLINK_DEFINE_STRUCT_TYPE( + SD_VARLINK_DEFINE_OUTPUT(state, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(result, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(rcode, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(errno, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(extendedDNSErrorCode, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(extendedDNSErrorMessage, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(question, ResourceKey, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(collectedQuestions, ResourceKey, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(answer, Answer, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( CacheEntry, - VARLINK_DEFINE_FIELD_BY_TYPE(key, ResourceKey, 0), - VARLINK_DEFINE_FIELD_BY_TYPE(rrs, ResourceRecordArray, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_FIELD(type, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(until, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(key, ResourceKey, 0), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(rrs, ResourceRecordArray, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_FIELD(type, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(until, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( ScopeCache, - VARLINK_DEFINE_FIELD(protocol, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(family, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(ifindex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(ifname, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD_BY_TYPE(cache, CacheEntry, VARLINK_ARRAY)); + SD_VARLINK_DEFINE_FIELD(protocol, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(family, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(ifname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(cache, CacheEntry, SD_VARLINK_ARRAY)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( DumpCache, - VARLINK_DEFINE_OUTPUT_BY_TYPE(dump, ScopeCache, VARLINK_ARRAY)); + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(dump, ScopeCache, SD_VARLINK_ARRAY)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( ServerState, - VARLINK_DEFINE_FIELD(Server, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(Type, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(Interface, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(InterfaceIndex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(VerifiedFeatureLevel, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(PossibleFeatureLevel, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(DNSSECMode, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(DNSSECSupported, VARLINK_BOOL, 0), - VARLINK_DEFINE_FIELD(ReceivedUDPFragmentMax, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(FailedUDPAttempts, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(FailedTCPAttempts, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(PacketTruncated, VARLINK_BOOL, 0), - VARLINK_DEFINE_FIELD(PacketBadOpt, VARLINK_BOOL, 0), - VARLINK_DEFINE_FIELD(PacketRRSIGMissing, VARLINK_BOOL, 0), - VARLINK_DEFINE_FIELD(PacketInvalid, VARLINK_BOOL, 0), - VARLINK_DEFINE_FIELD(PacketDoOff, VARLINK_BOOL, 0)); - -static VARLINK_DEFINE_METHOD( + SD_VARLINK_DEFINE_FIELD(Server, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(Type, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(Interface, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(InterfaceIndex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(VerifiedFeatureLevel, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(PossibleFeatureLevel, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(DNSSECMode, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(DNSSECSupported, SD_VARLINK_BOOL, 0), + SD_VARLINK_DEFINE_FIELD(ReceivedUDPFragmentMax, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(FailedUDPAttempts, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(FailedTCPAttempts, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(PacketTruncated, SD_VARLINK_BOOL, 0), + SD_VARLINK_DEFINE_FIELD(PacketBadOpt, SD_VARLINK_BOOL, 0), + SD_VARLINK_DEFINE_FIELD(PacketRRSIGMissing, SD_VARLINK_BOOL, 0), + SD_VARLINK_DEFINE_FIELD(PacketInvalid, SD_VARLINK_BOOL, 0), + SD_VARLINK_DEFINE_FIELD(PacketDoOff, SD_VARLINK_BOOL, 0)); + +static SD_VARLINK_DEFINE_METHOD( DumpServerState, - VARLINK_DEFINE_OUTPUT_BY_TYPE(dump, ServerState, VARLINK_ARRAY)); + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(dump, ServerState, SD_VARLINK_ARRAY)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( TransactionStatistics, - VARLINK_DEFINE_FIELD(currentTransactions, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(totalTransactions, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(totalTimeouts, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(totalTimeoutsServedStale, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(totalFailedResponses, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(totalFailedResponsesServedStale, VARLINK_INT, 0)); - -static VARLINK_DEFINE_STRUCT_TYPE( + SD_VARLINK_DEFINE_FIELD(currentTransactions, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(totalTransactions, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(totalTimeouts, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(totalTimeoutsServedStale, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(totalFailedResponses, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(totalFailedResponsesServedStale, SD_VARLINK_INT, 0)); + +static SD_VARLINK_DEFINE_STRUCT_TYPE( CacheStatistics, - VARLINK_DEFINE_FIELD(size, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(hits, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(misses, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_FIELD(size, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(hits, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(misses, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( DnssecStatistics, - VARLINK_DEFINE_FIELD(secure, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(insecure, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(bogus, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(indeterminate, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_FIELD(secure, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(insecure, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(bogus, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(indeterminate, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( DumpStatistics, - VARLINK_DEFINE_OUTPUT_BY_TYPE(transactions, TransactionStatistics, 0), - VARLINK_DEFINE_OUTPUT_BY_TYPE(cache, CacheStatistics, 0), - VARLINK_DEFINE_OUTPUT_BY_TYPE(dnssec, DnssecStatistics, 0)); + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(transactions, TransactionStatistics, 0), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(cache, CacheStatistics, 0), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(dnssec, DnssecStatistics, 0)); -static VARLINK_DEFINE_METHOD(ResetStatistics); +static SD_VARLINK_DEFINE_METHOD(ResetStatistics); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_Resolve_Monitor, "io.systemd.Resolve.Monitor", &vl_method_SubscribeQueryResults, diff --git a/src/shared/varlink-io.systemd.Resolve.Monitor.h b/src/shared/varlink-io.systemd.Resolve.Monitor.h index a133ec30a5..e633ddfe52 100644 --- a/src/shared/varlink-io.systemd.Resolve.Monitor.h +++ b/src/shared/varlink-io.systemd.Resolve.Monitor.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_Resolve_Monitor; +extern const sd_varlink_interface vl_interface_io_systemd_Resolve_Monitor; diff --git a/src/shared/varlink-io.systemd.Resolve.c b/src/shared/varlink-io.systemd.Resolve.c index 71f4dc84c0..83c68321c4 100644 --- a/src/shared/varlink-io.systemd.Resolve.c +++ b/src/shared/varlink-io.systemd.Resolve.c @@ -2,175 +2,175 @@ #include "varlink-io.systemd.Resolve.h" -VARLINK_DEFINE_STRUCT_TYPE( +SD_VARLINK_DEFINE_STRUCT_TYPE( ResourceKey, - VARLINK_DEFINE_FIELD(class, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(type, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(name, VARLINK_STRING, 0)); + SD_VARLINK_DEFINE_FIELD(class, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(type, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, 0)); -VARLINK_DEFINE_STRUCT_TYPE( +SD_VARLINK_DEFINE_STRUCT_TYPE( ResourceRecord, - VARLINK_DEFINE_FIELD_BY_TYPE(key, ResourceKey, 0), - VARLINK_DEFINE_FIELD(priority, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(weight, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(port, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(name, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(cpu, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(os, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(items, VARLINK_STRING, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_FIELD(address, VARLINK_INT, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_FIELD(mname, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(rname, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(serial, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(refresh, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(expire, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(minimum, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(exchange, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(version, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(size, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(horiz_pre, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(vert_pre, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(latitude, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(longitude, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(altitude, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(keyTag, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(algorithm, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(digestType, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(digest, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(fptype, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(fingerprint, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(flags, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(protocol, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(dnskey, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(signer, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(typeCovered, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(labels, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(originalTtl, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(expiration, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(inception, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(signature, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(nextDomain, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(types, VARLINK_INT, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_FIELD(iterations, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(salt, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(hash, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(certUsage, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(selector, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(matchingType, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(data, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(tag, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(value, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(target, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(params, VARLINK_STRING, VARLINK_NULLABLE|VARLINK_ARRAY), - VARLINK_DEFINE_FIELD(order, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(preference, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(naptrFlags, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(services, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(regexp, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(replacement, VARLINK_STRING, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD_BY_TYPE(key, ResourceKey, 0), + SD_VARLINK_DEFINE_FIELD(priority, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(weight, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(port, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(cpu, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(os, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(items, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_FIELD(address, SD_VARLINK_INT, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_FIELD(mname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(rname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(serial, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(refresh, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(expire, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(minimum, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(exchange, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(version, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(size, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(horiz_pre, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(vert_pre, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(latitude, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(longitude, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(altitude, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(keyTag, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(algorithm, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(digestType, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(digest, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(fptype, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(fingerprint, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(flags, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(protocol, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(dnskey, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(signer, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(typeCovered, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(labels, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(originalTtl, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(expiration, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(inception, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(signature, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(nextDomain, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(types, SD_VARLINK_INT, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_FIELD(iterations, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(salt, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(hash, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(certUsage, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(selector, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(matchingType, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(data, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(tag, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(value, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(target, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(params, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_FIELD(order, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(preference, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(naptrFlags, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(services, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(regexp, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(replacement, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( ResolvedAddress, - VARLINK_DEFINE_FIELD(ifindex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(family, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(address, VARLINK_INT, VARLINK_ARRAY)); + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(family, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(address, SD_VARLINK_INT, SD_VARLINK_ARRAY)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( ResolveHostname, - VARLINK_DEFINE_INPUT(ifindex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, 0), - VARLINK_DEFINE_INPUT(family, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(flags, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(addresses, ResolvedAddress, VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT(name, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(flags, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_INPUT(family, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(flags, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(addresses, ResolvedAddress, SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT(name, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(flags, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( ResolvedName, - VARLINK_DEFINE_FIELD(ifindex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(name, VARLINK_STRING, 0)); + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( ResolveAddress, - VARLINK_DEFINE_INPUT(ifindex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(family, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(address, VARLINK_INT, VARLINK_ARRAY), - VARLINK_DEFINE_INPUT(flags, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(names, ResolvedName, VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT(flags, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(family, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(address, SD_VARLINK_INT, SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_INPUT(flags, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(names, ResolvedName, SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT(flags, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( ResolvedService, - VARLINK_DEFINE_FIELD(priority, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(weight, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(port, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(hostname, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(canonicalName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD_BY_TYPE(addresses, ResolvedAddress, VARLINK_ARRAY|VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD(priority, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(weight, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(port, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(hostname, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(canonicalName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(addresses, ResolvedAddress, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( ResolvedCanonical, - VARLINK_DEFINE_FIELD(name, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(type, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(domain, VARLINK_STRING, 0)); + SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(type, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(domain, SD_VARLINK_STRING, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( ResolveService, - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(type, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(domain, VARLINK_STRING, 0), - VARLINK_DEFINE_INPUT(ifindex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(family, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(flags, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(services, ResolvedService, VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT(txt, VARLINK_STRING, VARLINK_ARRAY|VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(canonical, ResolvedCanonical, 0), - VARLINK_DEFINE_OUTPUT(flags, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(type, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(domain, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_INPUT(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(family, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(flags, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(services, ResolvedService, SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT(txt, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(canonical, ResolvedCanonical, 0), + SD_VARLINK_DEFINE_OUTPUT(flags, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_STRUCT_TYPE( +static SD_VARLINK_DEFINE_STRUCT_TYPE( ResolvedRecord, - VARLINK_DEFINE_FIELD(ifindex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD_BY_TYPE(rr, ResourceRecord, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(raw, VARLINK_STRING, 0)); + SD_VARLINK_DEFINE_FIELD(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD_BY_TYPE(rr, ResourceRecord, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(raw, SD_VARLINK_STRING, 0)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( ResolveRecord, - VARLINK_DEFINE_INPUT(ifindex, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(name, VARLINK_STRING, 0), - VARLINK_DEFINE_INPUT(class, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(type, VARLINK_INT, 0), - VARLINK_DEFINE_INPUT(flags, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(rrs, ResolvedRecord, VARLINK_ARRAY), - VARLINK_DEFINE_OUTPUT(flags, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(ifindex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_INPUT(class, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(type, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_INPUT(flags, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(rrs, ResolvedRecord, SD_VARLINK_ARRAY), + SD_VARLINK_DEFINE_OUTPUT(flags, SD_VARLINK_INT, 0)); -static VARLINK_DEFINE_ERROR(NoNameServers); -static VARLINK_DEFINE_ERROR(NoSuchResourceRecord); -static VARLINK_DEFINE_ERROR(QueryTimedOut); -static VARLINK_DEFINE_ERROR(MaxAttemptsReached); -static VARLINK_DEFINE_ERROR(InvalidReply); -static VARLINK_DEFINE_ERROR(QueryAborted); -static VARLINK_DEFINE_ERROR( +static SD_VARLINK_DEFINE_ERROR(NoNameServers); +static SD_VARLINK_DEFINE_ERROR(NoSuchResourceRecord); +static SD_VARLINK_DEFINE_ERROR(QueryTimedOut); +static SD_VARLINK_DEFINE_ERROR(MaxAttemptsReached); +static SD_VARLINK_DEFINE_ERROR(InvalidReply); +static SD_VARLINK_DEFINE_ERROR(QueryAborted); +static SD_VARLINK_DEFINE_ERROR( DNSSECValidationFailed, - VARLINK_DEFINE_FIELD(result, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(extendedDNSErrorCode, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(extendedDNSErrorMessage, VARLINK_STRING, VARLINK_NULLABLE)); -static VARLINK_DEFINE_ERROR(NoTrustAnchor); -static VARLINK_DEFINE_ERROR(ResourceRecordTypeUnsupported); -static VARLINK_DEFINE_ERROR(NetworkDown); -static VARLINK_DEFINE_ERROR(NoSource); -static VARLINK_DEFINE_ERROR(StubLoop); -static VARLINK_DEFINE_ERROR( + SD_VARLINK_DEFINE_FIELD(result, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(extendedDNSErrorCode, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(extendedDNSErrorMessage, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); +static SD_VARLINK_DEFINE_ERROR(NoTrustAnchor); +static SD_VARLINK_DEFINE_ERROR(ResourceRecordTypeUnsupported); +static SD_VARLINK_DEFINE_ERROR(NetworkDown); +static SD_VARLINK_DEFINE_ERROR(NoSource); +static SD_VARLINK_DEFINE_ERROR(StubLoop); +static SD_VARLINK_DEFINE_ERROR( DNSError, - VARLINK_DEFINE_FIELD(rcode, VARLINK_INT, 0), - VARLINK_DEFINE_FIELD(extendedDNSErrorCode, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_FIELD(extendedDNSErrorMessage, VARLINK_STRING, VARLINK_NULLABLE)); -static VARLINK_DEFINE_ERROR(CNAMELoop); -static VARLINK_DEFINE_ERROR(BadAddressSize); -static VARLINK_DEFINE_ERROR(ResourceRecordTypeInvalidForQuery); -static VARLINK_DEFINE_ERROR(ZoneTransfersNotPermitted); -static VARLINK_DEFINE_ERROR(ResourceRecordTypeObsolete); + SD_VARLINK_DEFINE_FIELD(rcode, SD_VARLINK_INT, 0), + SD_VARLINK_DEFINE_FIELD(extendedDNSErrorCode, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_FIELD(extendedDNSErrorMessage, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); +static SD_VARLINK_DEFINE_ERROR(CNAMELoop); +static SD_VARLINK_DEFINE_ERROR(BadAddressSize); +static SD_VARLINK_DEFINE_ERROR(ResourceRecordTypeInvalidForQuery); +static SD_VARLINK_DEFINE_ERROR(ZoneTransfersNotPermitted); +static SD_VARLINK_DEFINE_ERROR(ResourceRecordTypeObsolete); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_Resolve, "io.systemd.Resolve", &vl_method_ResolveHostname, diff --git a/src/shared/varlink-io.systemd.Resolve.h b/src/shared/varlink-io.systemd.Resolve.h index 48a9241ef4..b7a828530d 100644 --- a/src/shared/varlink-io.systemd.Resolve.h +++ b/src/shared/varlink-io.systemd.Resolve.h @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkSymbol vl_type_ResourceKey; -extern const VarlinkSymbol vl_type_ResourceRecord; +extern const sd_varlink_symbol vl_type_ResourceKey; +extern const sd_varlink_symbol vl_type_ResourceRecord; -extern const VarlinkInterface vl_interface_io_systemd_Resolve; +extern const sd_varlink_interface vl_interface_io_systemd_Resolve; diff --git a/src/shared/varlink-io.systemd.UserDatabase.c b/src/shared/varlink-io.systemd.UserDatabase.c index c10a7d3eea..b714550f7d 100644 --- a/src/shared/varlink-io.systemd.UserDatabase.c +++ b/src/shared/varlink-io.systemd.UserDatabase.c @@ -2,38 +2,38 @@ #include "varlink-io.systemd.UserDatabase.h" -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( GetUserRecord, - VARLINK_DEFINE_INPUT(uid, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(userName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(service, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(record, VARLINK_OBJECT, 0), - VARLINK_DEFINE_OUTPUT(incomplete, VARLINK_BOOL, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT(uid, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(userName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(service, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(record, SD_VARLINK_OBJECT, 0), + SD_VARLINK_DEFINE_OUTPUT(incomplete, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( GetGroupRecord, - VARLINK_DEFINE_INPUT(gid, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(groupName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(service, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(record, VARLINK_OBJECT, 0), - VARLINK_DEFINE_OUTPUT(incomplete, VARLINK_BOOL, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT(gid, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(groupName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(service, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(record, SD_VARLINK_OBJECT, 0), + SD_VARLINK_DEFINE_OUTPUT(incomplete, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( GetMemberships, - VARLINK_DEFINE_INPUT(userName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(groupName, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(service, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(userName, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(groupName, VARLINK_STRING, 0)); + SD_VARLINK_DEFINE_INPUT(userName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(groupName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(service, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(userName, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(groupName, SD_VARLINK_STRING, 0)); -static VARLINK_DEFINE_ERROR(NoRecordFound); -static VARLINK_DEFINE_ERROR(BadService); -static VARLINK_DEFINE_ERROR(ServiceNotAvailable); -static VARLINK_DEFINE_ERROR(ConflictingRecordNotFound); -static VARLINK_DEFINE_ERROR(EnumerationNotSupported); +static SD_VARLINK_DEFINE_ERROR(NoRecordFound); +static SD_VARLINK_DEFINE_ERROR(BadService); +static SD_VARLINK_DEFINE_ERROR(ServiceNotAvailable); +static SD_VARLINK_DEFINE_ERROR(ConflictingRecordNotFound); +static SD_VARLINK_DEFINE_ERROR(EnumerationNotSupported); /* As per https://systemd.io/USER_GROUP_API/ */ -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_UserDatabase, "io.systemd.UserDatabase", &vl_method_GetUserRecord, diff --git a/src/shared/varlink-io.systemd.UserDatabase.h b/src/shared/varlink-io.systemd.UserDatabase.h index 346ca848ac..fd8389f125 100644 --- a/src/shared/varlink-io.systemd.UserDatabase.h +++ b/src/shared/varlink-io.systemd.UserDatabase.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_UserDatabase; +extern const sd_varlink_interface vl_interface_io_systemd_UserDatabase; diff --git a/src/shared/varlink-io.systemd.c b/src/shared/varlink-io.systemd.c deleted file mode 100644 index cdfe9ac263..0000000000 --- a/src/shared/varlink-io.systemd.c +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include "varlink-io.systemd.h" - -/* These are local errors that never cross the wire, and are our own invention */ -static VARLINK_DEFINE_ERROR(Disconnected); -static VARLINK_DEFINE_ERROR(TimedOut); -static VARLINK_DEFINE_ERROR(Protocol); - -/* This one we invented, and use for generically propagating system errors (errno) to clients */ -static VARLINK_DEFINE_ERROR( - System, - VARLINK_DEFINE_FIELD(errno, VARLINK_INT, 0)); - -VARLINK_DEFINE_INTERFACE( - io_systemd, - "io.systemd", - &vl_error_Disconnected, - &vl_error_TimedOut, - &vl_error_Protocol, - &vl_error_System); diff --git a/src/shared/varlink-io.systemd.h b/src/shared/varlink-io.systemd.h deleted file mode 100644 index 6c17c6c4c7..0000000000 --- a/src/shared/varlink-io.systemd.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include "varlink-idl.h" - -extern const VarlinkInterface vl_interface_io_systemd; diff --git a/src/shared/varlink-io.systemd.oom.c b/src/shared/varlink-io.systemd.oom.c index e1da3fa527..67beb6b780 100644 --- a/src/shared/varlink-io.systemd.oom.c +++ b/src/shared/varlink-io.systemd.oom.c @@ -7,18 +7,18 @@ * Compare with io.systemd.ManagedOOM where the client/server roles of the service manager and oomd are * swapped! */ -VARLINK_DEFINE_STRUCT_TYPE( +SD_VARLINK_DEFINE_STRUCT_TYPE( ControlGroup, - VARLINK_DEFINE_FIELD(mode, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(path, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(property, VARLINK_STRING, 0), - VARLINK_DEFINE_FIELD(limit, VARLINK_INT, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_FIELD(mode, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(property, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_FIELD(limit, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( ReportManagedOOMCGroups, - VARLINK_DEFINE_INPUT_BY_TYPE(cgroups, ControlGroup, VARLINK_ARRAY)); + SD_VARLINK_DEFINE_INPUT_BY_TYPE(cgroups, ControlGroup, SD_VARLINK_ARRAY)); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_oom, "io.systemd.oom", &vl_method_ReportManagedOOMCGroups, diff --git a/src/shared/varlink-io.systemd.oom.h b/src/shared/varlink-io.systemd.oom.h index 911dbc29e6..5964c49825 100644 --- a/src/shared/varlink-io.systemd.oom.h +++ b/src/shared/varlink-io.systemd.oom.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkSymbol vl_type_ControlGroup; -extern const VarlinkInterface vl_interface_io_systemd_oom; +extern const sd_varlink_symbol vl_type_ControlGroup; +extern const sd_varlink_interface vl_interface_io_systemd_oom; diff --git a/src/shared/varlink-io.systemd.service.c b/src/shared/varlink-io.systemd.service.c index 87479e3758..666778bd41 100644 --- a/src/shared/varlink-io.systemd.service.c +++ b/src/shared/varlink-io.systemd.service.c @@ -2,35 +2,36 @@ #include <unistd.h> +#include "macro.h" #include "varlink-io.systemd.service.h" -static VARLINK_DEFINE_METHOD(Ping); +static SD_VARLINK_DEFINE_METHOD(Ping); -static VARLINK_DEFINE_METHOD(Reload); +static SD_VARLINK_DEFINE_METHOD(Reload); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( SetLogLevel, - VARLINK_DEFINE_INPUT(level, VARLINK_INT, 0)); + SD_VARLINK_DEFINE_INPUT(level, SD_VARLINK_INT, 0)); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_service, "io.systemd.service", &vl_method_Ping, &vl_method_Reload, &vl_method_SetLogLevel); -int varlink_method_ping(Varlink *link, sd_json_variant *parameters, VarlinkMethodFlags flags, void *userdata) { +int varlink_method_ping(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { assert(link); if (sd_json_variant_elements(parameters) > 0) - return varlink_error_invalid_parameter(link, parameters); + return sd_varlink_error_invalid_parameter(link, parameters); log_debug("Received io.systemd.service.Ping"); - return varlink_reply(link, NULL); + return sd_varlink_reply(link, NULL); } -int varlink_method_set_log_level(Varlink *link, sd_json_variant *parameters, VarlinkMethodFlags flags, void *userdata) { +int varlink_method_set_log_level(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { static const sd_json_dispatch_field dispatch_table[] = { { "level", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int64, 0, SD_JSON_MANDATORY }, {} @@ -46,25 +47,25 @@ int varlink_method_set_log_level(Varlink *link, sd_json_variant *parameters, Var /* NOTE: The method does have 1 parameter, but we must compare to 2 here, because * sd_json_variant_elements() breaks abstraction and exposes internal structure of JsonObject. */ if (sd_json_variant_elements(parameters) != 2) - return varlink_error_invalid_parameter(link, parameters); + return sd_varlink_error_invalid_parameter(link, parameters); - r = varlink_dispatch(link, parameters, dispatch_table, &level); + r = sd_varlink_dispatch(link, parameters, dispatch_table, &level); if (r != 0) return r; if (LOG_PRI(level) != level) - return varlink_error_invalid_parameter(link, parameters); + return sd_varlink_error_invalid_parameter(link, parameters); - r = varlink_get_peer_uid(link, &uid); + r = sd_varlink_get_peer_uid(link, &uid); if (r < 0) return r; if (uid != getuid() && uid != 0) - return varlink_error(link, VARLINK_ERROR_PERMISSION_DENIED, parameters); + return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, parameters); log_debug("Received io.systemd.service.SetLogLevel(%" PRIi64 ")", level); log_set_max_level(level); - return varlink_reply(link, NULL); + return sd_varlink_reply(link, NULL); } diff --git a/src/shared/varlink-io.systemd.service.h b/src/shared/varlink-io.systemd.service.h index 6ea1a0f11b..3f164783f5 100644 --- a/src/shared/varlink-io.systemd.service.h +++ b/src/shared/varlink-io.systemd.service.h @@ -1,10 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink.h" -#include "varlink-idl.h" +#include "sd-varlink.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_service; +extern const sd_varlink_interface vl_interface_io_systemd_service; -int varlink_method_ping(Varlink *link, sd_json_variant *parameters, VarlinkMethodFlags flags, void *userdata); -int varlink_method_set_log_level(Varlink *link, sd_json_variant *parameters, VarlinkMethodFlags flags, void *userdata); +int varlink_method_ping(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); +int varlink_method_set_log_level(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); diff --git a/src/shared/varlink-io.systemd.sysext.c b/src/shared/varlink-io.systemd.sysext.c index 66e35341bc..b20afb2950 100644 --- a/src/shared/varlink-io.systemd.sysext.c +++ b/src/shared/varlink-io.systemd.sysext.c @@ -2,59 +2,59 @@ #include "varlink-io.systemd.sysext.h" -static VARLINK_DEFINE_ENUM_TYPE( +static SD_VARLINK_DEFINE_ENUM_TYPE( ImageClass, - VARLINK_DEFINE_ENUM_VALUE(sysext), - VARLINK_DEFINE_ENUM_VALUE(confext)); + SD_VARLINK_DEFINE_ENUM_VALUE(sysext), + SD_VARLINK_DEFINE_ENUM_VALUE(confext)); -static VARLINK_DEFINE_ENUM_TYPE( +static SD_VARLINK_DEFINE_ENUM_TYPE( ImageType, - VARLINK_DEFINE_ENUM_VALUE(directory), - VARLINK_DEFINE_ENUM_VALUE(subvolume), - VARLINK_DEFINE_ENUM_VALUE(raw), - VARLINK_DEFINE_ENUM_VALUE(block)); + SD_VARLINK_DEFINE_ENUM_VALUE(directory), + SD_VARLINK_DEFINE_ENUM_VALUE(subvolume), + SD_VARLINK_DEFINE_ENUM_VALUE(raw), + SD_VARLINK_DEFINE_ENUM_VALUE(block)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Merge, - VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(force, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(noReload, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(noexec, VARLINK_BOOL, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(force, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(noReload, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(noexec, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Unmerge, - VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(noReload, VARLINK_BOOL, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(noReload, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( Refresh, - VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(force, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(noReload, VARLINK_BOOL, VARLINK_NULLABLE), - VARLINK_DEFINE_INPUT(noexec, VARLINK_BOOL, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(force, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(noReload, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_INPUT(noexec, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_METHOD( +static SD_VARLINK_DEFINE_METHOD( List, - VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT_BY_TYPE(Class, ImageClass, 0), - VARLINK_DEFINE_OUTPUT_BY_TYPE(Type, ImageType, 0), - VARLINK_DEFINE_OUTPUT(Name, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(Path, VARLINK_STRING, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(ReadOnly, VARLINK_BOOL, 0), - VARLINK_DEFINE_OUTPUT(CreationTimestamp, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(ModificationTimestamp, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(Usage, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(UsageExclusive, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(Limit, VARLINK_INT, VARLINK_NULLABLE), - VARLINK_DEFINE_OUTPUT(LimitExclusive, VARLINK_INT, VARLINK_NULLABLE)); + SD_VARLINK_DEFINE_INPUT_BY_TYPE(class, ImageClass, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(Class, ImageClass, 0), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(Type, ImageType, 0), + SD_VARLINK_DEFINE_OUTPUT(Name, SD_VARLINK_STRING, 0), + SD_VARLINK_DEFINE_OUTPUT(Path, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(ReadOnly, SD_VARLINK_BOOL, 0), + SD_VARLINK_DEFINE_OUTPUT(CreationTimestamp, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(ModificationTimestamp, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(Usage, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(UsageExclusive, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(Limit, SD_VARLINK_INT, SD_VARLINK_NULLABLE), + SD_VARLINK_DEFINE_OUTPUT(LimitExclusive, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); -static VARLINK_DEFINE_ERROR(NoImagesFound); +static SD_VARLINK_DEFINE_ERROR(NoImagesFound); -static VARLINK_DEFINE_ERROR( +static SD_VARLINK_DEFINE_ERROR( AlreadyMerged, - VARLINK_DEFINE_FIELD(hierarchy, VARLINK_STRING, 0)); + SD_VARLINK_DEFINE_FIELD(hierarchy, SD_VARLINK_STRING, 0)); -VARLINK_DEFINE_INTERFACE( +SD_VARLINK_DEFINE_INTERFACE( io_systemd_sysext, "io.systemd.sysext", &vl_type_ImageClass, diff --git a/src/shared/varlink-io.systemd.sysext.h b/src/shared/varlink-io.systemd.sysext.h index ee649c68b5..16769bdee6 100644 --- a/src/shared/varlink-io.systemd.sysext.h +++ b/src/shared/varlink-io.systemd.sysext.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "varlink-idl.h" +#include "sd-varlink-idl.h" -extern const VarlinkInterface vl_interface_io_systemd_sysext; +extern const sd_varlink_interface vl_interface_io_systemd_sysext; diff --git a/src/shared/varlink-org.varlink.service.c b/src/shared/varlink-org.varlink.service.c deleted file mode 100644 index e5122c08be..0000000000 --- a/src/shared/varlink-org.varlink.service.c +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include "varlink-org.varlink.service.h" - -static VARLINK_DEFINE_METHOD( - GetInfo, - VARLINK_DEFINE_OUTPUT(vendor, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(product, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(version, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(url, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(interfaces, VARLINK_STRING, VARLINK_ARRAY)); - -static VARLINK_DEFINE_METHOD( - GetInterfaceDescription, - VARLINK_DEFINE_INPUT(interface, VARLINK_STRING, 0), - VARLINK_DEFINE_OUTPUT(description, VARLINK_STRING, 0)); - -static VARLINK_DEFINE_ERROR( - InterfaceNotFound, - VARLINK_DEFINE_FIELD(interface, VARLINK_STRING, 0)); - -static VARLINK_DEFINE_ERROR( - MethodNotFound, - VARLINK_DEFINE_FIELD(method, VARLINK_STRING, 0)); - -static VARLINK_DEFINE_ERROR( - MethodNotImplemented, - VARLINK_DEFINE_FIELD(method, VARLINK_STRING, 0)); - -static VARLINK_DEFINE_ERROR( - InvalidParameter, - VARLINK_DEFINE_FIELD(parameter, VARLINK_STRING, 0)); - -static VARLINK_DEFINE_ERROR(PermissionDenied); - -static VARLINK_DEFINE_ERROR(ExpectedMore); - -/* As per https://varlink.org/Service */ -VARLINK_DEFINE_INTERFACE( - org_varlink_service, - "org.varlink.service", - &vl_method_GetInfo, - &vl_method_GetInterfaceDescription, - &vl_error_InterfaceNotFound, - &vl_error_MethodNotFound, - &vl_error_MethodNotImplemented, - &vl_error_InvalidParameter, - &vl_error_PermissionDenied, - &vl_error_ExpectedMore); diff --git a/src/shared/varlink-org.varlink.service.h b/src/shared/varlink-org.varlink.service.h deleted file mode 100644 index 75c55e6e82..0000000000 --- a/src/shared/varlink-org.varlink.service.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include "varlink-idl.h" - -extern const VarlinkInterface vl_interface_org_varlink_service; diff --git a/src/shared/varlink-serialize.c b/src/shared/varlink-serialize.c new file mode 100644 index 0000000000..422808df39 --- /dev/null +++ b/src/shared/varlink-serialize.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "parse-util.h" +#include "varlink-internal.h" +#include "varlink-serialize.h" + +int varlink_server_serialize(sd_varlink_server *s, FILE *f, FDSet *fds) { + assert(f); + assert(fds); + + if (!s) + return 0; + + LIST_FOREACH(sockets, ss, s->sockets) { + int copy; + + assert(ss->address); + assert(ss->fd >= 0); + + fprintf(f, "varlink-server-socket-address=%s", ss->address); + + /* If we fail to serialize the fd, it will be considered an error during deserialization */ + copy = fdset_put_dup(fds, ss->fd); + if (copy < 0) + return copy; + + fprintf(f, " varlink-server-socket-fd=%i", copy); + + fputc('\n', f); + } + + return 0; +} + +int varlink_server_deserialize_one(sd_varlink_server *s, const char *value, FDSet *fds) { + _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL; + _cleanup_free_ char *address = NULL; + const char *v = ASSERT_PTR(value); + int r, fd = -EBADF; + char *buf; + size_t n; + + assert(s); + assert(fds); + + n = strcspn(v, " "); + address = strndup(v, n); + if (!address) + return log_oom_debug(); + + if (v[n] != ' ') + return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EINVAL), + "Failed to deserialize sd_varlink_server_socket: %s: %m", value); + v = startswith(v + n + 1, "varlink-server-socket-fd="); + if (!v) + return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EINVAL), + "Failed to deserialize VarlinkServerSocket fd %s: %m", value); + + n = strcspn(v, " "); + buf = strndupa_safe(v, n); + + fd = parse_fd(buf); + if (fd < 0) + return varlink_server_log_errno(s, fd, "Unable to parse VarlinkServerSocket varlink-server-socket-fd=%s: %m", buf); + if (!fdset_contains(fds, fd)) + return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EBADF), + "VarlinkServerSocket varlink-server-socket-fd= has unknown fd %d: %m", fd); + + ss = new(VarlinkServerSocket, 1); + if (!ss) + return log_oom_debug(); + + *ss = (VarlinkServerSocket) { + .server = s, + .address = TAKE_PTR(address), + .fd = fdset_remove(fds, fd), + }; + + r = varlink_server_add_socket_event_source(s, ss, SD_EVENT_PRIORITY_NORMAL); + if (r < 0) + return varlink_server_log_errno(s, r, "Failed to add VarlinkServerSocket event source to the event loop: %m"); + + LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss)); + return 0; +} diff --git a/src/shared/varlink-serialize.h b/src/shared/varlink-serialize.h new file mode 100644 index 0000000000..149aa88b11 --- /dev/null +++ b/src/shared/varlink-serialize.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <stdio.h> + +#include "sd-varlink.h" + +#include "fdset.h" + +int varlink_server_serialize(sd_varlink_server *s, FILE *f, FDSet *fds); +int varlink_server_deserialize_one(sd_varlink_server *s, const char *value, FDSet *fds); diff --git a/src/shared/varlink.c b/src/shared/varlink.c deleted file mode 100644 index 35879e3872..0000000000 --- a/src/shared/varlink.c +++ /dev/null @@ -1,4494 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include <malloc.h> -#include <poll.h> - -#include <sd-daemon.h> - -#include "alloc-util.h" -#include "errno-util.h" -#include "escape.h" -#include "fd-util.h" -#include "glyph-util.h" -#include "hashmap.h" -#include "io-util.h" -#include "iovec-util.h" -#include "json-util.h" -#include "list.h" -#include "path-util.h" -#include "process-util.h" -#include "selinux-util.h" -#include "serialize.h" -#include "set.h" -#include "socket-util.h" -#include "string-table.h" -#include "string-util.h" -#include "strv.h" -#include "time-util.h" -#include "umask-util.h" -#include "user-util.h" -#include "varlink.h" -#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 - -#define VARLINK_DEFAULT_TIMEOUT_USEC (45U*USEC_PER_SEC) -#define VARLINK_BUFFER_MAX (16U*1024U*1024U) -#define VARLINK_READ_SIZE (64U*1024U) -#define VARLINK_COLLECT_MAX 1024U - -typedef enum VarlinkState { - /* Client side states */ - VARLINK_IDLE_CLIENT, - VARLINK_AWAITING_REPLY, - VARLINK_AWAITING_REPLY_MORE, - VARLINK_CALLING, - VARLINK_CALLED, - VARLINK_COLLECTING, - VARLINK_COLLECTING_REPLY, - VARLINK_PROCESSING_REPLY, - - /* Server side states */ - VARLINK_IDLE_SERVER, - VARLINK_PROCESSING_METHOD, - VARLINK_PROCESSING_METHOD_MORE, - VARLINK_PROCESSING_METHOD_ONEWAY, - VARLINK_PROCESSED_METHOD, - VARLINK_PENDING_METHOD, - VARLINK_PENDING_METHOD_MORE, - - /* Common states (only during shutdown) */ - VARLINK_PENDING_DISCONNECT, - VARLINK_PENDING_TIMEOUT, - VARLINK_PROCESSING_DISCONNECT, - VARLINK_PROCESSING_TIMEOUT, - VARLINK_PROCESSING_FAILURE, - VARLINK_DISCONNECTED, - - _VARLINK_STATE_MAX, - _VARLINK_STATE_INVALID = -EINVAL, -} VarlinkState; - -/* Tests whether we are not yet disconnected. Note that this is true during all states where the connection - * is still good for something, and false only when it's dead for good. This means: when we are - * asynchronously connecting to a peer and the connect() is still pending, then this will return 'true', as - * the connection is still good, and we are likely to be able to properly operate on it soon. */ -#define VARLINK_STATE_IS_ALIVE(state) \ - IN_SET(state, \ - VARLINK_IDLE_CLIENT, \ - VARLINK_AWAITING_REPLY, \ - VARLINK_AWAITING_REPLY_MORE, \ - VARLINK_CALLING, \ - VARLINK_CALLED, \ - VARLINK_COLLECTING, \ - VARLINK_COLLECTING_REPLY, \ - VARLINK_PROCESSING_REPLY, \ - VARLINK_IDLE_SERVER, \ - VARLINK_PROCESSING_METHOD, \ - VARLINK_PROCESSING_METHOD_MORE, \ - VARLINK_PROCESSING_METHOD_ONEWAY, \ - VARLINK_PROCESSED_METHOD, \ - VARLINK_PENDING_METHOD, \ - VARLINK_PENDING_METHOD_MORE) - -typedef struct VarlinkJsonQueueItem VarlinkJsonQueueItem; - -/* A queued message we shall write into the socket, along with the file descriptors to send at the same - * time. This queue item binds them together so that message/fd boundaries are maintained throughout the - * whole pipeline. */ -struct VarlinkJsonQueueItem { - LIST_FIELDS(VarlinkJsonQueueItem, queue); - sd_json_variant *data; - size_t n_fds; - int fds[]; -}; - -struct Varlink { - unsigned n_ref; - - VarlinkServer *server; - - VarlinkState state; - bool connecting; /* This boolean indicates whether the socket fd we are operating on is currently - * processing an asynchronous connect(). In that state we watch the socket for - * EPOLLOUT, but we refrain from calling read() or write() on the socket as that - * will trigger ENOTCONN. Note that this boolean is kept separate from the - * VarlinkState above on purpose: while the connect() is still not complete we - * already want to allow queuing of messages and similar. Thus it's nice to keep - * these two state concepts separate: the VarlinkState encodes what our own view of - * the connection is, i.e. whether we think it's a server, a client, and has - * something queued already, while 'connecting' tells us a detail about the - * transport used below, that should have no effect on how we otherwise accept and - * process operations from the user. - * - * Or to say this differently: VARLINK_STATE_IS_ALIVE(state) tells you whether the - * connection is good to use, even if it might not be fully connected - * yet. connecting=true then informs you that actually we are still connecting, and - * the connection is actually not established yet and thus any requests you enqueue - * now will still work fine but will be queued only, not sent yet, but that - * shouldn't stop you from using the connection, since eventually whatever you queue - * *will* be sent. - * - * Or to say this even differently: 'state' is a high-level ("application layer" - * high, if you so will) state, while 'conecting' is a low-level ("transport layer" - * low, if you so will) state, and while they are not entirely unrelated and - * sometimes propagate effects to each other they are only asynchronously connected - * at most. */ - unsigned n_pending; - - int input_fd; - int output_fd; - - char *input_buffer; /* valid data starts at input_buffer_index, ends at input_buffer_index+input_buffer_size */ - size_t input_buffer_index; - size_t input_buffer_size; - size_t input_buffer_unscanned; - - void *input_control_buffer; - size_t input_control_buffer_size; - - char *output_buffer; /* valid data starts at output_buffer_index, ends at output_buffer_index+output_buffer_size */ - size_t output_buffer_index; - size_t output_buffer_size; - - int *input_fds; /* file descriptors associated with the data in input_buffer (for fd passing) */ - size_t n_input_fds; - - int *output_fds; /* file descriptors associated with the data in output_buffer (for fd passing) */ - size_t n_output_fds; - - /* Further messages to output not yet formatted into text, and thus not included in output_buffer - * yet. We keep them separate from output_buffer, to not violate fd message boundaries: we want that - * each fd that is sent is associated with its fds, and that fds cannot be accidentally associated - * with preceding or following messages. */ - LIST_HEAD(VarlinkJsonQueueItem, output_queue); - VarlinkJsonQueueItem *output_queue_tail; - - /* The fds to associate with the next message that is about to be enqueued. The user first pushes the - * fds it intends to send via varlink_push_fd() into this queue, and then once the message data is - * submitted we'll combine the fds and the message data into one. */ - int *pushed_fds; - size_t n_pushed_fds; - - VarlinkReply reply_callback; - - sd_json_variant *current; - sd_json_variant *current_collected; - VarlinkReplyFlags current_reply_flags; - VarlinkSymbol *current_method; - - int peer_pidfd; - struct ucred ucred; - bool ucred_acquired:1; - - bool write_disconnected:1; - bool read_disconnected:1; - bool prefer_read:1; - bool prefer_write:1; - bool got_pollhup:1; - - bool allow_fd_passing_input:1; - bool allow_fd_passing_output:1; - - bool output_buffer_sensitive:1; /* whether to erase the output buffer after writing it to the socket */ - bool input_sensitive:1; /* Whether incoming messages might be sensitive */ - - int af; /* address family if socket; AF_UNSPEC if not socket; negative if not known */ - - usec_t timestamp; - usec_t timeout; - - void *userdata; - char *description; - - sd_event *event; - sd_event_source *input_event_source; - sd_event_source *output_event_source; - sd_event_source *time_event_source; - sd_event_source *quit_event_source; - sd_event_source *defer_event_source; - - pid_t exec_pid; -}; - -typedef struct VarlinkServerSocket VarlinkServerSocket; - -struct VarlinkServerSocket { - VarlinkServer *server; - - int fd; - char *address; - - sd_event_source *event_source; - - LIST_FIELDS(VarlinkServerSocket, sockets); -}; - -struct VarlinkServer { - unsigned n_ref; - VarlinkServerFlags flags; - - LIST_HEAD(VarlinkServerSocket, sockets); - - Hashmap *methods; /* Fully qualified symbol name of a method → VarlinkMethod */ - Hashmap *interfaces; /* Fully qualified interface name → VarlinkInterface* */ - Hashmap *symbols; /* Fully qualified symbol name of method/error → VarlinkSymbol* */ - VarlinkConnect connect_callback; - VarlinkDisconnect disconnect_callback; - - sd_event *event; - int64_t event_priority; - - unsigned n_connections; - Hashmap *by_uid; /* UID_TO_PTR(uid) → UINT_TO_PTR(n_connections) */ - - void *userdata; - char *description; - - unsigned connections_max; - unsigned connections_per_uid_max; - - bool exit_on_idle; -}; - -static const char* const varlink_state_table[_VARLINK_STATE_MAX] = { - [VARLINK_IDLE_CLIENT] = "idle-client", - [VARLINK_AWAITING_REPLY] = "awaiting-reply", - [VARLINK_AWAITING_REPLY_MORE] = "awaiting-reply-more", - [VARLINK_CALLING] = "calling", - [VARLINK_CALLED] = "called", - [VARLINK_COLLECTING] = "collecting", - [VARLINK_COLLECTING_REPLY] = "collecting-reply", - [VARLINK_PROCESSING_REPLY] = "processing-reply", - [VARLINK_IDLE_SERVER] = "idle-server", - [VARLINK_PROCESSING_METHOD] = "processing-method", - [VARLINK_PROCESSING_METHOD_MORE] = "processing-method-more", - [VARLINK_PROCESSING_METHOD_ONEWAY] = "processing-method-oneway", - [VARLINK_PROCESSED_METHOD] = "processed-method", - [VARLINK_PENDING_METHOD] = "pending-method", - [VARLINK_PENDING_METHOD_MORE] = "pending-method-more", - [VARLINK_PENDING_DISCONNECT] = "pending-disconnect", - [VARLINK_PENDING_TIMEOUT] = "pending-timeout", - [VARLINK_PROCESSING_DISCONNECT] = "processing-disconnect", - [VARLINK_PROCESSING_TIMEOUT] = "processing-timeout", - [VARLINK_PROCESSING_FAILURE] = "processing-failure", - [VARLINK_DISCONNECTED] = "disconnected", -}; - -DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(varlink_state, VarlinkState); - -#define varlink_log_errno(v, error, fmt, ...) \ - log_debug_errno(error, "%s: " fmt, varlink_description(v), ##__VA_ARGS__) - -#define varlink_log(v, fmt, ...) \ - log_debug("%s: " fmt, varlink_description(v), ##__VA_ARGS__) - -#define varlink_server_log_errno(s, error, fmt, ...) \ - log_debug_errno(error, "%s: " fmt, varlink_server_description(s), ##__VA_ARGS__) - -#define varlink_server_log(s, fmt, ...) \ - log_debug("%s: " fmt, varlink_server_description(s), ##__VA_ARGS__) - -static int varlink_format_queue(Varlink *v); -static void varlink_server_test_exit_on_idle(VarlinkServer *s); - -static const char *varlink_description(Varlink *v) { - return (v ? v->description : NULL) ?: "varlink"; -} - -static const char *varlink_server_description(VarlinkServer *s) { - return (s ? s->description : NULL) ?: "varlink"; -} - -static VarlinkJsonQueueItem *varlink_json_queue_item_free(VarlinkJsonQueueItem *q) { - if (!q) - return NULL; - - sd_json_variant_unref(q->data); - close_many(q->fds, q->n_fds); - - return mfree(q); -} - -static VarlinkJsonQueueItem *varlink_json_queue_item_new(sd_json_variant *m, const int fds[], size_t n_fds) { - VarlinkJsonQueueItem *q; - - assert(m); - assert(fds || n_fds == 0); - - q = malloc(offsetof(VarlinkJsonQueueItem, fds) + sizeof(int) * n_fds); - if (!q) - return NULL; - - *q = (VarlinkJsonQueueItem) { - .data = sd_json_variant_ref(m), - .n_fds = n_fds, - }; - - memcpy_safe(q->fds, fds, n_fds * sizeof(int)); - - return TAKE_PTR(q); -} - -static void varlink_set_state(Varlink *v, VarlinkState state) { - assert(v); - assert(state >= 0 && state < _VARLINK_STATE_MAX); - - if (v->state < 0) - varlink_log(v, "Setting state %s", - varlink_state_to_string(state)); - else - varlink_log(v, "Changing state %s %s %s", - varlink_state_to_string(v->state), - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), - varlink_state_to_string(state)); - - v->state = state; -} - -static int varlink_new(Varlink **ret) { - Varlink *v; - - assert(ret); - - v = new(Varlink, 1); - if (!v) - return -ENOMEM; - - *v = (Varlink) { - .n_ref = 1, - .input_fd = -EBADF, - .output_fd = -EBADF, - - .state = _VARLINK_STATE_INVALID, - - .ucred = UCRED_INVALID, - - .timestamp = USEC_INFINITY, - .timeout = VARLINK_DEFAULT_TIMEOUT_USEC, - - .af = -1, - - .peer_pidfd = -EBADF, - }; - - *ret = v; - return 0; -} - -int varlink_connect_address(Varlink **ret, const char *address) { - _cleanup_(varlink_unrefp) Varlink *v = NULL; - union sockaddr_union sockaddr; - int r; - - assert_return(ret, -EINVAL); - assert_return(address, -EINVAL); - - r = varlink_new(&v); - if (r < 0) - return log_debug_errno(r, "Failed to create varlink object: %m"); - - v->input_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - if (v->input_fd < 0) - return log_debug_errno(errno, "Failed to create AF_UNIX socket: %m"); - - v->output_fd = v->input_fd = fd_move_above_stdio(v->input_fd); - v->af = AF_UNIX; - - r = sockaddr_un_set_path(&sockaddr.un, address); - if (r < 0) { - if (r != -ENAMETOOLONG) - return log_debug_errno(r, "Failed to set socket address '%s': %m", address); - - /* This is a file system path, and too long to fit into sockaddr_un. Let's connect via O_PATH - * to this socket. */ - - r = connect_unix_path(v->input_fd, AT_FDCWD, address); - } else - r = RET_NERRNO(connect(v->input_fd, &sockaddr.sa, r)); - - if (r < 0) { - if (!IN_SET(r, -EAGAIN, -EINPROGRESS)) - return log_debug_errno(r, "Failed to connect to %s: %m", address); - - v->connecting = true; /* We are asynchronously connecting, i.e. the connect() is being - * processed in the background. As long as that's the case the socket - * is in a special state: it's there, we can poll it for EPOLLOUT, but - * if we attempt to write() to it before we see EPOLLOUT we'll get - * ENOTCONN (and not EAGAIN, like we would for a normal connected - * socket that isn't writable at the moment). Since ENOTCONN on write() - * hence can mean two different things (i.e. connection not complete - * yet vs. already disconnected again), we store as a boolean whether - * we are still in connect(). */ - } - - varlink_set_state(v, VARLINK_IDLE_CLIENT); - - *ret = TAKE_PTR(v); - return 0; -} - -int varlink_connect_exec(Varlink **ret, const char *_command, char **_argv) { - _cleanup_close_pair_ int pair[2] = EBADF_PAIR; - _cleanup_(sigkill_waitp) pid_t pid = 0; - _cleanup_free_ char *command = NULL; - _cleanup_strv_free_ char **argv = NULL; - int r; - - assert_return(ret, -EINVAL); - assert_return(_command, -EINVAL); - - /* Copy the strings, in case they point into our own argv[], which we'll invalidate shortly because - * we rename the child process */ - command = strdup(_command); - if (!command) - return -ENOMEM; - - if (strv_isempty(_argv)) - argv = strv_new(command); - else - argv = strv_copy(_argv); - if (!argv) - return -ENOMEM; - - log_debug("Forking off Varlink child process '%s'.", command); - - if (socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, pair) < 0) - return log_debug_errno(errno, "Failed to allocate AF_UNIX socket pair: %m"); - - r = fd_nonblock(pair[1], false); - if (r < 0) - return log_debug_errno(r, "Failed to disable O_NONBLOCK for varlink socket: %m"); - - r = safe_fork_full( - "(sd-vlexec)", - /* stdio_fds= */ NULL, - /* except_fds= */ (int[]) { pair[1] }, - /* n_except_fds= */ 1, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, - &pid); - if (r < 0) - return log_debug_errno(r, "Failed to spawn process: %m"); - if (r == 0) { - char spid[DECIMAL_STR_MAX(pid_t)+1]; - const char *setenv_list[] = { - "LISTEN_FDS", "1", - "LISTEN_PID", spid, - "LISTEN_FDNAMES", "varlink", - NULL, NULL, - }; - /* Child */ - - pair[0] = -EBADF; - - r = move_fd(pair[1], 3, /* cloexec= */ false); - if (r < 0) { - log_debug_errno(r, "Failed to move file descriptor to 3: %m"); - _exit(EXIT_FAILURE); - } - - xsprintf(spid, PID_FMT, pid); - - STRV_FOREACH_PAIR(a, b, setenv_list) { - if (setenv(*a, *b, /* override= */ true) < 0) { - log_debug_errno(errno, "Failed to set environment variable '%s': %m", *a); - _exit(EXIT_FAILURE); - } - } - - execvp(command, argv); - log_debug_errno(r, "Failed to invoke process '%s': %m", command); - _exit(EXIT_FAILURE); - } - - pair[1] = safe_close(pair[1]); - - Varlink *v; - r = varlink_new(&v); - if (r < 0) - return log_debug_errno(r, "Failed to create varlink object: %m"); - - v->output_fd = v->input_fd = TAKE_FD(pair[0]); - v->af = AF_UNIX; - v->exec_pid = TAKE_PID(pid); - varlink_set_state(v, VARLINK_IDLE_CLIENT); - - *ret = v; - return 0; -} - -static int ssh_path(const char **ret) { - assert(ret); - - const char *ssh = secure_getenv("SYSTEMD_SSH") ?: "ssh"; - if (!path_is_valid(ssh)) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "SSH path is not valid, refusing: %s", ssh); - - *ret = ssh; - return 0; -} - -static int varlink_connect_ssh_unix(Varlink **ret, const char *where) { - _cleanup_close_pair_ int pair[2] = EBADF_PAIR; - _cleanup_(sigkill_waitp) pid_t pid = 0; - int r; - - assert_return(ret, -EINVAL); - assert_return(where, -EINVAL); - - /* Connects to an SSH server via OpenSSH 9.4's -W switch to connect to a remote AF_UNIX socket. For - * now we do not expose this function directly, but only via varlink_connect_url(). */ - - const char *ssh; - r = ssh_path(&ssh); - if (r < 0) - return r; - - const char *e = strchr(where, ':'); - if (!e) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "SSH specification lacks a : separator between host and path, refusing: %s", where); - - _cleanup_free_ char *h = strndup(where, e - where); - if (!h) - return log_oom_debug(); - - _cleanup_free_ char *c = strdup(e + 1); - if (!c) - return log_oom_debug(); - - if (!path_is_absolute(c)) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Remote AF_UNIX socket path is not absolute, refusing: %s", c); - - _cleanup_free_ char *p = NULL; - r = path_simplify_alloc(c, &p); - if (r < 0) - return r; - - if (!path_is_normalized(p)) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Specified path is not normalized, refusing: %s", p); - - log_debug("Forking off SSH child process '%s -W %s %s'.", ssh, p, h); - - if (socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, pair) < 0) - return log_debug_errno(errno, "Failed to allocate AF_UNIX socket pair: %m"); - - r = safe_fork_full( - "(sd-vlssh)", - /* stdio_fds= */ (int[]) { pair[1], pair[1], STDERR_FILENO }, - /* except_fds= */ NULL, - /* n_except_fds= */ 0, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO, - &pid); - if (r < 0) - return log_debug_errno(r, "Failed to spawn process: %m"); - if (r == 0) { - /* Child */ - - execlp(ssh, "ssh", "-W", p, h, NULL); - log_debug_errno(errno, "Failed to invoke %s: %m", ssh); - _exit(EXIT_FAILURE); - } - - pair[1] = safe_close(pair[1]); - - Varlink *v; - r = varlink_new(&v); - if (r < 0) - return log_debug_errno(r, "Failed to create varlink object: %m"); - - v->output_fd = v->input_fd = TAKE_FD(pair[0]); - v->af = AF_UNIX; - v->exec_pid = TAKE_PID(pid); - varlink_set_state(v, VARLINK_IDLE_CLIENT); - - *ret = v; - return 0; -} - -static int varlink_connect_ssh_exec(Varlink **ret, const char *where) { - _cleanup_close_pair_ int input_pipe[2] = EBADF_PAIR, output_pipe[2] = EBADF_PAIR; - _cleanup_(sigkill_waitp) pid_t pid = 0; - int r; - - assert_return(ret, -EINVAL); - assert_return(where, -EINVAL); - - /* Connects to an SSH server to connect to a remote process' stdin/stdout. For now we do not expose - * this function directly, but only via varlink_connect_url(). */ - - const char *ssh; - r = ssh_path(&ssh); - if (r < 0) - return r; - - const char *e = strchr(where, ':'); - if (!e) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "SSH specification lacks a : separator between host and path, refusing: %s", where); - - _cleanup_free_ char *h = strndup(where, e - where); - if (!h) - return log_oom_debug(); - - _cleanup_strv_free_ char **cmdline = NULL; - r = strv_split_full(&cmdline, e + 1, /* separators= */ NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE); - if (r < 0) - return log_debug_errno(r, "Failed to split command line: %m"); - if (strv_isempty(cmdline)) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Remote command line is empty, refusing."); - - _cleanup_strv_free_ char **full_cmdline = NULL; - full_cmdline = strv_new("ssh", "-e", "none", "-T", h, "env", "SYSTEMD_VARLINK_LISTEN=-"); - if (!full_cmdline) - return log_oom_debug(); - r = strv_extend_strv(&full_cmdline, cmdline, /* filter_duplicates= */ false); - if (r < 0) - return log_oom_debug(); - - _cleanup_free_ char *j = NULL; - j = quote_command_line(full_cmdline, SHELL_ESCAPE_EMPTY); - if (!j) - return log_oom_debug(); - - log_debug("Forking off SSH child process: %s", j); - - if (pipe2(input_pipe, O_CLOEXEC) < 0) - return log_debug_errno(errno, "Failed to allocate input pipe: %m"); - if (pipe2(output_pipe, O_CLOEXEC) < 0) - return log_debug_errno(errno, "Failed to allocate output pipe: %m"); - - r = safe_fork_full( - "(sd-vlssh)", - /* stdio_fds= */ (int[]) { input_pipe[0], output_pipe[1], STDERR_FILENO }, - /* except_fds= */ NULL, - /* n_except_fds= */ 0, - FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REARRANGE_STDIO, - &pid); - if (r < 0) - return log_debug_errno(r, "Failed to spawn process: %m"); - if (r == 0) { - /* Child */ - execvp(ssh, full_cmdline); - log_debug_errno(errno, "Failed to invoke %s: %m", j); - _exit(EXIT_FAILURE); - } - - input_pipe[0] = safe_close(input_pipe[0]); - output_pipe[1] = safe_close(output_pipe[1]); - - r = fd_nonblock(input_pipe[1], true); - if (r < 0) - return log_debug_errno(r, "Failed to make input pipe non-blocking: %m"); - - r = fd_nonblock(output_pipe[0], true); - if (r < 0) - return log_debug_errno(r, "Failed to make output pipe non-blocking: %m"); - - Varlink *v; - r = varlink_new(&v); - if (r < 0) - return log_debug_errno(r, "Failed to create varlink object: %m"); - - v->input_fd = TAKE_FD(output_pipe[0]); - v->output_fd = TAKE_FD(input_pipe[1]); - v->af = AF_UNSPEC; - v->exec_pid = TAKE_PID(pid); - varlink_set_state(v, VARLINK_IDLE_CLIENT); - - *ret = v; - return 0; -} - -int varlink_connect_url(Varlink **ret, const char *url) { - _cleanup_free_ char *c = NULL; - const char *p; - enum { - SCHEME_UNIX, - SCHEME_EXEC, - SCHEME_SSH_UNIX, - SCHEME_SSH_EXEC, - } scheme; - int r; - - assert_return(ret, -EINVAL); - assert_return(url, -EINVAL); - - // FIXME: Maybe add support for vsock: and ssh-exec: URL schemes here. - - /* The Varlink URL scheme is a bit underdefined. We support only the spec-defined unix: transport for - * now, plus exec:, ssh: transports we made up ourselves. Strictly speaking this shouldn't even be - * called "URL", since it has nothing to do with Internet URLs by RFC. */ - - p = startswith(url, "unix:"); - if (p) - scheme = SCHEME_UNIX; - else if ((p = startswith(url, "exec:"))) - scheme = SCHEME_EXEC; - else if ((p = STARTSWITH_SET(url, "ssh:", "ssh-unix:"))) - scheme = SCHEME_SSH_UNIX; - else if ((p = startswith(url, "ssh-exec:"))) - scheme = SCHEME_SSH_EXEC; - else - return log_debug_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "URL scheme not supported."); - - /* The varlink.org reference C library supports more than just file system paths. We might want to - * support that one day too. For now simply refuse that. */ - if (p[strcspn(p, ";?#")] != '\0') - return log_debug_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "URL parameterization with ';', '?', '#' not supported."); - - if (scheme == SCHEME_SSH_UNIX) - return varlink_connect_ssh_unix(ret, p); - if (scheme == SCHEME_SSH_EXEC) - return varlink_connect_ssh_exec(ret, p); - - if (scheme == SCHEME_EXEC || p[0] != '@') { /* no path validity checks for abstract namespace sockets */ - - if (!path_is_absolute(p)) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Specified path not absolute, refusing."); - - r = path_simplify_alloc(p, &c); - if (r < 0) - return r; - - if (!path_is_normalized(c)) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Specified path is not normalized, refusing."); - } - - if (scheme == SCHEME_EXEC) - return varlink_connect_exec(ret, c, NULL); - - return varlink_connect_address(ret, c ?: p); -} - -int varlink_connect_fd_pair(Varlink **ret, int input_fd, int output_fd, const struct ucred *override_ucred) { - Varlink *v; - int r; - - assert_return(ret, -EINVAL); - assert_return(input_fd >= 0, -EBADF); - assert_return(output_fd >= 0, -EBADF); - - r = fd_nonblock(input_fd, true); - if (r < 0) - return log_debug_errno(r, "Failed to make input fd %d nonblocking: %m", input_fd); - - if (input_fd != output_fd) { - r = fd_nonblock(output_fd, true); - if (r < 0) - return log_debug_errno(r, "Failed to make output fd %d nonblocking: %m", output_fd); - } - - r = varlink_new(&v); - if (r < 0) - return log_debug_errno(r, "Failed to create varlink object: %m"); - - v->input_fd = input_fd; - v->output_fd = output_fd; - v->af = -1; - - if (override_ucred) { - v->ucred = *override_ucred; - v->ucred_acquired = true; - } - - varlink_set_state(v, VARLINK_IDLE_CLIENT); - - /* Note that if this function is called we assume the passed socket (if it is one) is already - * properly connected, i.e. any asynchronous connect() done on it already completed. Because of that - * we'll not set the 'connecting' boolean here, i.e. we don't need to avoid write()ing to the socket - * until the connection is fully set up. Behaviour here is hence a bit different from - * varlink_connect_address() above, as there we do handle asynchronous connections ourselves and - * avoid doing write() on it before we saw EPOLLOUT for the first time. */ - - *ret = v; - return 0; -} - -int varlink_connect_fd(Varlink **ret, int fd) { - return varlink_connect_fd_pair(ret, fd, fd, /* override_ucred= */ NULL); -} - -static void varlink_detach_event_sources(Varlink *v) { - assert(v); - - v->input_event_source = sd_event_source_disable_unref(v->input_event_source); - v->output_event_source = sd_event_source_disable_unref(v->output_event_source); - v->time_event_source = sd_event_source_disable_unref(v->time_event_source); - v->quit_event_source = sd_event_source_disable_unref(v->quit_event_source); - v->defer_event_source = sd_event_source_disable_unref(v->defer_event_source); -} - -static void varlink_clear_current(Varlink *v) { - assert(v); - - /* Clears the currently processed incoming message */ - v->current = sd_json_variant_unref(v->current); - v->current_collected = sd_json_variant_unref(v->current_collected); - v->current_method = NULL; - v->current_reply_flags = 0; - - close_many(v->input_fds, v->n_input_fds); - v->input_fds = mfree(v->input_fds); - v->n_input_fds = 0; -} - -static void varlink_clear(Varlink *v) { - assert(v); - - varlink_detach_event_sources(v); - - if (v->input_fd != v->output_fd) { - v->input_fd = safe_close(v->input_fd); - v->output_fd = safe_close(v->output_fd); - } else - v->output_fd = v->input_fd = safe_close(v->input_fd); - - varlink_clear_current(v); - - v->input_buffer = v->input_sensitive ? erase_and_free(v->input_buffer) : mfree(v->input_buffer); - v->output_buffer = v->output_buffer_sensitive ? erase_and_free(v->output_buffer) : mfree(v->output_buffer); - - v->input_control_buffer = mfree(v->input_control_buffer); - v->input_control_buffer_size = 0; - - close_many(v->output_fds, v->n_output_fds); - v->output_fds = mfree(v->output_fds); - v->n_output_fds = 0; - - close_many(v->pushed_fds, v->n_pushed_fds); - v->pushed_fds = mfree(v->pushed_fds); - v->n_pushed_fds = 0; - - LIST_CLEAR(queue, v->output_queue, varlink_json_queue_item_free); - v->output_queue_tail = NULL; - - v->event = sd_event_unref(v->event); - - if (v->exec_pid > 0) { - sigterm_wait(v->exec_pid); - v->exec_pid = 0; - } - - v->peer_pidfd = safe_close(v->peer_pidfd); -} - -static Varlink* varlink_destroy(Varlink *v) { - if (!v) - return NULL; - - /* If this is called the server object must already been unreffed here. Why that? because when we - * linked up the varlink connection with the server object we took one ref in each direction */ - assert(!v->server); - - varlink_clear(v); - - free(v->description); - return mfree(v); -} - -DEFINE_TRIVIAL_REF_UNREF_FUNC(Varlink, varlink, varlink_destroy); - -static int varlink_test_disconnect(Varlink *v) { - assert(v); - - /* Tests whether we the connection has been terminated. We are careful to not stop processing it - * prematurely, since we want to handle half-open connections as well as possible and want to flush - * out and read data before we close down if we can. */ - - /* Already disconnected? */ - if (!VARLINK_STATE_IS_ALIVE(v->state)) - return 0; - - /* Wait until connection setup is complete, i.e. until asynchronous connect() completes */ - if (v->connecting) - return 0; - - /* Still something to write and we can write? Stay around */ - if (v->output_buffer_size > 0 && !v->write_disconnected) - return 0; - - /* Both sides gone already? Then there's no need to stick around */ - if (v->read_disconnected && v->write_disconnected) - goto disconnect; - - /* If we are waiting for incoming data but the read side is shut down, disconnect. */ - if (IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_AWAITING_REPLY_MORE, VARLINK_CALLING, VARLINK_COLLECTING, VARLINK_IDLE_SERVER) && v->read_disconnected) - goto disconnect; - - /* Similar, if are a client that hasn't written anything yet but the write side is dead, also - * disconnect. We also explicitly check for POLLHUP here since we likely won't notice the write side - * being down if we never wrote anything. */ - if (v->state == VARLINK_IDLE_CLIENT && (v->write_disconnected || v->got_pollhup)) - goto disconnect; - - /* We are on the server side and still want to send out more replies, but we saw POLLHUP already, and - * either got no buffered bytes to write anymore or already saw a write error. In that case we should - * shut down the varlink link. */ - if (IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE) && (v->write_disconnected || v->output_buffer_size == 0) && v->got_pollhup) - goto disconnect; - - return 0; - -disconnect: - varlink_set_state(v, VARLINK_PENDING_DISCONNECT); - return 1; -} - -static int varlink_write(Varlink *v) { - ssize_t n; - int r; - - assert(v); - - if (!VARLINK_STATE_IS_ALIVE(v->state)) - return 0; - if (v->connecting) /* Writing while we are still wait for a non-blocking connect() to complete will - * result in ENOTCONN, hence exit early here */ - return 0; - if (v->write_disconnected) - return 0; - - /* If needed let's convert some output queue json variants into text form */ - r = varlink_format_queue(v); - if (r < 0) - return r; - - if (v->output_buffer_size == 0) - return 0; - - assert(v->output_fd >= 0); - - if (v->n_output_fds > 0) { /* If we shall send fds along, we must use sendmsg() */ - struct iovec iov = { - .iov_base = v->output_buffer + v->output_buffer_index, - .iov_len = v->output_buffer_size, - }; - struct msghdr mh = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_controllen = CMSG_SPACE(sizeof(int) * v->n_output_fds), - }; - - mh.msg_control = alloca0(mh.msg_controllen); - - struct cmsghdr *control = CMSG_FIRSTHDR(&mh); - control->cmsg_len = CMSG_LEN(sizeof(int) * v->n_output_fds); - control->cmsg_level = SOL_SOCKET; - control->cmsg_type = SCM_RIGHTS; - memcpy(CMSG_DATA(control), v->output_fds, sizeof(int) * v->n_output_fds); - - n = sendmsg(v->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL); - } else { - /* We generally prefer recv()/send() (mostly because of MSG_NOSIGNAL) but also want to be compatible - * with non-socket IO, hence fall back automatically. - * - * Use a local variable to help gcc figure out that we set 'n' in all cases. */ - bool prefer_write = v->prefer_write; - if (!prefer_write) { - n = send(v->output_fd, v->output_buffer + v->output_buffer_index, v->output_buffer_size, MSG_DONTWAIT|MSG_NOSIGNAL); - if (n < 0 && errno == ENOTSOCK) - prefer_write = v->prefer_write = true; - } - if (prefer_write) - n = write(v->output_fd, v->output_buffer + v->output_buffer_index, v->output_buffer_size); - } - if (n < 0) { - if (errno == EAGAIN) - return 0; - - if (ERRNO_IS_DISCONNECT(errno)) { - /* If we get informed about a disconnect on write, then let's remember that, but not - * act on it just yet. Let's wait for read() to report the issue first. */ - v->write_disconnected = true; - return 1; - } - - return -errno; - } - - if (v->output_buffer_sensitive) - explicit_bzero_safe(v->output_buffer + v->output_buffer_index, n); - - v->output_buffer_size -= n; - - if (v->output_buffer_size == 0) { - v->output_buffer_index = 0; - v->output_buffer_sensitive = false; /* We can reset the sensitive flag once the buffer is empty */ - } else - v->output_buffer_index += n; - - close_many(v->output_fds, v->n_output_fds); - v->n_output_fds = 0; - - v->timestamp = now(CLOCK_MONOTONIC); - return 1; -} - -#define VARLINK_FDS_MAX (16U*1024U) - -static int varlink_read(Varlink *v) { - struct iovec iov; - struct msghdr mh; - size_t rs; - ssize_t n; - void *p; - - assert(v); - - if (!IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_AWAITING_REPLY_MORE, VARLINK_CALLING, VARLINK_COLLECTING, VARLINK_IDLE_SERVER)) - return 0; - if (v->connecting) /* read() on a socket while we are in connect() will fail with EINVAL, hence exit early here */ - return 0; - if (v->current) - return 0; - if (v->input_buffer_unscanned > 0) - return 0; - if (v->read_disconnected) - return 0; - - if (v->input_buffer_size >= VARLINK_BUFFER_MAX) - return -ENOBUFS; - - assert(v->input_fd >= 0); - - if (MALLOC_SIZEOF_SAFE(v->input_buffer) <= v->input_buffer_index + v->input_buffer_size) { - size_t add; - - add = MIN(VARLINK_BUFFER_MAX - v->input_buffer_size, VARLINK_READ_SIZE); - - if (v->input_buffer_index == 0) { - - if (!GREEDY_REALLOC(v->input_buffer, v->input_buffer_size + add)) - return -ENOMEM; - - } else { - char *b; - - b = new(char, v->input_buffer_size + add); - if (!b) - return -ENOMEM; - - memcpy(b, v->input_buffer + v->input_buffer_index, v->input_buffer_size); - - free_and_replace(v->input_buffer, b); - v->input_buffer_index = 0; - } - } - - p = v->input_buffer + v->input_buffer_index + v->input_buffer_size; - rs = MALLOC_SIZEOF_SAFE(v->input_buffer) - (v->input_buffer_index + v->input_buffer_size); - - if (v->allow_fd_passing_input) { - iov = IOVEC_MAKE(p, rs); - - /* Allocate the fd buffer on the heap, since we need a lot of space potentially */ - if (!v->input_control_buffer) { - v->input_control_buffer_size = CMSG_SPACE(sizeof(int) * VARLINK_FDS_MAX); - v->input_control_buffer = malloc(v->input_control_buffer_size); - if (!v->input_control_buffer) - return -ENOMEM; - } - - mh = (struct msghdr) { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = v->input_control_buffer, - .msg_controllen = v->input_control_buffer_size, - }; - - n = recvmsg_safe(v->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); - } else { - bool prefer_read = v->prefer_read; - if (!prefer_read) { - n = recv(v->input_fd, p, rs, MSG_DONTWAIT); - if (n < 0 && errno == ENOTSOCK) - prefer_read = v->prefer_read = true; - } - if (prefer_read) - n = read(v->input_fd, p, rs); - } - if (n < 0) { - if (errno == EAGAIN) - return 0; - - if (ERRNO_IS_DISCONNECT(errno)) { - v->read_disconnected = true; - return 1; - } - - return -errno; - } - if (n == 0) { /* EOF */ - - if (v->allow_fd_passing_input) - cmsg_close_all(&mh); - - v->read_disconnected = true; - return 1; - } - - if (v->allow_fd_passing_input) { - struct cmsghdr* cmsg; - - cmsg = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, (socklen_t) -1); - if (cmsg) { - size_t add; - - /* We only allow file descriptors to be passed along with the first byte of a - * message. If they are passed with any other byte this is a protocol violation. */ - if (v->input_buffer_size != 0) { - cmsg_close_all(&mh); - return -EPROTO; - } - - add = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); - if (add > INT_MAX - v->n_input_fds) { - cmsg_close_all(&mh); - return -EBADF; - } - - if (!GREEDY_REALLOC(v->input_fds, v->n_input_fds + add)) { - cmsg_close_all(&mh); - return -ENOMEM; - } - - memcpy_safe(v->input_fds + v->n_input_fds, CMSG_TYPED_DATA(cmsg, int), add * sizeof(int)); - v->n_input_fds += add; - } - } - - v->input_buffer_size += n; - v->input_buffer_unscanned += n; - - return 1; -} - -static int varlink_parse_message(Varlink *v) { - const char *e; - char *begin; - size_t sz; - int r; - - assert(v); - - if (v->current) - return 0; - if (v->input_buffer_unscanned <= 0) - return 0; - - assert(v->input_buffer_unscanned <= v->input_buffer_size); - assert(v->input_buffer_index + v->input_buffer_size <= MALLOC_SIZEOF_SAFE(v->input_buffer)); - - begin = v->input_buffer + v->input_buffer_index; - - e = memchr(begin + v->input_buffer_size - v->input_buffer_unscanned, 0, v->input_buffer_unscanned); - if (!e) { - v->input_buffer_unscanned = 0; - return 0; - } - - sz = e - begin + 1; - - r = sd_json_parse(begin, 0, &v->current, NULL, NULL); - if (v->input_sensitive) - explicit_bzero_safe(begin, sz); - if (r < 0) { - /* If we encounter a parse failure flush all data. We cannot possibly recover from this, - * hence drop all buffered data now. */ - v->input_buffer_index = v->input_buffer_size = v->input_buffer_unscanned = 0; - return varlink_log_errno(v, r, "Failed to parse JSON: %m"); - } - - if (v->input_sensitive) { - /* Mark the parameters subfield as sensitive right-away, if that's requested */ - sd_json_variant *parameters = sd_json_variant_by_key(v->current, "parameters"); - if (parameters) - sd_json_variant_sensitive(parameters); - } - - if (DEBUG_LOGGING) { - _cleanup_(erase_and_freep) char *censored_text = NULL; - - /* Suppress sensitive fields in the debug output */ - r = sd_json_variant_format(v->current, /* flags= */ SD_JSON_FORMAT_CENSOR_SENSITIVE, &censored_text); - if (r < 0) - return r; - - varlink_log(v, "Received message: %s", censored_text); - } - - v->input_buffer_size -= sz; - - if (v->input_buffer_size == 0) - v->input_buffer_index = 0; - else - v->input_buffer_index += sz; - - v->input_buffer_unscanned = v->input_buffer_size; - return 1; -} - -static int varlink_test_timeout(Varlink *v) { - assert(v); - - if (!IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_AWAITING_REPLY_MORE, VARLINK_CALLING, VARLINK_COLLECTING)) - return 0; - if (v->timeout == USEC_INFINITY) - return 0; - - if (now(CLOCK_MONOTONIC) < usec_add(v->timestamp, v->timeout)) - return 0; - - varlink_set_state(v, VARLINK_PENDING_TIMEOUT); - - return 1; -} - -static int varlink_dispatch_local_error(Varlink *v, const char *error) { - int r; - - assert(v); - assert(error); - - if (!v->reply_callback) - return 0; - - r = v->reply_callback(v, NULL, error, VARLINK_REPLY_ERROR|VARLINK_REPLY_LOCAL, v->userdata); - if (r < 0) - varlink_log_errno(v, r, "Reply callback returned error, ignoring: %m"); - - return 1; -} - -static int varlink_dispatch_timeout(Varlink *v) { - assert(v); - - if (v->state != VARLINK_PENDING_TIMEOUT) - return 0; - - varlink_set_state(v, VARLINK_PROCESSING_TIMEOUT); - varlink_dispatch_local_error(v, VARLINK_ERROR_TIMEOUT); - varlink_close(v); - - return 1; -} - -static int varlink_dispatch_disconnect(Varlink *v) { - assert(v); - - if (v->state != VARLINK_PENDING_DISCONNECT) - return 0; - - varlink_set_state(v, VARLINK_PROCESSING_DISCONNECT); - varlink_dispatch_local_error(v, VARLINK_ERROR_DISCONNECTED); - varlink_close(v); - - return 1; -} - -static int varlink_sanitize_parameters(sd_json_variant **v) { - int r; - - assert(v); - - /* Varlink always wants a parameters list, hence make one if the caller doesn't want any */ - if (!*v) - return sd_json_variant_new_object(v, NULL, 0); - if (sd_json_variant_is_null(*v)) { - sd_json_variant *empty; - - r = sd_json_variant_new_object(&empty, NULL, 0); - if (r < 0) - return r; - - sd_json_variant_unref(*v); - *v = empty; - return 0; - } - if (!sd_json_variant_is_object(*v)) - return -EINVAL; - - return 0; -} - -static int varlink_dispatch_reply(Varlink *v) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - VarlinkReplyFlags flags = 0; - const char *error = NULL; - sd_json_variant *e; - const char *k; - int r; - - assert(v); - - if (!IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_AWAITING_REPLY_MORE, VARLINK_CALLING, VARLINK_COLLECTING)) - return 0; - if (!v->current) - return 0; - - assert(v->n_pending > 0); - - if (!sd_json_variant_is_object(v->current)) - goto invalid; - - JSON_VARIANT_OBJECT_FOREACH(k, e, v->current) { - - if (streq(k, "error")) { - if (error) - goto invalid; - if (!sd_json_variant_is_string(e)) - goto invalid; - - error = sd_json_variant_string(e); - flags |= VARLINK_REPLY_ERROR; - - } else if (streq(k, "parameters")) { - if (parameters) - goto invalid; - if (!sd_json_variant_is_object(e) && !sd_json_variant_is_null(e)) - goto invalid; - - parameters = sd_json_variant_ref(e); - - } else if (streq(k, "continues")) { - if (FLAGS_SET(flags, VARLINK_REPLY_CONTINUES)) - goto invalid; - - if (!sd_json_variant_is_boolean(e)) - goto invalid; - - if (sd_json_variant_boolean(e)) - flags |= VARLINK_REPLY_CONTINUES; - } else - goto invalid; - } - - /* Replies with 'continue' set are only OK if we set 'more' when the method call was initiated */ - if (!IN_SET(v->state, VARLINK_AWAITING_REPLY_MORE, VARLINK_COLLECTING) && FLAGS_SET(flags, VARLINK_REPLY_CONTINUES)) - goto invalid; - - /* An error is final */ - if (error && FLAGS_SET(flags, VARLINK_REPLY_CONTINUES)) - goto invalid; - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - goto invalid; - - v->current_reply_flags = flags; - - if (IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_AWAITING_REPLY_MORE)) { - varlink_set_state(v, VARLINK_PROCESSING_REPLY); - - if (v->reply_callback) { - r = v->reply_callback(v, parameters, error, flags, v->userdata); - if (r < 0) - varlink_log_errno(v, r, "Reply callback returned error, ignoring: %m"); - } - - varlink_clear_current(v); - - if (v->state == VARLINK_PROCESSING_REPLY) { - assert(v->n_pending > 0); - - if (!FLAGS_SET(flags, VARLINK_REPLY_CONTINUES)) - v->n_pending--; - - varlink_set_state(v, - FLAGS_SET(flags, VARLINK_REPLY_CONTINUES) ? VARLINK_AWAITING_REPLY_MORE : - v->n_pending == 0 ? VARLINK_IDLE_CLIENT : VARLINK_AWAITING_REPLY); - } - } else if (v->state == VARLINK_COLLECTING) - varlink_set_state(v, VARLINK_COLLECTING_REPLY); - else { - assert(v->state == VARLINK_CALLING); - varlink_set_state(v, VARLINK_CALLED); - } - - return 1; - -invalid: - varlink_set_state(v, VARLINK_PROCESSING_FAILURE); - varlink_dispatch_local_error(v, VARLINK_ERROR_PROTOCOL); - varlink_close(v); - - return 1; -} - -static int generic_method_get_info( - Varlink *link, - sd_json_variant *parameters, - VarlinkMethodFlags flags, - void *userdata) { - - _cleanup_strv_free_ char **interfaces = NULL; - _cleanup_free_ char *product = NULL; - int r; - - assert(link); - - if (sd_json_variant_elements(parameters) != 0) - return varlink_error_invalid_parameter(link, parameters); - - product = strjoin("systemd (", program_invocation_short_name, ")"); - if (!product) - return -ENOMEM; - - VarlinkInterface *interface; - HASHMAP_FOREACH(interface, ASSERT_PTR(link->server)->interfaces) { - r = strv_extend(&interfaces, interface->name); - if (r < 0) - return r; - } - - strv_sort(interfaces); - - return 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_STRV("interfaces", interfaces)); -} - -static int generic_method_get_interface_description( - Varlink *link, - sd_json_variant *parameters, - VarlinkMethodFlags flags, - void *userdata) { - - static const struct sd_json_dispatch_field dispatch_table[] = { - { "interface", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, SD_JSON_MANDATORY }, - {} - }; - _cleanup_free_ char *text = NULL; - const VarlinkInterface *interface; - const char *name = NULL; - int r; - - assert(link); - - r = sd_json_dispatch(parameters, dispatch_table, 0, &name); - if (r < 0) - return r; - - interface = hashmap_get(ASSERT_PTR(link->server)->interfaces, name); - if (!interface) - return varlink_errorbo( - link, - VARLINK_ERROR_INTERFACE_NOT_FOUND, - SD_JSON_BUILD_PAIR_STRING("interface", name)); - - r = varlink_idl_format(interface, &text); - if (r < 0) - return r; - - return varlink_replybo( - link, - SD_JSON_BUILD_PAIR_STRING("description", text)); -} - -static int varlink_dispatch_method(Varlink *v) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - VarlinkMethodFlags flags = 0; - const char *method = NULL; - sd_json_variant *e; - VarlinkMethod callback; - const char *k; - int r; - - assert(v); - - if (v->state != VARLINK_IDLE_SERVER) - return 0; - if (!v->current) - return 0; - - if (!sd_json_variant_is_object(v->current)) - goto invalid; - - JSON_VARIANT_OBJECT_FOREACH(k, e, v->current) { - - if (streq(k, "method")) { - if (method) - goto invalid; - if (!sd_json_variant_is_string(e)) - goto invalid; - - method = sd_json_variant_string(e); - - } else if (streq(k, "parameters")) { - if (parameters) - goto invalid; - if (!sd_json_variant_is_object(e) && !sd_json_variant_is_null(e)) - goto invalid; - - parameters = sd_json_variant_ref(e); - - } else if (streq(k, "oneway")) { - - if ((flags & (VARLINK_METHOD_ONEWAY|VARLINK_METHOD_MORE)) != 0) - goto invalid; - - if (!sd_json_variant_is_boolean(e)) - goto invalid; - - if (sd_json_variant_boolean(e)) - flags |= VARLINK_METHOD_ONEWAY; - - } else if (streq(k, "more")) { - - if ((flags & (VARLINK_METHOD_ONEWAY|VARLINK_METHOD_MORE)) != 0) - goto invalid; - - if (!sd_json_variant_is_boolean(e)) - goto invalid; - - if (sd_json_variant_boolean(e)) - flags |= VARLINK_METHOD_MORE; - - } else - goto invalid; - } - - if (!method) - goto invalid; - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - goto fail; - - varlink_set_state(v, (flags & VARLINK_METHOD_MORE) ? VARLINK_PROCESSING_METHOD_MORE : - (flags & VARLINK_METHOD_ONEWAY) ? VARLINK_PROCESSING_METHOD_ONEWAY : - VARLINK_PROCESSING_METHOD); - - assert(v->server); - - /* First consult user supplied method implementations */ - callback = hashmap_get(v->server->methods, method); - if (!callback) { - if (streq(method, "org.varlink.service.GetInfo")) - callback = generic_method_get_info; - else if (streq(method, "org.varlink.service.GetInterfaceDescription")) - callback = generic_method_get_interface_description; - } - - if (callback) { - bool invalid = false; - - v->current_method = hashmap_get(v->server->symbols, method); - if (!v->current_method) - varlink_log(v, "No interface description defined for method '%s', not validating.", method); - else { - const char *bad_field; - - r = varlink_idl_validate_method_call(v->current_method, parameters, &bad_field); - if (r < 0) { - /* Please adjust test/units/end.sh when updating the log message. */ - varlink_log_errno(v, r, "Parameters for method %s() didn't pass validation on field '%s': %m", - method, strna(bad_field)); - - if (IN_SET(v->state, VARLINK_PROCESSING_METHOD, VARLINK_PROCESSING_METHOD_MORE)) { - r = varlink_error_invalid_parameter_name(v, bad_field); - if (r < 0) - return r; - } - invalid = true; - } - } - - if (!invalid) { - r = callback(v, parameters, flags, v->userdata); - if (r < 0) { - varlink_log_errno(v, r, "Callback for %s returned error: %m", method); - - /* We got an error back from the callback. Propagate it to the client if the method call remains unanswered. */ - if (IN_SET(v->state, VARLINK_PROCESSING_METHOD, VARLINK_PROCESSING_METHOD_MORE)) { - r = varlink_error_errno(v, r); - if (r < 0) - return r; - } - } - } - } else if (IN_SET(v->state, VARLINK_PROCESSING_METHOD, VARLINK_PROCESSING_METHOD_MORE)) { - r = varlink_errorbo(v, VARLINK_ERROR_METHOD_NOT_FOUND, SD_JSON_BUILD_PAIR("method", SD_JSON_BUILD_STRING(method))); - if (r < 0) - return r; - } - - switch (v->state) { - - case VARLINK_PROCESSED_METHOD: /* Method call is fully processed */ - case VARLINK_PROCESSING_METHOD_ONEWAY: /* ditto */ - varlink_clear_current(v); - varlink_set_state(v, VARLINK_IDLE_SERVER); - break; - - case VARLINK_PROCESSING_METHOD: /* Method call wasn't replied to, will be replied to later */ - varlink_set_state(v, VARLINK_PENDING_METHOD); - break; - - case VARLINK_PROCESSING_METHOD_MORE: /* No reply for a "more" message was sent, more to come */ - varlink_set_state(v, VARLINK_PENDING_METHOD_MORE); - break; - - default: - assert_not_reached(); - } - - return 1; - -invalid: - r = -EINVAL; - -fail: - varlink_set_state(v, VARLINK_PROCESSING_FAILURE); - varlink_dispatch_local_error(v, VARLINK_ERROR_PROTOCOL); - varlink_close(v); - - return r; -} - -int varlink_process(Varlink *v) { - int r; - - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - varlink_ref(v); - - r = varlink_write(v); - if (r < 0) - varlink_log_errno(v, r, "Write failed: %m"); - if (r != 0) - goto finish; - - r = varlink_dispatch_reply(v); - if (r < 0) - varlink_log_errno(v, r, "Reply dispatch failed: %m"); - if (r != 0) - goto finish; - - r = varlink_dispatch_method(v); - if (r < 0) - varlink_log_errno(v, r, "Method dispatch failed: %m"); - if (r != 0) - goto finish; - - r = varlink_parse_message(v); - if (r < 0) - varlink_log_errno(v, r, "Message parsing failed: %m"); - if (r != 0) - goto finish; - - r = varlink_read(v); - if (r < 0) - varlink_log_errno(v, r, "Read failed: %m"); - if (r != 0) - goto finish; - - r = varlink_test_disconnect(v); - assert(r >= 0); - if (r != 0) - goto finish; - - r = varlink_dispatch_disconnect(v); - assert(r >= 0); - if (r != 0) - goto finish; - - r = varlink_test_timeout(v); - assert(r >= 0); - if (r != 0) - goto finish; - - r = varlink_dispatch_timeout(v); - assert(r >= 0); - if (r != 0) - goto finish; - -finish: - if (r >= 0 && v->defer_event_source) { - int q; - - /* If we did some processing, make sure we are called again soon */ - q = sd_event_source_set_enabled(v->defer_event_source, r > 0 ? SD_EVENT_ON : SD_EVENT_OFF); - if (q < 0) - r = varlink_log_errno(v, q, "Failed to enable deferred event source: %m"); - } - - if (r < 0) { - if (VARLINK_STATE_IS_ALIVE(v->state)) - /* Initiate disconnection */ - varlink_set_state(v, VARLINK_PENDING_DISCONNECT); - else - /* We failed while disconnecting, in that case close right away */ - varlink_close(v); - } - - varlink_unref(v); - return r; -} - -int varlink_dispatch_again(Varlink *v) { - int r; - - assert_return(v, -EINVAL); - - /* If a method call handler could not process the method call just yet (for example because it needed - * some Polkit authentication first), then it can leave the call unanswered, do its thing, and then - * ask to be dispatched a second time, via this call. It will then be called again, for the same - * message */ - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - if (v->state != VARLINK_PENDING_METHOD) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection has no pending method."); - - varlink_set_state(v, VARLINK_IDLE_SERVER); - - r = sd_event_source_set_enabled(v->defer_event_source, SD_EVENT_ON); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enable deferred event source: %m"); - - return 0; -} - -int varlink_get_current_parameters(Varlink *v, sd_json_variant **ret) { - sd_json_variant *p; - - assert_return(v, -EINVAL); - - if (!v->current) - return -ENODATA; - - p = sd_json_variant_by_key(v->current, "parameters"); - if (!p) - return -ENODATA; - - if (ret) - *ret = sd_json_variant_ref(p); - - return 0; -} - -static void handle_revents(Varlink *v, int revents) { - assert(v); - - if (v->connecting) { - /* If we have seen POLLOUT or POLLHUP on a socket we are asynchronously waiting a connect() - * to complete on, we know we are ready. We don't read the connection error here though, - * we'll get the error on the next read() or write(). */ - if ((revents & (POLLOUT|POLLHUP)) == 0) - return; - - varlink_log(v, "Asynchronous connection completed."); - v->connecting = false; - } else { - /* Note that we don't care much about POLLIN/POLLOUT here, we'll just try reading and writing - * what we can. However, we do care about POLLHUP to detect connection termination even if we - * momentarily don't want to read nor write anything. */ - - if (!FLAGS_SET(revents, POLLHUP)) - return; - - varlink_log(v, "Got POLLHUP from socket."); - v->got_pollhup = true; - } -} - -int varlink_wait(Varlink *v, usec_t timeout) { - int r, events; - usec_t t; - - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - r = varlink_get_timeout(v, &t); - if (r < 0) - return r; - if (t != USEC_INFINITY) { - usec_t n; - - n = now(CLOCK_MONOTONIC); - if (t < n) - t = 0; - else - t = usec_sub_unsigned(t, n); - } - - if (timeout != USEC_INFINITY && - (t == USEC_INFINITY || timeout < t)) - t = timeout; - - events = varlink_get_events(v); - if (events < 0) - return events; - - struct pollfd pollfd[2]; - size_t n_poll_fd = 0; - - if (v->input_fd == v->output_fd) { - pollfd[n_poll_fd++] = (struct pollfd) { - .fd = v->input_fd, - .events = events, - }; - } else { - pollfd[n_poll_fd++] = (struct pollfd) { - .fd = v->input_fd, - .events = events & POLLIN, - }; - pollfd[n_poll_fd++] = (struct pollfd) { - .fd = v->output_fd, - .events = events & POLLOUT, - }; - }; - - r = ppoll_usec(pollfd, n_poll_fd, t); - if (ERRNO_IS_NEG_TRANSIENT(r)) /* Treat EINTR as not a timeout, but also nothing happened, and - * the caller gets a chance to call back into us */ - return 1; - if (r <= 0) - return r; - - /* Merge the seen events into one */ - int revents = 0; - FOREACH_ARRAY(p, pollfd, n_poll_fd) - revents |= p->revents; - - handle_revents(v, revents); - return 1; -} - -int varlink_is_idle(Varlink *v) { - assert_return(v, -EINVAL); - - /* Returns true if there's nothing pending on the connection anymore, i.e. we processed all incoming - * or outgoing messages fully, or finished disconnection */ - - return IN_SET(v->state, VARLINK_DISCONNECTED, VARLINK_IDLE_CLIENT, VARLINK_IDLE_SERVER); -} - -int varlink_get_fd(Varlink *v) { - - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - if (v->input_fd != v->output_fd) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBADF), "Separate file descriptors for input/output set."); - if (v->input_fd < 0) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBADF), "No valid fd."); - - return v->input_fd; -} - -int varlink_get_events(Varlink *v) { - int ret = 0; - - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - if (v->connecting) /* When processing an asynchronous connect(), we only wait for EPOLLOUT, which - * tells us that the connection is now complete. Before that we should neither - * write() or read() from the fd. */ - return EPOLLOUT; - - if (!v->read_disconnected && - IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_AWAITING_REPLY_MORE, VARLINK_CALLING, VARLINK_COLLECTING, VARLINK_IDLE_SERVER) && - !v->current && - v->input_buffer_unscanned <= 0) - ret |= EPOLLIN; - - if (!v->write_disconnected && - v->output_buffer_size > 0) - ret |= EPOLLOUT; - - return ret; -} - -int varlink_get_timeout(Varlink *v, usec_t *ret) { - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - if (IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_AWAITING_REPLY_MORE, VARLINK_CALLING, VARLINK_COLLECTING) && - v->timeout != USEC_INFINITY) { - if (ret) - *ret = usec_add(v->timestamp, v->timeout); - return 1; - } else { - if (ret) - *ret = USEC_INFINITY; - return 0; - } -} - -int varlink_flush(Varlink *v) { - int ret = 0, r; - - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - for (;;) { - if (v->output_buffer_size == 0) - break; - if (v->write_disconnected) - return -ECONNRESET; - - r = varlink_write(v); - if (r < 0) - return r; - if (r > 0) { - ret = 1; - continue; - } - - r = fd_wait_for_event(v->output_fd, POLLOUT, USEC_INFINITY); - if (ERRNO_IS_NEG_TRANSIENT(r)) - continue; - if (r < 0) - return varlink_log_errno(v, r, "Poll failed on fd: %m"); - assert(r > 0); - - handle_revents(v, r); - } - - return ret; -} - -static void varlink_detach_server(Varlink *v) { - VarlinkServer *saved_server; - assert(v); - - if (!v->server) - return; - - if (v->server->by_uid && - v->ucred_acquired && - uid_is_valid(v->ucred.uid)) { - unsigned c; - - c = PTR_TO_UINT(hashmap_get(v->server->by_uid, UID_TO_PTR(v->ucred.uid))); - assert(c > 0); - - if (c == 1) - (void) hashmap_remove(v->server->by_uid, UID_TO_PTR(v->ucred.uid)); - else - (void) hashmap_replace(v->server->by_uid, UID_TO_PTR(v->ucred.uid), UINT_TO_PTR(c - 1)); - } - - assert(v->server->n_connections > 0); - v->server->n_connections--; - - /* If this is a connection associated to a server, then let's disconnect the server and the - * connection from each other. This drops the dangling reference that connect_callback() set up. But - * before we release the references, let's call the disconnection callback if it is defined. */ - - saved_server = TAKE_PTR(v->server); - - if (saved_server->disconnect_callback) - saved_server->disconnect_callback(saved_server, v, saved_server->userdata); - - varlink_server_test_exit_on_idle(saved_server); - varlink_server_unref(saved_server); - varlink_unref(v); -} - -int varlink_close(Varlink *v) { - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return 0; - - varlink_set_state(v, VARLINK_DISCONNECTED); - - /* Let's take a reference first, since varlink_detach_server() might drop the final (dangling) ref - * which would destroy us before we can call varlink_clear() */ - varlink_ref(v); - varlink_detach_server(v); - varlink_clear(v); - varlink_unref(v); - - return 1; -} - -Varlink* varlink_close_unref(Varlink *v) { - if (!v) - return NULL; - - (void) varlink_close(v); - return varlink_unref(v); -} - -Varlink* varlink_flush_close_unref(Varlink *v) { - if (!v) - return NULL; - - (void) varlink_flush(v); - return varlink_close_unref(v); -} - -static int varlink_format_json(Varlink *v, sd_json_variant *m) { - _cleanup_(erase_and_freep) char *text = NULL; - int sz, r; - - assert(v); - assert(m); - - sz = sd_json_variant_format(m, /* flags= */ 0, &text); - if (sz < 0) - return sz; - assert(text[sz] == '\0'); - - if (v->output_buffer_size + sz + 1 > VARLINK_BUFFER_MAX) - return -ENOBUFS; - - if (DEBUG_LOGGING) { - _cleanup_(erase_and_freep) char *censored_text = NULL; - - /* Suppress sensitive fields in the debug output */ - r = sd_json_variant_format(m, SD_JSON_FORMAT_CENSOR_SENSITIVE, &censored_text); - if (r < 0) - return r; - - varlink_log(v, "Sending message: %s", censored_text); - } - - if (v->output_buffer_size == 0) { - - free_and_replace(v->output_buffer, text); - - v->output_buffer_size = sz + 1; - v->output_buffer_index = 0; - - } else if (v->output_buffer_index == 0) { - - if (!GREEDY_REALLOC(v->output_buffer, v->output_buffer_size + sz + 1)) - return -ENOMEM; - - memcpy(v->output_buffer + v->output_buffer_size, text, sz + 1); - v->output_buffer_size += sz + 1; - } else { - char *n; - const size_t new_size = v->output_buffer_size + sz + 1; - - n = new(char, new_size); - if (!n) - return -ENOMEM; - - memcpy(mempcpy(n, v->output_buffer + v->output_buffer_index, v->output_buffer_size), text, sz + 1); - - free_and_replace(v->output_buffer, n); - v->output_buffer_size = new_size; - v->output_buffer_index = 0; - } - - if (sd_json_variant_is_sensitive_recursive(m)) - v->output_buffer_sensitive = true; /* Propagate sensitive flag */ - else - text = mfree(text); /* No point in the erase_and_free() destructor declared above */ - - return 0; -} - -static int varlink_enqueue_json(Varlink *v, sd_json_variant *m) { - VarlinkJsonQueueItem *q; - - assert(v); - assert(m); - - /* If there are no file descriptors to be queued and no queue entries yet we can shortcut things and - * append this entry directly to the output buffer */ - if (v->n_pushed_fds == 0 && !v->output_queue) - return varlink_format_json(v, m); - - /* Otherwise add a queue entry for this */ - q = varlink_json_queue_item_new(m, v->pushed_fds, v->n_pushed_fds); - if (!q) - return -ENOMEM; - - v->n_pushed_fds = 0; /* fds now belong to the queue entry */ - - LIST_INSERT_AFTER(queue, v->output_queue, v->output_queue_tail, q); - v->output_queue_tail = q; - return 0; -} - -static int varlink_format_queue(Varlink *v) { - int r; - - assert(v); - - /* Takes entries out of the output queue and formats them into the output buffer. But only if this - * would not corrupt our fd message boundaries */ - - while (v->output_queue) { - _cleanup_free_ int *array = NULL; - VarlinkJsonQueueItem *q = v->output_queue; - - if (v->n_output_fds > 0) /* unwritten fds? if we'd add more we'd corrupt the fd message boundaries, hence wait */ - return 0; - - if (q->n_fds > 0) { - array = newdup(int, q->fds, q->n_fds); - if (!array) - return -ENOMEM; - } - - r = varlink_format_json(v, q->data); - if (r < 0) - return r; - - /* Take possession of the queue element's fds */ - free(v->output_fds); - v->output_fds = TAKE_PTR(array); - v->n_output_fds = q->n_fds; - q->n_fds = 0; - - LIST_REMOVE(queue, v->output_queue, q); - if (!v->output_queue) - v->output_queue_tail = NULL; - - varlink_json_queue_item_free(q); - } - - return 0; -} - -int varlink_send(Varlink *v, const char *method, sd_json_variant *parameters) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(method, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - /* We allow enqueuing multiple method calls at once! */ - if (!IN_SET(v->state, VARLINK_IDLE_CLIENT, VARLINK_AWAITING_REPLY)) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection busy."); - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - return varlink_log_errno(v, r, "Failed to sanitize parameters: %m"); - - r = sd_json_buildo( - &m, - SD_JSON_BUILD_PAIR("method", SD_JSON_BUILD_STRING(method)), - SD_JSON_BUILD_PAIR("parameters", SD_JSON_BUILD_VARIANT(parameters)), - SD_JSON_BUILD_PAIR("oneway", SD_JSON_BUILD_BOOLEAN(true))); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - r = varlink_enqueue_json(v, m); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enqueue json message: %m"); - - /* No state change here, this is one-way only after all */ - v->timestamp = now(CLOCK_MONOTONIC); - return 0; -} - -int varlink_sendb(Varlink *v, const char *method, ...) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - int r; - - assert_return(v, -EINVAL); - - va_start(ap, method); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - return varlink_send(v, method, parameters); -} - -int varlink_invoke(Varlink *v, const char *method, sd_json_variant *parameters) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(method, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - /* We allow enqueuing multiple method calls at once! */ - if (!IN_SET(v->state, VARLINK_IDLE_CLIENT, VARLINK_AWAITING_REPLY)) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection busy."); - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - return varlink_log_errno(v, r, "Failed to sanitize parameters: %m"); - - r = sd_json_buildo( - &m, - SD_JSON_BUILD_PAIR("method", SD_JSON_BUILD_STRING(method)), - SD_JSON_BUILD_PAIR("parameters", SD_JSON_BUILD_VARIANT(parameters))); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - r = varlink_enqueue_json(v, m); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enqueue json message: %m"); - - varlink_set_state(v, VARLINK_AWAITING_REPLY); - v->n_pending++; - v->timestamp = now(CLOCK_MONOTONIC); - - return 0; -} - -int varlink_invokeb(Varlink *v, const char *method, ...) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - int r; - - assert_return(v, -EINVAL); - - va_start(ap, method); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - return varlink_invoke(v, method, parameters); -} - -int varlink_observe(Varlink *v, const char *method, sd_json_variant *parameters) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(method, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - /* Note that we don't allow enqueuing multiple method calls when we are in more/continues mode! We - * thus insist on an idle client here. */ - if (v->state != VARLINK_IDLE_CLIENT) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection busy."); - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - return varlink_log_errno(v, r, "Failed to sanitize parameters: %m"); - - r = sd_json_buildo( - &m, - SD_JSON_BUILD_PAIR("method", SD_JSON_BUILD_STRING(method)), - SD_JSON_BUILD_PAIR("parameters", SD_JSON_BUILD_VARIANT(parameters)), - SD_JSON_BUILD_PAIR("more", SD_JSON_BUILD_BOOLEAN(true))); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - r = varlink_enqueue_json(v, m); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enqueue json message: %m"); - - varlink_set_state(v, VARLINK_AWAITING_REPLY_MORE); - v->n_pending++; - v->timestamp = now(CLOCK_MONOTONIC); - - return 0; -} - -int varlink_observeb(Varlink *v, const char *method, ...) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - int r; - - assert_return(v, -EINVAL); - - va_start(ap, method); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - return varlink_observe(v, method, parameters); -} - -int varlink_call_full( - Varlink *v, - const char *method, - sd_json_variant *parameters, - sd_json_variant **ret_parameters, - const char **ret_error_id, - VarlinkReplyFlags *ret_flags) { - - _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(method, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - if (v->state != VARLINK_IDLE_CLIENT) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection busy."); - - assert(v->n_pending == 0); /* n_pending can't be > 0 if we are in VARLINK_IDLE_CLIENT state */ - - /* If there was still a reply pinned from a previous call, now it's the time to get rid of it, so - * that we can assign a new reply shortly. */ - varlink_clear_current(v); - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - return varlink_log_errno(v, r, "Failed to sanitize parameters: %m"); - - r = sd_json_buildo( - &m, - SD_JSON_BUILD_PAIR("method", SD_JSON_BUILD_STRING(method)), - SD_JSON_BUILD_PAIR("parameters", SD_JSON_BUILD_VARIANT(parameters))); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - r = varlink_enqueue_json(v, m); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enqueue json message: %m"); - - varlink_set_state(v, VARLINK_CALLING); - v->n_pending++; - v->timestamp = now(CLOCK_MONOTONIC); - - while (v->state == VARLINK_CALLING) { - r = varlink_process(v); - if (r < 0) - return r; - if (r > 0) - continue; - - r = varlink_wait(v, USEC_INFINITY); - if (r < 0) - return r; - } - - switch (v->state) { - - case VARLINK_CALLED: { - assert(v->current); - - varlink_set_state(v, VARLINK_IDLE_CLIENT); - assert(v->n_pending == 1); - v->n_pending--; - - sd_json_variant *e = sd_json_variant_by_key(v->current, "error"), - *p = sd_json_variant_by_key(v->current, "parameters"); - - /* If caller doesn't ask for the error string, then let's return an error code in case of failure */ - if (!ret_error_id && e) - return varlink_error_to_errno(sd_json_variant_string(e), p); - - if (ret_parameters) - *ret_parameters = p; - if (ret_error_id) - *ret_error_id = e ? sd_json_variant_string(e) : NULL; - if (ret_flags) - *ret_flags = v->current_reply_flags; - - return 1; - } - - case VARLINK_PENDING_DISCONNECT: - case VARLINK_DISCONNECTED: - return varlink_log_errno(v, SYNTHETIC_ERRNO(ECONNRESET), "Connection was closed."); - - case VARLINK_PENDING_TIMEOUT: - return varlink_log_errno(v, SYNTHETIC_ERRNO(ETIME), "Connection timed out."); - - default: - assert_not_reached(); - } -} - -int varlink_callb_ap( - Varlink *v, - const char *method, - sd_json_variant **ret_parameters, - const char **ret_error_id, - VarlinkReplyFlags *ret_flags, - va_list ap) { - - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(method, -EINVAL); - - r = sd_json_buildv(¶meters, ap); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - return varlink_call_full(v, method, parameters, ret_parameters, ret_error_id, ret_flags); -} - -int varlink_call_and_log( - Varlink *v, - const char *method, - sd_json_variant *parameters, - sd_json_variant **ret_parameters) { - - sd_json_variant *reply = NULL; - const char *error_id = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(method, -EINVAL); - - r = varlink_call(v, method, parameters, &reply, &error_id); - if (r < 0) - return log_error_errno(r, "Failed to issue %s() varlink call: %m", method); - if (error_id) - return log_error_errno(varlink_error_to_errno(error_id, reply), - "Failed to issue %s() varlink call: %s", method, error_id); - - if (ret_parameters) - *ret_parameters = TAKE_PTR(reply); - - return 0; -} - -int varlink_callb_and_log( - Varlink *v, - const char *method, - sd_json_variant **ret_parameters, - ...) { - - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - int r; - - assert_return(v, -EINVAL); - assert_return(method, -EINVAL); - - va_start(ap, ret_parameters); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - if (r < 0) - return log_error_errno(r, "Failed to build JSON message: %m"); - - return varlink_call_and_log(v, method, parameters, ret_parameters); -} - -int varlink_collect_full( - Varlink *v, - const char *method, - sd_json_variant *parameters, - sd_json_variant **ret_parameters, - const char **ret_error_id, - VarlinkReplyFlags *ret_flags) { - - _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL, *collected = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(method, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - if (v->state != VARLINK_IDLE_CLIENT) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection busy."); - - assert(v->n_pending == 0); /* n_pending can't be > 0 if we are in VARLINK_IDLE_CLIENT state */ - - /* If there was still a reply pinned from a previous call, now it's the time to get rid of it, so - * that we can assign a new reply shortly. */ - varlink_clear_current(v); - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - return varlink_log_errno(v, r, "Failed to sanitize parameters: %m"); - - r = sd_json_buildo( - &m, - SD_JSON_BUILD_PAIR("method", SD_JSON_BUILD_STRING(method)), - SD_JSON_BUILD_PAIR("parameters", SD_JSON_BUILD_VARIANT(parameters)), - SD_JSON_BUILD_PAIR("more", SD_JSON_BUILD_BOOLEAN(true))); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - r = varlink_enqueue_json(v, m); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enqueue json message: %m"); - - varlink_set_state(v, VARLINK_COLLECTING); - v->n_pending++; - v->timestamp = now(CLOCK_MONOTONIC); - - for (;;) { - while (v->state == VARLINK_COLLECTING) { - r = varlink_process(v); - if (r < 0) - return r; - if (r > 0) - continue; - - r = varlink_wait(v, USEC_INFINITY); - if (r < 0) - return r; - } - - switch (v->state) { - - case VARLINK_COLLECTING_REPLY: { - assert(v->current); - - sd_json_variant *e = sd_json_variant_by_key(v->current, "error"), - *p = sd_json_variant_by_key(v->current, "parameters"); - - /* Unless there is more to collect we reset state to idle */ - if (!FLAGS_SET(v->current_reply_flags, VARLINK_REPLY_CONTINUES)) { - varlink_set_state(v, VARLINK_IDLE_CLIENT); - assert(v->n_pending == 1); - v->n_pending--; - } - - if (e) { - if (!ret_error_id) - return varlink_error_to_errno(sd_json_variant_string(e), p); - - if (ret_parameters) - *ret_parameters = p; - if (ret_error_id) - *ret_error_id = sd_json_variant_string(e); - if (ret_flags) - *ret_flags = v->current_reply_flags; - - return 1; - } - - if (sd_json_variant_elements(collected) >= VARLINK_COLLECT_MAX) - return varlink_log_errno(v, SYNTHETIC_ERRNO(E2BIG), "Number of reply messages grew too large (%zu) while collecting.", sd_json_variant_elements(collected)); - - r = sd_json_variant_append_array(&collected, p); - if (r < 0) - return varlink_log_errno(v, r, "Failed to append JSON object to array: %m"); - - if (FLAGS_SET(v->current_reply_flags, VARLINK_REPLY_CONTINUES)) { - /* There's more to collect, continue */ - varlink_clear_current(v); - varlink_set_state(v, VARLINK_COLLECTING); - continue; - } - - if (ret_parameters) - /* Install the collection array in the connection object, so that we can hand - * out a pointer to it without passing over ownership, to make it work more - * alike regular method call replies */ - *ret_parameters = v->current_collected = TAKE_PTR(collected); - if (ret_error_id) - *ret_error_id = NULL; - if (ret_flags) - *ret_flags = v->current_reply_flags; - - return 1; - } - - case VARLINK_PENDING_DISCONNECT: - case VARLINK_DISCONNECTED: - return varlink_log_errno(v, SYNTHETIC_ERRNO(ECONNRESET), "Connection was closed."); - - case VARLINK_PENDING_TIMEOUT: - return varlink_log_errno(v, SYNTHETIC_ERRNO(ETIME), "Connection timed out."); - - default: - assert_not_reached(); - } - } -} - -int varlink_collectb( - Varlink *v, - const char *method, - sd_json_variant **ret_parameters, - const char **ret_error_id, - ...) { - - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - int r; - - assert_return(v, -EINVAL); - - va_start(ap, ret_error_id); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - return varlink_collect_full(v, method, parameters, ret_parameters, ret_error_id, NULL); -} - -int varlink_reply(Varlink *v, sd_json_variant *parameters) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL; - int r; - - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return -ENOTCONN; - if (!IN_SET(v->state, - VARLINK_PROCESSING_METHOD, VARLINK_PROCESSING_METHOD_MORE, - VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE)) - return -EBUSY; - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - return varlink_log_errno(v, r, "Failed to sanitize parameters: %m"); - - r = sd_json_buildo(&m, SD_JSON_BUILD_PAIR("parameters", SD_JSON_BUILD_VARIANT(parameters))); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - if (v->current_method) { - const char *bad_field = NULL; - - r = varlink_idl_validate_method_reply(v->current_method, parameters, &bad_field); - if (r < 0) - /* Please adjust test/units/end.sh when updating the log message. */ - varlink_log_errno(v, r, "Return parameters for method reply %s() didn't pass validation on field '%s', ignoring: %m", - v->current_method->name, strna(bad_field)); - } - - r = varlink_enqueue_json(v, m); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enqueue json message: %m"); - - if (IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE)) { - /* We just replied to a method call that was let hanging for a while (i.e. we were outside of - * the varlink_dispatch_method() stack frame), which means with this reply we are ready to - * process further messages. */ - varlink_clear_current(v); - varlink_set_state(v, VARLINK_IDLE_SERVER); - } else - /* We replied to a method call from within the varlink_dispatch_method() stack frame), which - * means we should it handle the rest of the state engine. */ - varlink_set_state(v, VARLINK_PROCESSED_METHOD); - - return 1; -} - -int varlink_replyb(Varlink *v, ...) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - int r; - - assert_return(v, -EINVAL); - - va_start(ap, v); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - - if (r < 0) - return r; - - return varlink_reply(v, parameters); -} - -int varlink_error(Varlink *v, const char *error_id, sd_json_variant *parameters) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(error_id, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - if (!IN_SET(v->state, - VARLINK_PROCESSING_METHOD, VARLINK_PROCESSING_METHOD_MORE, - VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE)) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection busy."); - - /* Reset the list of pushed file descriptors before sending an error reply. We do this here to - * simplify code that puts together a complex reply message with fds, and half-way something - * fails. In that case the pushed fds need to be flushed out again. Under the assumption that it - * never makes sense to send fds along with errors we simply flush them out here beforehand, so that - * the callers don't need to do this explicitly. */ - varlink_reset_fds(v); - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - return varlink_log_errno(v, r, "Failed to sanitize parameters: %m"); - - r = sd_json_buildo( - &m, - SD_JSON_BUILD_PAIR("error", SD_JSON_BUILD_STRING(error_id)), - SD_JSON_BUILD_PAIR("parameters", SD_JSON_BUILD_VARIANT(parameters))); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - VarlinkSymbol *symbol = hashmap_get(v->server->symbols, error_id); - if (!symbol) - varlink_log(v, "No interface description defined for error '%s', not validating.", error_id); - else { - const char *bad_field = NULL; - - r = varlink_idl_validate_error(symbol, parameters, &bad_field); - if (r < 0) - /* Please adjust test/units/end.sh when updating the log message. */ - varlink_log_errno(v, r, "Parameters for error %s didn't pass validation on field '%s', ignoring: %m", - error_id, strna(bad_field)); - } - - r = varlink_enqueue_json(v, m); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enqueue json message: %m"); - - if (IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE)) { - varlink_clear_current(v); - varlink_set_state(v, VARLINK_IDLE_SERVER); - } else - varlink_set_state(v, VARLINK_PROCESSED_METHOD); - - return 1; -} - -int varlink_errorb(Varlink *v, const char *error_id, ...) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - int r; - - assert_return(v, -EINVAL); - assert_return(error_id, -EINVAL); - - va_start(ap, error_id); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - return varlink_error(v, error_id, parameters); -} - -int varlink_error_invalid_parameter(Varlink *v, sd_json_variant *parameters) { - int r; - - assert_return(v, -EINVAL); - assert_return(parameters, -EINVAL); - - /* We expect to be called in one of two ways: the 'parameters' argument is a string variant in which - * case it is the parameter key name that is invalid. Or the 'parameters' argument is an object - * variant in which case we'll pull out the first key. The latter mode is useful in functions that - * don't expect any arguments. */ - - /* varlink_error(...) expects a json object as the third parameter. Passing a string variant causes - * parameter sanitization to fail, and it returns -EINVAL. */ - - if (sd_json_variant_is_string(parameters)) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters_obj = NULL; - - r = sd_json_buildo(¶meters_obj,SD_JSON_BUILD_PAIR("parameter", SD_JSON_BUILD_VARIANT(parameters))); - if (r < 0) - return r; - - return varlink_error(v, VARLINK_ERROR_INVALID_PARAMETER, parameters_obj); - } - - if (sd_json_variant_is_object(parameters) && - sd_json_variant_elements(parameters) > 0) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters_obj = NULL; - - r = sd_json_buildo(¶meters_obj, SD_JSON_BUILD_PAIR("parameter", SD_JSON_BUILD_VARIANT(sd_json_variant_by_index(parameters, 0)))); - if (r < 0) - return r; - - return varlink_error(v, VARLINK_ERROR_INVALID_PARAMETER, parameters_obj); - } - - return -EINVAL; -} - -int varlink_error_invalid_parameter_name(Varlink *v, const char *name) { - return varlink_errorbo( - v, - VARLINK_ERROR_INVALID_PARAMETER, - SD_JSON_BUILD_PAIR("parameter", SD_JSON_BUILD_STRING(name))); -} - -int varlink_error_errno(Varlink *v, int error) { - return varlink_errorbo( - v, - VARLINK_ERROR_SYSTEM, - SD_JSON_BUILD_PAIR("errno", SD_JSON_BUILD_INTEGER(abs(error)))); -} - -int varlink_notify(Varlink *v, sd_json_variant *parameters) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *m = NULL; - int r; - - assert_return(v, -EINVAL); - - if (v->state == VARLINK_DISCONNECTED) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENOTCONN), "Not connected."); - - /* If we want to reply with a notify connection but the caller didn't set "more", then return an - * error indicating that we expected to be called with "more" set */ - if (IN_SET(v->state, VARLINK_PROCESSING_METHOD, VARLINK_PENDING_METHOD)) - return varlink_error(v, VARLINK_ERROR_EXPECTED_MORE, NULL); - - if (!IN_SET(v->state, VARLINK_PROCESSING_METHOD_MORE, VARLINK_PENDING_METHOD_MORE)) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "Connection busy."); - - r = varlink_sanitize_parameters(¶meters); - if (r < 0) - return varlink_log_errno(v, r, "Failed to sanitize parameters: %m"); - - r = sd_json_buildo( - &m, - SD_JSON_BUILD_PAIR("parameters", SD_JSON_BUILD_VARIANT(parameters)), - SD_JSON_BUILD_PAIR("continues", SD_JSON_BUILD_BOOLEAN(true))); - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - if (v->current_method) { - const char *bad_field = NULL; - - r = varlink_idl_validate_method_reply(v->current_method, parameters, &bad_field); - if (r < 0) - /* Please adjust test/units/end.sh when updating the log message. */ - varlink_log_errno(v, r, "Return parameters for method reply %s() didn't pass validation on field '%s', ignoring: %m", - v->current_method->name, strna(bad_field)); - } - - r = varlink_enqueue_json(v, m); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enqueue json message: %m"); - - /* No state change, as more is coming */ - return 1; -} - -int varlink_notifyb(Varlink *v, ...) { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - int r; - - assert_return(v, -EINVAL); - - va_start(ap, v); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - - if (r < 0) - return varlink_log_errno(v, r, "Failed to build json message: %m"); - - return varlink_notify(v, parameters); -} - -int varlink_dispatch(Varlink *v, sd_json_variant *parameters, const sd_json_dispatch_field table[], void *userdata) { - const char *bad_field = NULL; - int r; - - assert_return(v, -EINVAL); - assert_return(table, -EINVAL); - - /* A wrapper around json_dispatch_full() that returns a nice InvalidParameter error if we hit a problem with some field. */ - - r = sd_json_dispatch_full(parameters, table, /* bad= */ NULL, /* flags= */ 0, userdata, &bad_field); - if (r < 0) { - if (bad_field) - return varlink_error_invalid_parameter_name(v, bad_field); - return r; - } - - return 0; -} - -int varlink_bind_reply(Varlink *v, VarlinkReply callback) { - assert_return(v, -EINVAL); - - if (callback && v->reply_callback && callback != v->reply_callback) - return varlink_log_errno(v, SYNTHETIC_ERRNO(EBUSY), "A different callback was already set."); - - v->reply_callback = callback; - - return 0; -} - -void* varlink_set_userdata(Varlink *v, void *userdata) { - void *old; - - assert_return(v, NULL); - - old = v->userdata; - v->userdata = userdata; - - return old; -} - -void* varlink_get_userdata(Varlink *v) { - assert_return(v, NULL); - - return v->userdata; -} - -static int varlink_acquire_ucred(Varlink *v) { - int r; - - assert(v); - - if (v->ucred_acquired) - return 0; - - /* If we are connected asymmetrically, let's refuse, since it's not clear if caller wants to know - * peer on read or write fd */ - if (v->input_fd != v->output_fd) - return -EBADF; - - r = getpeercred(v->input_fd, &v->ucred); - if (r < 0) - return r; - - v->ucred_acquired = true; - return 0; -} - -int varlink_get_peer_uid(Varlink *v, uid_t *ret) { - int r; - - assert_return(v, -EINVAL); - assert_return(ret, -EINVAL); - - r = varlink_acquire_ucred(v); - if (r < 0) - return varlink_log_errno(v, r, "Failed to acquire credentials: %m"); - - if (!uid_is_valid(v->ucred.uid)) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENODATA), "Peer UID is invalid."); - - *ret = v->ucred.uid; - return 0; -} - -int varlink_get_peer_gid(Varlink *v, gid_t *ret) { - int r; - - assert_return(v, -EINVAL); - assert_return(ret, -EINVAL); - - r = varlink_acquire_ucred(v); - if (r < 0) - return varlink_log_errno(v, r, "Failed to acquire credentials: %m"); - - if (!gid_is_valid(v->ucred.gid)) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENODATA), "Peer GID is invalid."); - - *ret = v->ucred.gid; - return 0; -} - -int varlink_get_peer_pid(Varlink *v, pid_t *ret) { - int r; - - assert_return(v, -EINVAL); - assert_return(ret, -EINVAL); - - r = varlink_acquire_ucred(v); - if (r < 0) - return varlink_log_errno(v, r, "Failed to acquire credentials: %m"); - - if (!pid_is_valid(v->ucred.pid)) - return varlink_log_errno(v, SYNTHETIC_ERRNO(ENODATA), "Peer uid is invalid."); - - *ret = v->ucred.pid; - return 0; -} - -static int varlink_acquire_pidfd(Varlink *v) { - assert(v); - - if (v->peer_pidfd >= 0) - return 0; - - if (v->input_fd != v->output_fd) - return -EBADF; - - v->peer_pidfd = getpeerpidfd(v->input_fd); - if (v->peer_pidfd < 0) - return v->peer_pidfd; - - return 0; -} - -int varlink_get_peer_pidref(Varlink *v, PidRef *ret) { - int r; - - assert_return(v, -EINVAL); - assert_return(ret, -EINVAL); - - /* Returns r > 0 if we acquired the pidref via SO_PEERPIDFD (i.e. if we can use it for - * authentication). Returns == 0 if we didn't, and the pidref should not be used for - * authentication. */ - - r = varlink_acquire_pidfd(v); - if (r < 0 && !ERRNO_IS_NEG_NOT_SUPPORTED(r)) - return r; - - if (v->peer_pidfd < 0) { - pid_t pid; - - r = varlink_get_peer_pid(v, &pid); - if (r < 0) - return r; - - r = pidref_set_pid(ret, pid); - if (r < 0) - return r; - - return 0; /* didn't get pidfd securely */ - } - - r = pidref_set_pidfd(ret, v->peer_pidfd); - if (r < 0) - return r; - - return 1; /* got pidfd securely */ -} - -int varlink_set_relative_timeout(Varlink *v, usec_t timeout) { - assert_return(v, -EINVAL); - assert_return(timeout > 0, -EINVAL); - - v->timeout = timeout; - return 0; -} - -VarlinkServer *varlink_get_server(Varlink *v) { - assert_return(v, NULL); - - return v->server; -} - -int varlink_set_description(Varlink *v, const char *description) { - assert_return(v, -EINVAL); - - return free_and_strdup(&v->description, description); -} - -static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - Varlink *v = ASSERT_PTR(userdata); - - assert(s); - - handle_revents(v, revents); - (void) varlink_process(v); - - return 1; -} - -static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) { - Varlink *v = ASSERT_PTR(userdata); - - assert(s); - - (void) varlink_process(v); - return 1; -} - -static int defer_callback(sd_event_source *s, void *userdata) { - Varlink *v = ASSERT_PTR(userdata); - - assert(s); - - (void) varlink_process(v); - return 1; -} - -static int prepare_callback(sd_event_source *s, void *userdata) { - Varlink *v = ASSERT_PTR(userdata); - int r, e; - usec_t until; - bool have_timeout; - - assert(s); - - e = varlink_get_events(v); - if (e < 0) - return e; - - if (v->input_event_source == v->output_event_source) - /* Same fd for input + output */ - r = sd_event_source_set_io_events(v->input_event_source, e); - else { - r = sd_event_source_set_io_events(v->input_event_source, e & EPOLLIN); - if (r >= 0) - r = sd_event_source_set_io_events(v->output_event_source, e & EPOLLOUT); - } - if (r < 0) - return varlink_log_errno(v, r, "Failed to set source events: %m"); - - r = varlink_get_timeout(v, &until); - if (r < 0) - return r; - have_timeout = r > 0; - - if (have_timeout) { - r = sd_event_source_set_time(v->time_event_source, until); - if (r < 0) - return varlink_log_errno(v, r, "Failed to set source time: %m"); - } - - r = sd_event_source_set_enabled(v->time_event_source, have_timeout ? SD_EVENT_ON : SD_EVENT_OFF); - if (r < 0) - return varlink_log_errno(v, r, "Failed to enable event source: %m"); - - return 1; -} - -static int quit_callback(sd_event_source *event, void *userdata) { - Varlink *v = ASSERT_PTR(userdata); - - assert(event); - - varlink_flush(v); - varlink_close(v); - - return 1; -} - -int varlink_attach_event(Varlink *v, sd_event *e, int64_t priority) { - int r; - - assert_return(v, -EINVAL); - assert_return(!v->event, -EBUSY); - - if (e) - v->event = sd_event_ref(e); - else { - r = sd_event_default(&v->event); - if (r < 0) - return varlink_log_errno(v, r, "Failed to create event source: %m"); - } - - r = sd_event_add_time(v->event, &v->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, v); - if (r < 0) - goto fail; - - r = sd_event_source_set_priority(v->time_event_source, priority); - if (r < 0) - goto fail; - - (void) sd_event_source_set_description(v->time_event_source, "varlink-time"); - - r = sd_event_add_exit(v->event, &v->quit_event_source, quit_callback, v); - if (r < 0) - goto fail; - - r = sd_event_source_set_priority(v->quit_event_source, priority); - if (r < 0) - goto fail; - - (void) sd_event_source_set_description(v->quit_event_source, "varlink-quit"); - - r = sd_event_add_io(v->event, &v->input_event_source, v->input_fd, 0, io_callback, v); - if (r < 0) - goto fail; - - r = sd_event_source_set_prepare(v->input_event_source, prepare_callback); - if (r < 0) - goto fail; - - r = sd_event_source_set_priority(v->input_event_source, priority); - if (r < 0) - goto fail; - - (void) sd_event_source_set_description(v->input_event_source, "varlink-input"); - - if (v->input_fd == v->output_fd) - v->output_event_source = sd_event_source_ref(v->input_event_source); - else { - r = sd_event_add_io(v->event, &v->output_event_source, v->output_fd, 0, io_callback, v); - if (r < 0) - goto fail; - - r = sd_event_source_set_priority(v->output_event_source, priority); - if (r < 0) - goto fail; - - (void) sd_event_source_set_description(v->output_event_source, "varlink-output"); - } - - r = sd_event_add_defer(v->event, &v->defer_event_source, defer_callback, v); - if (r < 0) - goto fail; - - r = sd_event_source_set_priority(v->defer_event_source, priority); - if (r < 0) - goto fail; - - (void) sd_event_source_set_description(v->defer_event_source, "varlink-defer"); - - return 0; - -fail: - varlink_log_errno(v, r, "Failed to setup event source: %m"); - varlink_detach_event(v); - return r; -} - -void varlink_detach_event(Varlink *v) { - if (!v) - return; - - varlink_detach_event_sources(v); - - v->event = sd_event_unref(v->event); -} - -sd_event *varlink_get_event(Varlink *v) { - assert_return(v, NULL); - - return v->event; -} - -int varlink_push_fd(Varlink *v, int fd) { - int i; - - assert_return(v, -EINVAL); - assert_return(fd >= 0, -EBADF); - - /* Takes an fd to send along with the *next* varlink message sent via this varlink connection. This - * takes ownership of the specified fd. Use varlink_dup_fd() below to duplicate the fd first. */ - - if (!v->allow_fd_passing_output) - return -EPERM; - - if (v->n_pushed_fds >= INT_MAX) - return -ENOMEM; - - if (!GREEDY_REALLOC(v->pushed_fds, v->n_pushed_fds + 1)) - return -ENOMEM; - - i = (int) v->n_pushed_fds; - v->pushed_fds[v->n_pushed_fds++] = fd; - return i; -} - -int varlink_push_dup_fd(Varlink *v, int fd) { - _cleanup_close_ int dp = -1; - int r; - - assert_return(v, -EINVAL); - assert_return(fd >= 0, -EBADF); - - /* Like varlink_push_fd() but duplicates the specified fd instead of taking possession of it */ - - dp = fcntl(fd, F_DUPFD_CLOEXEC, 3); - if (dp < 0) - return -errno; - - r = varlink_push_fd(v, dp); - if (r < 0) - return r; - - TAKE_FD(dp); - return r; -} - -int varlink_reset_fds(Varlink *v) { - assert_return(v, -EINVAL); - - /* Closes all currently pending fds to send. This may be used whenever the caller is in the process - * of putting together a message with fds, and then eventually something fails and they need to - * rollback the fds. Note that this is implicitly called whenever an error reply is sent, see above. */ - - close_many(v->output_fds, v->n_output_fds); - v->n_output_fds = 0; - return 0; -} - -int varlink_peek_fd(Varlink *v, size_t i) { - assert_return(v, -EINVAL); - - /* Returns one of the file descriptors that were received along with the current message. This does - * not duplicate the fd nor invalidate it, it hence remains in our possession. */ - - if (!v->allow_fd_passing_input) - return -EPERM; - - if (i >= v->n_input_fds) - return -ENXIO; - - return v->input_fds[i]; -} - -int varlink_peek_dup_fd(Varlink *v, size_t i) { - int fd; - - fd = varlink_peek_fd(v, i); - if (fd < 0) - return fd; - - return RET_NERRNO(fcntl(fd, F_DUPFD_CLOEXEC, 3)); -} - -int varlink_take_fd(Varlink *v, size_t i) { - assert_return(v, -EINVAL); - - /* Similar to varlink_peek_fd() but the file descriptor's ownership is passed to the caller, and - * we'll invalidate the reference to it under our possession. If called twice in a row will return - * -EBADF */ - - if (!v->allow_fd_passing_input) - return -EPERM; - - if (i >= v->n_input_fds) - return -ENXIO; - - return TAKE_FD(v->input_fds[i]); -} - -static int verify_unix_socket(Varlink *v) { - assert(v); - - /* Returns: - * • 0 if this is an AF_UNIX socket - * • -ENOTSOCK if this is not a socket at all - * • -ENOMEDIUM if this is a socket, but not an AF_UNIX socket - * - * Reminder: - * • v->af is < 0 if we haven't checked what kind of address family the thing is yet. - * • v->af == AF_UNSPEC if we checked but it's not a socket - * • otherwise: v->af contains the address family we determined */ - - if (v->af < 0) { - /* If we have distinct input + output fds, we don't consider ourselves to be connected via a regular - * AF_UNIX socket. */ - if (v->input_fd != v->output_fd) { - v->af = AF_UNSPEC; - return -ENOTSOCK; - } - - struct stat st; - - if (fstat(v->input_fd, &st) < 0) - return -errno; - if (!S_ISSOCK(st.st_mode)) { - v->af = AF_UNSPEC; - return -ENOTSOCK; - } - - v->af = socket_get_family(v->input_fd); - if (v->af < 0) - return v->af; - } - - return v->af == AF_UNIX ? 0 : - v->af == AF_UNSPEC ? -ENOTSOCK : -ENOMEDIUM; -} - -int varlink_set_allow_fd_passing_input(Varlink *v, bool b) { - int r; - - assert_return(v, -EINVAL); - - if (v->allow_fd_passing_input == b) - return 0; - - if (!b) { - v->allow_fd_passing_input = false; - return 1; - } - - r = verify_unix_socket(v); - if (r < 0) - return r; - - v->allow_fd_passing_input = true; - return 0; -} - -int varlink_set_allow_fd_passing_output(Varlink *v, bool b) { - int r; - - assert_return(v, -EINVAL); - - if (v->allow_fd_passing_output == b) - return 0; - - if (!b) { - v->allow_fd_passing_output = false; - return 1; - } - - r = verify_unix_socket(v); - if (r < 0) - return r; - - v->allow_fd_passing_output = true; - return 0; -} - -int varlink_set_input_sensitive(Varlink *v) { - assert_return(v, -EINVAL); - - v->input_sensitive = true; - return 0; -} - -int varlink_server_new(VarlinkServer **ret, VarlinkServerFlags flags) { - _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL; - int r; - - assert_return(ret, -EINVAL); - assert_return((flags & ~_VARLINK_SERVER_FLAGS_ALL) == 0, -EINVAL); - - s = new(VarlinkServer, 1); - if (!s) - return log_oom_debug(); - - *s = (VarlinkServer) { - .n_ref = 1, - .flags = flags, - .connections_max = varlink_server_connections_max(NULL), - .connections_per_uid_max = varlink_server_connections_per_uid_max(NULL), - }; - - r = varlink_server_add_interface_many( - s, - &vl_interface_io_systemd, - &vl_interface_org_varlink_service); - if (r < 0) - return r; - - *ret = TAKE_PTR(s); - return 0; -} - -static VarlinkServer* varlink_server_destroy(VarlinkServer *s) { - char *m; - - if (!s) - return NULL; - - varlink_server_shutdown(s); - - while ((m = hashmap_steal_first_key(s->methods))) - free(m); - - hashmap_free(s->methods); - hashmap_free(s->interfaces); - hashmap_free(s->symbols); - hashmap_free(s->by_uid); - - sd_event_unref(s->event); - - free(s->description); - - return mfree(s); -} - -DEFINE_TRIVIAL_REF_UNREF_FUNC(VarlinkServer, varlink_server, varlink_server_destroy); - -static int validate_connection(VarlinkServer *server, const struct ucred *ucred) { - int allowed = -1; - - assert(server); - assert(ucred); - - if (FLAGS_SET(server->flags, VARLINK_SERVER_ROOT_ONLY)) - allowed = ucred->uid == 0; - - if (FLAGS_SET(server->flags, VARLINK_SERVER_MYSELF_ONLY)) - allowed = allowed > 0 || ucred->uid == getuid(); - - if (allowed == 0) { /* Allow access when it is explicitly allowed or when neither - * VARLINK_SERVER_ROOT_ONLY nor VARLINK_SERVER_MYSELF_ONLY are specified. */ - varlink_server_log(server, "Unprivileged client attempted connection, refusing."); - return 0; - } - - if (server->n_connections >= server->connections_max) { - varlink_server_log(server, "Connection limit of %u reached, refusing.", server->connections_max); - return 0; - } - - if (FLAGS_SET(server->flags, VARLINK_SERVER_ACCOUNT_UID)) { - unsigned c; - - if (!uid_is_valid(ucred->uid)) { - varlink_server_log(server, "Client with invalid UID attempted connection, refusing."); - return 0; - } - - c = PTR_TO_UINT(hashmap_get(server->by_uid, UID_TO_PTR(ucred->uid))); - if (c >= server->connections_per_uid_max) { - varlink_server_log(server, "Per-UID connection limit of %u reached, refusing.", - server->connections_per_uid_max); - return 0; - } - } - - return 1; -} - -static int count_connection(VarlinkServer *server, const struct ucred *ucred) { - unsigned c; - int r; - - assert(server); - assert(ucred); - - server->n_connections++; - - if (FLAGS_SET(server->flags, VARLINK_SERVER_ACCOUNT_UID)) { - assert(uid_is_valid(ucred->uid)); - - r = hashmap_ensure_allocated(&server->by_uid, NULL); - if (r < 0) - return varlink_server_log_errno(server, r, "Failed to allocate UID hash table: %m"); - - c = PTR_TO_UINT(hashmap_get(server->by_uid, UID_TO_PTR(ucred->uid))); - - varlink_server_log(server, "Connections of user " UID_FMT ": %u (of %u max)", - ucred->uid, c, server->connections_per_uid_max); - - r = hashmap_replace(server->by_uid, UID_TO_PTR(ucred->uid), UINT_TO_PTR(c + 1)); - if (r < 0) - return varlink_server_log_errno(server, r, "Failed to increment counter in UID hash table: %m"); - } - - return 0; -} - -int varlink_server_add_connection_pair( - VarlinkServer *server, - int input_fd, - int output_fd, - const struct ucred *override_ucred, - Varlink **ret) { - - _cleanup_(varlink_unrefp) Varlink *v = NULL; - struct ucred ucred = UCRED_INVALID; - bool ucred_acquired; - int r; - - assert_return(server, -EINVAL); - assert_return(input_fd >= 0, -EBADF); - assert_return(output_fd >= 0, -EBADF); - - if ((server->flags & (VARLINK_SERVER_ROOT_ONLY|VARLINK_SERVER_ACCOUNT_UID)) != 0) { - - if (override_ucred) - ucred = *override_ucred; - else { - if (input_fd != output_fd) - return varlink_server_log_errno(server, SYNTHETIC_ERRNO(EOPNOTSUPP), "Cannot determine peer identity of connection with separate input/output, refusing: %m"); - - r = getpeercred(input_fd, &ucred); - if (r < 0) - return varlink_server_log_errno(server, r, "Failed to acquire peer credentials of incoming socket, refusing: %m"); - } - - ucred_acquired = true; - - r = validate_connection(server, &ucred); - if (r < 0) - return r; - if (r == 0) - return -EPERM; - } else - ucred_acquired = false; - - r = varlink_new(&v); - if (r < 0) - return varlink_server_log_errno(server, r, "Failed to allocate connection object: %m"); - - r = count_connection(server, &ucred); - if (r < 0) - return r; - - v->input_fd = input_fd; - v->output_fd = output_fd; - if (server->flags & VARLINK_SERVER_INHERIT_USERDATA) - v->userdata = server->userdata; - - if (ucred_acquired) { - v->ucred = ucred; - v->ucred_acquired = true; - } - - _cleanup_free_ char *desc = NULL; - if (asprintf(&desc, "%s-%i-%i", varlink_server_description(server), input_fd, output_fd) >= 0) - v->description = TAKE_PTR(desc); - - /* Link up the server and the connection, and take reference in both directions. Note that the - * reference on the connection is left dangling. It will be dropped when the connection is closed, - * which happens in varlink_close(), including in the event loop quit callback. */ - v->server = varlink_server_ref(server); - varlink_ref(v); - - varlink_set_state(v, VARLINK_IDLE_SERVER); - - if (server->event) { - r = varlink_attach_event(v, server->event, server->event_priority); - if (r < 0) { - varlink_log_errno(v, r, "Failed to attach new connection: %m"); - TAKE_FD(v->input_fd); /* take the fd out of the connection again */ - TAKE_FD(v->output_fd); - varlink_close(v); - return r; - } - } - - if (ret) - *ret = v; - - return 0; -} - -int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret) { - return varlink_server_add_connection_pair(server, fd, fd, /* override_ucred= */ NULL, ret); -} - -static VarlinkServerSocket *varlink_server_socket_free(VarlinkServerSocket *ss) { - if (!ss) - return NULL; - - free(ss->address); - return mfree(ss); -} - -DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkServerSocket *, varlink_server_socket_free); - -static int connect_callback(sd_event_source *source, int fd, uint32_t revents, void *userdata) { - VarlinkServerSocket *ss = ASSERT_PTR(userdata); - _cleanup_close_ int cfd = -EBADF; - Varlink *v = NULL; - int r; - - assert(source); - - varlink_server_log(ss->server, "New incoming connection."); - - cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); - if (cfd < 0) { - if (ERRNO_IS_ACCEPT_AGAIN(errno)) - return 0; - - return varlink_server_log_errno(ss->server, errno, "Failed to accept incoming socket: %m"); - } - - r = varlink_server_add_connection(ss->server, cfd, &v); - if (r < 0) - return 0; - - TAKE_FD(cfd); - - if (FLAGS_SET(ss->server->flags, VARLINK_SERVER_INPUT_SENSITIVE)) - varlink_set_input_sensitive(v); - - if (ss->server->connect_callback) { - r = ss->server->connect_callback(ss->server, v, ss->server->userdata); - if (r < 0) { - varlink_log_errno(v, r, "Connection callback returned error, disconnecting client: %m"); - varlink_close(v); - return 0; - } - } - - return 0; -} - -static int varlink_server_create_listen_fd_socket(VarlinkServer *s, int fd, VarlinkServerSocket **ret_ss) { - _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL; - int r; - - assert(s); - assert(fd >= 0); - assert(ret_ss); - - ss = new(VarlinkServerSocket, 1); - if (!ss) - return log_oom_debug(); - - *ss = (VarlinkServerSocket) { - .server = s, - .fd = fd, - }; - - if (s->event) { - r = sd_event_add_io(s->event, &ss->event_source, fd, EPOLLIN, connect_callback, ss); - if (r < 0) - return r; - - r = sd_event_source_set_priority(ss->event_source, s->event_priority); - if (r < 0) - return r; - } - - *ret_ss = TAKE_PTR(ss); - return 0; -} - -int varlink_server_listen_fd(VarlinkServer *s, int fd) { - _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL; - int r; - - assert_return(s, -EINVAL); - assert_return(fd >= 0, -EBADF); - - r = fd_nonblock(fd, true); - if (r < 0) - return r; - - r = fd_cloexec(fd, true); - if (r < 0) - return r; - - r = varlink_server_create_listen_fd_socket(s, fd, &ss); - if (r < 0) - return r; - - LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss)); - return 0; -} - -int varlink_server_listen_address(VarlinkServer *s, const char *address, mode_t m) { - _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL; - union sockaddr_union sockaddr; - socklen_t sockaddr_len; - _cleanup_close_ int fd = -EBADF; - int r; - - assert_return(s, -EINVAL); - assert_return(address, -EINVAL); - assert_return((m & ~0777) == 0, -EINVAL); - - r = sockaddr_un_set_path(&sockaddr.un, address); - if (r < 0) - return r; - sockaddr_len = r; - - fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - if (fd < 0) - return -errno; - - fd = fd_move_above_stdio(fd); - - (void) sockaddr_un_unlink(&sockaddr.un); - - WITH_UMASK(~m & 0777) { - r = mac_selinux_bind(fd, &sockaddr.sa, sockaddr_len); - if (r < 0) - return r; - } - - if (listen(fd, SOMAXCONN_DELUXE) < 0) - return -errno; - - r = varlink_server_create_listen_fd_socket(s, fd, &ss); - if (r < 0) - return r; - - r = free_and_strdup(&ss->address, address); - if (r < 0) - return r; - - LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss)); - TAKE_FD(fd); - return 0; -} - -int varlink_server_add_connection_stdio(VarlinkServer *s, Varlink **ret) { - _cleanup_close_ int input_fd = -EBADF, output_fd = -EBADF; - int r; - - assert_return(s, -EINVAL); - - input_fd = fcntl(STDIN_FILENO, F_DUPFD_CLOEXEC, 3); - if (input_fd < 0) - return -errno; - - output_fd = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 3); - if (output_fd < 0) - return -errno; - - r = rearrange_stdio(-EBADF, -EBADF, STDERR_FILENO); - if (r < 0) - return r; - - r = fd_nonblock(input_fd, true); - if (r < 0) - return r; - - r = fd_nonblock(output_fd, true); - if (r < 0) - return r; - - struct stat input_st; - if (fstat(input_fd, &input_st) < 0) - return -errno; - - struct stat output_st; - if (fstat(output_fd, &output_st) < 0) - return -errno; - - /* If stdin/stdout are both pipes and have the same owning uid/gid then let's synthesize a "struct - * ucred" from the owning UID/GID, since we got them passed in with such ownership. We'll not fill in - * the PID however, since there's no way to know which process created a pipe. */ - struct ucred ucred, *pucred; - if (S_ISFIFO(input_st.st_mode) && - S_ISFIFO(output_st.st_mode) && - input_st.st_uid == output_st.st_uid && - input_st.st_gid == output_st.st_gid) { - ucred = (struct ucred) { - .uid = input_st.st_uid, - .gid = input_st.st_gid, - }; - pucred = &ucred; - } else - pucred = NULL; - - r = varlink_server_add_connection_pair(s, input_fd, output_fd, pucred, ret); - if (r < 0) - return r; - - TAKE_FD(input_fd); - TAKE_FD(output_fd); - - return 0; -} - -int varlink_server_listen_auto(VarlinkServer *s) { - _cleanup_strv_free_ char **names = NULL; - int r, n = 0; - - assert_return(s, -EINVAL); - - /* Adds all passed fds marked as "varlink" to our varlink server. These fds can either refer to a - * listening socket or to a connection socket. - * - * See https://varlink.org/#activation for the environment variables this is backed by and the - * recommended "varlink" identifier in $LISTEN_FDNAMES. */ - - r = sd_listen_fds_with_names(/* unset_environment= */ false, &names); - if (r < 0) - return r; - - for (int i = 0; i < r; i++) { - int b, fd; - socklen_t l = sizeof(b); - - if (!streq(names[i], "varlink")) - continue; - - fd = SD_LISTEN_FDS_START + i; - - if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0) - return -errno; - - assert(l == sizeof(b)); - - if (b) /* Listening socket? */ - r = varlink_server_listen_fd(s, fd); - else /* Otherwise assume connection socket */ - r = varlink_server_add_connection(s, fd, NULL); - if (r < 0) - return r; - - n++; - } - - /* Let's listen on an explicitly specified address */ - const char *e = secure_getenv("SYSTEMD_VARLINK_LISTEN"); - if (e) { - if (streq(e, "-")) - r = varlink_server_add_connection_stdio(s, /* ret= */ NULL); - else - r = varlink_server_listen_address(s, e, FLAGS_SET(s->flags, VARLINK_SERVER_ROOT_ONLY) ? 0600 : 0666); - if (r < 0) - return r; - - n++; - } - - return n; -} - -void* varlink_server_set_userdata(VarlinkServer *s, void *userdata) { - void *ret; - - assert_return(s, NULL); - - ret = s->userdata; - s->userdata = userdata; - - return ret; -} - -void* varlink_server_get_userdata(VarlinkServer *s) { - assert_return(s, NULL); - - return s->userdata; -} - -int varlink_server_loop_auto(VarlinkServer *server) { - _cleanup_(sd_event_unrefp) sd_event *event = NULL; - int r; - - assert_return(server, -EINVAL); - assert_return(!server->event, -EBUSY); - - /* Runs a Varlink service event loop populated with a passed fd. Exits on the last connection. */ - - r = sd_event_new(&event); - if (r < 0) - return r; - - r = varlink_server_set_exit_on_idle(server, true); - if (r < 0) - return r; - - r = varlink_server_attach_event(server, event, 0); - if (r < 0) - return r; - - r = varlink_server_listen_auto(server); - if (r < 0) - return r; - - return sd_event_loop(event); -} - -static VarlinkServerSocket* varlink_server_socket_destroy(VarlinkServerSocket *ss) { - if (!ss) - return NULL; - - if (ss->server) - LIST_REMOVE(sockets, ss->server->sockets, ss); - - sd_event_source_disable_unref(ss->event_source); - - free(ss->address); - safe_close(ss->fd); - - return mfree(ss); -} - -int varlink_server_shutdown(VarlinkServer *s) { - assert_return(s, -EINVAL); - - while (s->sockets) - varlink_server_socket_destroy(s->sockets); - - return 0; -} - -static void varlink_server_test_exit_on_idle(VarlinkServer *s) { - assert(s); - - if (s->exit_on_idle && s->event && s->n_connections == 0) - (void) sd_event_exit(s->event, 0); -} - -int varlink_server_set_exit_on_idle(VarlinkServer *s, bool b) { - assert_return(s, -EINVAL); - - s->exit_on_idle = b; - varlink_server_test_exit_on_idle(s); - return 0; -} - -static int varlink_server_add_socket_event_source(VarlinkServer *s, VarlinkServerSocket *ss, int64_t priority) { - _cleanup_(sd_event_source_unrefp) sd_event_source *es = NULL; - int r; - - assert(s); - assert(s->event); - assert(ss); - assert(ss->fd >= 0); - assert(!ss->event_source); - - r = sd_event_add_io(s->event, &es, ss->fd, EPOLLIN, connect_callback, ss); - if (r < 0) - return r; - - r = sd_event_source_set_priority(es, priority); - if (r < 0) - return r; - - ss->event_source = TAKE_PTR(es); - return 0; -} - -int varlink_server_attach_event(VarlinkServer *s, sd_event *e, int64_t priority) { - int r; - - assert_return(s, -EINVAL); - assert_return(!s->event, -EBUSY); - - if (e) - s->event = sd_event_ref(e); - else { - r = sd_event_default(&s->event); - if (r < 0) - return r; - } - - LIST_FOREACH(sockets, ss, s->sockets) { - r = varlink_server_add_socket_event_source(s, ss, priority); - if (r < 0) - goto fail; - } - - s->event_priority = priority; - return 0; - -fail: - varlink_server_detach_event(s); - return r; -} - -int varlink_server_detach_event(VarlinkServer *s) { - assert_return(s, -EINVAL); - - LIST_FOREACH(sockets, ss, s->sockets) - ss->event_source = sd_event_source_disable_unref(ss->event_source); - - s->event = sd_event_unref(s->event); - return 0; -} - -sd_event *varlink_server_get_event(VarlinkServer *s) { - assert_return(s, NULL); - - return s->event; -} - -static bool varlink_symbol_in_interface(const char *method, const char *interface) { - const char *p; - - assert(method); - assert(interface); - - p = startswith(method, interface); - if (!p) - return false; - - if (*p != '.') - return false; - - return !strchr(p+1, '.'); -} - -int varlink_server_bind_method(VarlinkServer *s, const char *method, VarlinkMethod callback) { - _cleanup_free_ char *m = NULL; - int r; - - assert_return(s, -EINVAL); - assert_return(method, -EINVAL); - assert_return(callback, -EINVAL); - - if (varlink_symbol_in_interface(method, "org.varlink.service") || - varlink_symbol_in_interface(method, "io.systemd")) - return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EEXIST), "Cannot bind server to '%s'.", method); - - m = strdup(method); - if (!m) - return log_oom_debug(); - - r = hashmap_ensure_put(&s->methods, &string_hash_ops, m, callback); - if (r == -ENOMEM) - return log_oom_debug(); - if (r < 0) - return varlink_server_log_errno(s, r, "Failed to register callback: %m"); - if (r > 0) - TAKE_PTR(m); - - return 0; -} - -int varlink_server_bind_method_many_internal(VarlinkServer *s, ...) { - va_list ap; - int r = 0; - - assert_return(s, -EINVAL); - - va_start(ap, s); - for (;;) { - VarlinkMethod callback; - const char *method; - - method = va_arg(ap, const char *); - if (!method) - break; - - callback = va_arg(ap, VarlinkMethod); - - r = varlink_server_bind_method(s, method, callback); - if (r < 0) - break; - } - va_end(ap); - - return r; -} - -int varlink_server_bind_connect(VarlinkServer *s, VarlinkConnect callback) { - assert_return(s, -EINVAL); - - if (callback && s->connect_callback && callback != s->connect_callback) - return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EBUSY), "A different callback was already set."); - - s->connect_callback = callback; - return 0; -} - -int varlink_server_bind_disconnect(VarlinkServer *s, VarlinkDisconnect callback) { - assert_return(s, -EINVAL); - - if (callback && s->disconnect_callback && callback != s->disconnect_callback) - return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EBUSY), "A different callback was already set."); - - s->disconnect_callback = callback; - return 0; -} - -int varlink_server_add_interface(VarlinkServer *s, const VarlinkInterface *interface) { - int r; - - assert_return(s, -EINVAL); - assert_return(interface, -EINVAL); - assert_return(interface->name, -EINVAL); - - if (hashmap_contains(s->interfaces, interface->name)) - return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EEXIST), "Duplicate registration of interface '%s'.", interface->name); - - r = hashmap_ensure_put(&s->interfaces, &string_hash_ops, interface->name, (void*) interface); - if (r < 0) - return r; - - for (const VarlinkSymbol *const*symbol = interface->symbols; *symbol; symbol++) { - _cleanup_free_ char *j = NULL; - - /* We only ever want to validate method calls/replies and errors against the interface - * definitions, hence don't bother with the type symbols */ - if (!IN_SET((*symbol)->symbol_type, VARLINK_METHOD, VARLINK_ERROR)) - continue; - - j = strjoin(interface->name, ".", (*symbol)->name); - if (!j) - return -ENOMEM; - - r = hashmap_ensure_put(&s->symbols, &string_hash_ops_free, j, (void*) *symbol); - if (r < 0) - return r; - - TAKE_PTR(j); - } - - return 0; -} - -int varlink_server_add_interface_many_internal(VarlinkServer *s, ...) { - va_list ap; - int r = 0; - - assert_return(s, -EINVAL); - - va_start(ap, s); - for (;;) { - const VarlinkInterface *interface = va_arg(ap, const VarlinkInterface*); - if (!interface) - break; - - r = varlink_server_add_interface(s, interface); - if (r < 0) - break; - } - va_end(ap); - - return r; -} - -unsigned varlink_server_connections_max(VarlinkServer *s) { - int dts; - - /* If a server is specified, return the setting for that server, otherwise the default value */ - if (s) - return s->connections_max; - - dts = getdtablesize(); - assert_se(dts > 0); - - /* Make sure we never use up more than ¾th of RLIMIT_NOFILE for IPC */ - if (VARLINK_DEFAULT_CONNECTIONS_MAX > (unsigned) dts / 4 * 3) - return dts / 4 * 3; - - return VARLINK_DEFAULT_CONNECTIONS_MAX; -} - -unsigned varlink_server_connections_per_uid_max(VarlinkServer *s) { - unsigned m; - - if (s) - return s->connections_per_uid_max; - - /* Make sure to never use up more than ¾th of available connections for a single user */ - m = varlink_server_connections_max(NULL); - if (VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX > m) - return m / 4 * 3; - - return VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX; -} - -int varlink_server_set_connections_per_uid_max(VarlinkServer *s, unsigned m) { - assert_return(s, -EINVAL); - assert_return(m > 0, -EINVAL); - - s->connections_per_uid_max = m; - return 0; -} - -int varlink_server_set_connections_max(VarlinkServer *s, unsigned m) { - assert_return(s, -EINVAL); - assert_return(m > 0, -EINVAL); - - s->connections_max = m; - return 0; -} - -unsigned varlink_server_current_connections(VarlinkServer *s) { - - if (!s) /* Unallocated servers have zero connections */ - return 0; - - return s->n_connections; -} - -int varlink_server_set_description(VarlinkServer *s, const char *description) { - assert_return(s, -EINVAL); - - return free_and_strdup(&s->description, description); -} - -int varlink_server_serialize(VarlinkServer *s, FILE *f, FDSet *fds) { - assert(f); - assert(fds); - - if (!s) - return 0; - - LIST_FOREACH(sockets, ss, s->sockets) { - int copy; - - assert(ss->address); - assert(ss->fd >= 0); - - fprintf(f, "varlink-server-socket-address=%s", ss->address); - - /* If we fail to serialize the fd, it will be considered an error during deserialization */ - copy = fdset_put_dup(fds, ss->fd); - if (copy < 0) - return copy; - - fprintf(f, " varlink-server-socket-fd=%i", copy); - - fputc('\n', f); - } - - return 0; -} - -int varlink_server_deserialize_one(VarlinkServer *s, const char *value, FDSet *fds) { - _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL; - _cleanup_free_ char *address = NULL; - const char *v = ASSERT_PTR(value); - int r, fd = -EBADF; - char *buf; - size_t n; - - assert(s); - assert(fds); - - n = strcspn(v, " "); - address = strndup(v, n); - if (!address) - return log_oom_debug(); - - if (v[n] != ' ') - return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EINVAL), - "Failed to deserialize VarlinkServerSocket: %s: %m", value); - v = startswith(v + n + 1, "varlink-server-socket-fd="); - if (!v) - return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EINVAL), - "Failed to deserialize VarlinkServerSocket fd %s: %m", value); - - n = strcspn(v, " "); - buf = strndupa_safe(v, n); - - fd = parse_fd(buf); - if (fd < 0) - return varlink_server_log_errno(s, fd, "Unable to parse VarlinkServerSocket varlink-server-socket-fd=%s: %m", buf); - if (!fdset_contains(fds, fd)) - return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EBADF), - "VarlinkServerSocket varlink-server-socket-fd= has unknown fd %d: %m", fd); - - ss = new(VarlinkServerSocket, 1); - if (!ss) - return log_oom_debug(); - - *ss = (VarlinkServerSocket) { - .server = s, - .address = TAKE_PTR(address), - .fd = fdset_remove(fds, fd), - }; - - r = varlink_server_add_socket_event_source(s, ss, SD_EVENT_PRIORITY_NORMAL); - if (r < 0) - return varlink_server_log_errno(s, r, "Failed to add VarlinkServerSocket event source to the event loop: %m"); - - LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss)); - return 0; -} - -int varlink_invocation(VarlinkInvocationFlags flags) { - _cleanup_strv_free_ char **names = NULL; - int r, b; - socklen_t l = sizeof(b); - - /* Returns true if this is a "pure" varlink server invocation, i.e. with one fd passed. */ - - const char *e = secure_getenv("SYSTEMD_VARLINK_LISTEN"); /* Permit an explicit override */ - if (e) - return true; - - r = sd_listen_fds_with_names(/* unset_environment= */ false, &names); - if (r < 0) - return r; - if (r == 0) - return false; - if (r > 1) - return -ETOOMANYREFS; - - if (!strv_equal(names, STRV_MAKE("varlink"))) - return false; - - if (FLAGS_SET(flags, VARLINK_ALLOW_LISTEN|VARLINK_ALLOW_ACCEPT)) /* Both flags set? Then allow everything */ - return true; - - if ((flags & (VARLINK_ALLOW_LISTEN|VARLINK_ALLOW_ACCEPT)) == 0) /* Neither is set, then fail */ - return -EISCONN; - - if (getsockopt(SD_LISTEN_FDS_START, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0) - return -errno; - - assert(l == sizeof(b)); - - if (!FLAGS_SET(flags, b ? VARLINK_ALLOW_LISTEN : VARLINK_ALLOW_ACCEPT)) - return -EISCONN; - - return true; -} - -int varlink_error_to_errno(const char *error, sd_json_variant *parameters) { - static const struct { - const char *error; - int value; - } table[] = { - { VARLINK_ERROR_DISCONNECTED, -ECONNRESET }, - { VARLINK_ERROR_TIMEOUT, -ETIMEDOUT }, - { VARLINK_ERROR_PROTOCOL, -EPROTO }, - { VARLINK_ERROR_INTERFACE_NOT_FOUND, -EADDRNOTAVAIL }, - { VARLINK_ERROR_METHOD_NOT_FOUND, -ENXIO }, - { VARLINK_ERROR_METHOD_NOT_IMPLEMENTED, -ENOTTY }, - { VARLINK_ERROR_INVALID_PARAMETER, -EINVAL }, - { VARLINK_ERROR_PERMISSION_DENIED, -EACCES }, - { VARLINK_ERROR_EXPECTED_MORE, -EBADE }, - }; - - if (!error) - return 0; - - FOREACH_ELEMENT(t, table) - if (streq(error, t->error)) - return t->value; - - if (streq(error, VARLINK_ERROR_SYSTEM) && parameters) { - sd_json_variant *e; - - e = sd_json_variant_by_key(parameters, "errno"); - if (sd_json_variant_is_integer(e)) { - int64_t i; - - i = sd_json_variant_integer(e); - if (i > 0 && i < ERRNO_MAX) - return -i; - } - } - - return -EBADR; /* Catch-all */ -} - -int varlink_many_notifyb(Set *s, ...) { - int r; - - /* Equivalent to varlink_notifyb(), but does this for each entry of the supplied set of Varlink connections */ - - if (set_isempty(s)) - return 0; - - _cleanup_(sd_json_variant_unrefp) sd_json_variant *parameters = NULL; - va_list ap; - va_start(ap, s); - r = sd_json_buildv(¶meters, ap); - va_end(ap); - if (r < 0) - return r; - - int ret = 1; - Varlink *link; - SET_FOREACH(link, s) - RET_GATHER(ret, varlink_notify(link, parameters)); - - return ret; -} - -int varlink_many_reply(Set *s, sd_json_variant *parameters) { - if (set_isempty(s)) - return 0; - - int ret = 1; - Varlink *link; - SET_FOREACH(link, s) - RET_GATHER(ret, varlink_reply(link, parameters)); - - return ret; -} - -int varlink_many_error(Set *s, const char *error_id, sd_json_variant *parameters) { - if (set_isempty(s)) - return 0; - - int ret = 1; - Varlink *link; - SET_FOREACH(link, s) - RET_GATHER(ret, varlink_error(link, error_id, parameters)); - - return ret; -} diff --git a/src/shared/varlink.h b/src/shared/varlink.h deleted file mode 100644 index 47eed171de..0000000000 --- a/src/shared/varlink.h +++ /dev/null @@ -1,301 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include <sys/socket.h> - -#include "sd-event.h" -#include "sd-json.h" - -#include "pidref.h" -#include "set.h" -#include "time-util.h" -#include "varlink-idl.h" - -/* A minimal Varlink implementation. We only implement the minimal, obvious bits here though. No validation, - * no introspection, no name service, just the stuff actually needed. - * - * You might wonder why we aren't using libvarlink here? Varlink is a very simple protocol, which allows us - * to write our own implementation relatively easily. However, the main reasons are these: - * - * • We want to use our own JSON subsystem, with all the benefits that brings (i.e. accurate unsigned+signed - * 64-bit integers, full fuzzing, logging during parsing and so on). If we'd want to use that with - * libvarlink we'd have to serialize and deserialize all the time from its own representation which is - * inefficient and nasty. - * - * • We want integration into sd-event, but also synchronous event-loop-less operation - * - * • We need proper per-UID accounting and access control, since we want to allow communication between - * unprivileged clients and privileged servers. - * - * • And of course, we don't want the name service and introspection stuff for now (though that might - * change). - */ - -typedef struct Varlink Varlink; -typedef struct VarlinkServer VarlinkServer; - -typedef enum VarlinkReplyFlags { - VARLINK_REPLY_ERROR = 1 << 0, - VARLINK_REPLY_CONTINUES = 1 << 1, - VARLINK_REPLY_LOCAL = 1 << 2, -} VarlinkReplyFlags; - -typedef enum VarlinkMethodFlags { - VARLINK_METHOD_ONEWAY = 1 << 0, - VARLINK_METHOD_MORE = 2 << 1, -} VarlinkMethodFlags; - -typedef enum VarlinkServerFlags { - VARLINK_SERVER_ROOT_ONLY = 1 << 0, /* Only accessible by root */ - VARLINK_SERVER_MYSELF_ONLY = 1 << 1, /* Only accessible by our own UID */ - VARLINK_SERVER_ACCOUNT_UID = 1 << 2, /* Do per user accounting */ - VARLINK_SERVER_INHERIT_USERDATA = 1 << 3, /* Initialize Varlink connection userdata from VarlinkServer userdata */ - VARLINK_SERVER_INPUT_SENSITIVE = 1 << 4, /* Automatically mark al connection input as sensitive */ - _VARLINK_SERVER_FLAGS_ALL = (1 << 5) - 1, -} VarlinkServerFlags; - -typedef int (*VarlinkMethod)(Varlink *link, sd_json_variant *parameters, VarlinkMethodFlags flags, void *userdata); -typedef int (*VarlinkReply)(Varlink *link, sd_json_variant *parameters, const char *error_id, VarlinkReplyFlags flags, void *userdata); -typedef int (*VarlinkConnect)(VarlinkServer *server, Varlink *link, void *userdata); -typedef void (*VarlinkDisconnect)(VarlinkServer *server, Varlink *link, void *userdata); - -int varlink_connect_address(Varlink **ret, const char *address); -int varlink_connect_exec(Varlink **ret, const char *command, char **argv); -int varlink_connect_url(Varlink **ret, const char *url); -int varlink_connect_fd(Varlink **ret, int fd); -int varlink_connect_fd_pair(Varlink **ret, int input_fd, int output_fd, const struct ucred *override_ucred); - -Varlink* varlink_ref(Varlink *link); -Varlink* varlink_unref(Varlink *v); - -int varlink_get_fd(Varlink *v); -int varlink_get_events(Varlink *v); -int varlink_get_timeout(Varlink *v, usec_t *ret); - -int varlink_attach_event(Varlink *v, sd_event *e, int64_t priority); -void varlink_detach_event(Varlink *v); -sd_event *varlink_get_event(Varlink *v); - -int varlink_process(Varlink *v); -int varlink_wait(Varlink *v, usec_t timeout); - -int varlink_is_idle(Varlink *v); - -int varlink_flush(Varlink *v); -int varlink_close(Varlink *v); - -Varlink* varlink_flush_close_unref(Varlink *v); -Varlink* varlink_close_unref(Varlink *v); - -/* Enqueue method call, not expecting a reply */ -int varlink_send(Varlink *v, const char *method, sd_json_variant *parameters); -int varlink_sendb(Varlink *v, const char *method, ...); -#define varlink_sendbo(v, method, ...) \ - varlink_sendb((v), (method), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) - -/* Send method call and wait for reply */ -int varlink_call_full(Varlink *v, const char *method, sd_json_variant *parameters, sd_json_variant **ret_parameters, const char **ret_error_id, VarlinkReplyFlags *ret_flags); -static inline int varlink_call(Varlink *v, const char *method, sd_json_variant *parameters, sd_json_variant **ret_parameters, const char **ret_error_id) { - return varlink_call_full(v, method, parameters, ret_parameters, ret_error_id, NULL); -} -int varlink_call_and_log(Varlink *v, const char *method, sd_json_variant *parameters, sd_json_variant **ret_parameters); - -int varlink_callb_ap(Varlink *v, const char *method, sd_json_variant **ret_parameters, const char **ret_error_id, VarlinkReplyFlags *ret_flags, va_list ap); -static inline int varlink_callb_full(Varlink *v, const char *method, sd_json_variant **ret_parameters, const char **ret_error_id, VarlinkReplyFlags *ret_flags, ...) { - va_list ap; - int r; - - va_start(ap, ret_flags); - r = varlink_callb_ap(v, method, ret_parameters, ret_error_id, ret_flags, ap); - va_end(ap); - return r; -} -#define varlink_callbo_full(v, method, ret_parameters, ret_error_id, ret_flags, ...) \ - varlink_callb_full((v), (method), (ret_parameters), (ret_error_id), (ret_flags), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) -static inline int varlink_callb(Varlink *v, const char *method, sd_json_variant **ret_parameters, const char **ret_error_id, ...) { - va_list ap; - int r; - - va_start(ap, ret_error_id); - r = varlink_callb_ap(v, method, ret_parameters, ret_error_id, NULL, ap); - va_end(ap); - return r; -} -#define varlink_callbo(v, method, ret_parameters, ret_error_id, ...) \ - varlink_callb((v), (method), (ret_parameters), (ret_error_id), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) -int varlink_callb_and_log(Varlink *v, const char *method, sd_json_variant **ret_parameters, ...); -#define varlink_callbo_and_log(v, method, ret_parameters, ...) \ - varlink_callb_and_log((v), (method), (ret_parameters), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) - -/* Send method call and begin collecting all 'more' replies into an array, finishing when a final reply is sent */ -int varlink_collect_full(Varlink *v, const char *method, sd_json_variant *parameters, sd_json_variant **ret_parameters, const char **ret_error_id, VarlinkReplyFlags *ret_flags); -static inline int varlink_collect(Varlink *v, const char *method, sd_json_variant *parameters, sd_json_variant **ret_parameters, const char **ret_error_id) { - return varlink_collect_full(v, method, parameters, ret_parameters, ret_error_id, NULL); -} -int varlink_collectb(Varlink *v, const char *method, sd_json_variant **ret_parameters, const char **ret_error_id, ...); -#define varlink_collectbo(v, method, ret_parameters, ret_error_id, ...) \ - varlink_collectb((v), (method), (ret_parameters), (ret_error_id), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) - -/* Enqueue method call, expect a reply, which is eventually delivered to the reply callback */ -int varlink_invoke(Varlink *v, const char *method, sd_json_variant *parameters); -int varlink_invokeb(Varlink *v, const char *method, ...); -#define varlink_invokebo(v, method, ...) \ - varlink_invokeb((v), (method), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) - -/* Enqueue method call, expect a reply now, and possibly more later, which are all delivered to the reply callback */ -int varlink_observe(Varlink *v, const char *method, sd_json_variant *parameters); -int varlink_observeb(Varlink *v, const char *method, ...); -#define varlink_observebo(v, method, ...) \ - varlink_observeb((v), (method), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) - -/* Enqueue a final reply */ -int varlink_reply(Varlink *v, sd_json_variant *parameters); -int varlink_replyb(Varlink *v, ...); -#define varlink_replybo(v, ...) \ - varlink_replyb((v), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) - -/* Enqueue a (final) error */ -int varlink_error(Varlink *v, const char *error_id, sd_json_variant *parameters); -int varlink_errorb(Varlink *v, const char *error_id, ...); -#define varlink_errorbo(v, error_id, ...) \ - varlink_errorb((v), (error_id), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) -int varlink_error_invalid_parameter(Varlink *v, sd_json_variant *parameters); -int varlink_error_invalid_parameter_name(Varlink *v, const char *name); -int varlink_error_errno(Varlink *v, int error); - -/* Enqueue a "more" reply */ -int varlink_notify(Varlink *v, sd_json_variant *parameters); -int varlink_notifyb(Varlink *v, ...); -#define varlink_notifybo(v, ...) \ - varlink_notifyb((v), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) - -/* Ask for the current message to be dispatched again */ -int varlink_dispatch_again(Varlink *v); - -/* Get the currently processed incoming message */ -int varlink_get_current_parameters(Varlink *v, sd_json_variant **ret); - -/* Parsing incoming data via json_dispatch() and generate a nice error on parse errors */ -int varlink_dispatch(Varlink *v, sd_json_variant *parameters, const sd_json_dispatch_field table[], void *userdata); - -/* Write outgoing fds into the socket (to be associated with the next enqueued message) */ -int varlink_push_fd(Varlink *v, int fd); -int varlink_push_dup_fd(Varlink *v, int fd); -int varlink_reset_fds(Varlink *v); - -/* Read incoming fds from the socket (associated with the currently handled message) */ -int varlink_peek_fd(Varlink *v, size_t i); -int varlink_peek_dup_fd(Varlink *v, size_t i); -int varlink_take_fd(Varlink *v, size_t i); - -int varlink_set_allow_fd_passing_input(Varlink *v, bool b); -int varlink_set_allow_fd_passing_output(Varlink *v, bool b); - -/* Bind a disconnect, reply or timeout callback */ -int varlink_bind_reply(Varlink *v, VarlinkReply reply); - -void* varlink_set_userdata(Varlink *v, void *userdata); -void* varlink_get_userdata(Varlink *v); - -int varlink_get_peer_uid(Varlink *v, uid_t *ret); -int varlink_get_peer_gid(Varlink *v, gid_t *ret); -int varlink_get_peer_pid(Varlink *v, pid_t *ret); -int varlink_get_peer_pidref(Varlink *v, PidRef *ret); - -int varlink_set_relative_timeout(Varlink *v, usec_t usec); - -VarlinkServer* varlink_get_server(Varlink *v); - -int varlink_set_description(Varlink *v, const char *d); - -/* Automatically mark the parameters part of incoming messages as security sensitive */ -int varlink_set_input_sensitive(Varlink *v); - -/* Create a varlink server */ -int varlink_server_new(VarlinkServer **ret, VarlinkServerFlags flags); -VarlinkServer *varlink_server_ref(VarlinkServer *s); -VarlinkServer *varlink_server_unref(VarlinkServer *s); - -/* Add addresses or fds to listen on */ -int varlink_server_listen_address(VarlinkServer *s, const char *address, mode_t mode); -int varlink_server_listen_fd(VarlinkServer *s, int fd); -int varlink_server_listen_auto(VarlinkServer *s); -int varlink_server_add_connection(VarlinkServer *s, int fd, Varlink **ret); -int varlink_server_add_connection_pair(VarlinkServer *s, int input_fd, int output_fd, const struct ucred *ucred_override, Varlink **ret); -int varlink_server_add_connection_stdio(VarlinkServer *s, Varlink **ret); - -/* Bind callbacks */ -int varlink_server_bind_method(VarlinkServer *s, const char *method, VarlinkMethod callback); -int varlink_server_bind_method_many_internal(VarlinkServer *s, ...); -#define varlink_server_bind_method_many(s, ...) varlink_server_bind_method_many_internal(s, __VA_ARGS__, NULL) -int varlink_server_bind_connect(VarlinkServer *s, VarlinkConnect connect); -int varlink_server_bind_disconnect(VarlinkServer *s, VarlinkDisconnect disconnect); - -/* Add interface definition */ -int varlink_server_add_interface(VarlinkServer *s, const VarlinkInterface *interface); -int varlink_server_add_interface_many_internal(VarlinkServer *s, ...); -#define varlink_server_add_interface_many(s, ...) varlink_server_add_interface_many_internal(s, __VA_ARGS__, NULL) - -void* varlink_server_set_userdata(VarlinkServer *s, void *userdata); -void* varlink_server_get_userdata(VarlinkServer *s); - -int varlink_server_attach_event(VarlinkServer *v, sd_event *e, int64_t priority); -int varlink_server_detach_event(VarlinkServer *v); -sd_event *varlink_server_get_event(VarlinkServer *v); - -int varlink_server_loop_auto(VarlinkServer *server); - -int varlink_server_shutdown(VarlinkServer *server); - -int varlink_server_set_exit_on_idle(VarlinkServer *s, bool b); - -unsigned varlink_server_connections_max(VarlinkServer *s); -unsigned varlink_server_connections_per_uid_max(VarlinkServer *s); - -int varlink_server_set_connections_per_uid_max(VarlinkServer *s, unsigned m); -int varlink_server_set_connections_max(VarlinkServer *s, unsigned m); - -unsigned varlink_server_current_connections(VarlinkServer *s); - -int varlink_server_set_description(VarlinkServer *s, const char *description); - -typedef enum VarlinkInvocationFlags { - VARLINK_ALLOW_LISTEN = 1 << 0, - VARLINK_ALLOW_ACCEPT = 1 << 1, - _VARLINK_SERVER_INVOCATION_FLAGS_MAX = (1 << 2) - 1, - _VARLINK_SERVER_INVOCATION_FLAGS_INVALID = -EINVAL, -} VarlinkInvocationFlags; - -int varlink_invocation(VarlinkInvocationFlags flags); - -int varlink_error_to_errno(const char *error, sd_json_variant *parameters); - -int varlink_many_notifyb(Set *s, ...); -#define varlink_many_notifybo(s, ...) \ - varlink_many_notifyb((s), SD_JSON_BUILD_OBJECT(__VA_ARGS__)) -int varlink_many_reply(Set *s, sd_json_variant *parameters); -int varlink_many_error(Set *s, const char *error_id, sd_json_variant *parameters); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_close_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_flush_close_unref); -DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkServer *, varlink_server_unref); - -/* These are local errors that never cross the wire, and are our own invention */ -#define VARLINK_ERROR_DISCONNECTED "io.systemd.Disconnected" -#define VARLINK_ERROR_TIMEOUT "io.systemd.TimedOut" -#define VARLINK_ERROR_PROTOCOL "io.systemd.Protocol" - -/* This one we invented, and use for generically propagating system errors (errno) to clients */ -#define VARLINK_ERROR_SYSTEM "io.systemd.System" - -/* This one we invented and is a weaker version of "org.varlink.service.PermissionDenied", and indicates that if user would allow interactive auth, we might allow access */ -#define VARLINK_ERROR_INTERACTIVE_AUTHENTICATION_REQUIRED "io.systemd.InteractiveAuthenticationRequired" - -/* These are errors defined in the Varlink spec */ -#define VARLINK_ERROR_INTERFACE_NOT_FOUND "org.varlink.service.InterfaceNotFound" -#define VARLINK_ERROR_METHOD_NOT_FOUND "org.varlink.service.MethodNotFound" -#define VARLINK_ERROR_METHOD_NOT_IMPLEMENTED "org.varlink.service.MethodNotImplemented" -#define VARLINK_ERROR_INVALID_PARAMETER "org.varlink.service.InvalidParameter" -#define VARLINK_ERROR_PERMISSION_DENIED "org.varlink.service.PermissionDenied" -#define VARLINK_ERROR_EXPECTED_MORE "org.varlink.service.ExpectedMore" |