diff --git a/include/ctl-server.h b/include/ctl-server.h index b3b2469..6d3139c 100644 --- a/include/ctl-server.h +++ b/include/ctl-server.h @@ -19,6 +19,8 @@ #include "output.h" +#include + struct ctl; struct cmd_response; @@ -26,9 +28,12 @@ struct ctl_server_client; struct ctl_server_client_info { int id; - const char *hostname; - const char *username; - const char *seat; + union { + struct sockaddr_storage address_storage; + struct sockaddr address; + }; + const char* username; + const char* seat; }; struct ctl_server_output { diff --git a/meson.build b/meson.build index 2f42fe3..2eeba48 100644 --- a/meson.build +++ b/meson.build @@ -57,7 +57,7 @@ wayland_client = dependency('wayland-client') jansson = dependency('jansson') aml_version = ['>=0.3.0', '<0.4.0'] -neatvnc_version = ['>=0.7.0', '<0.9.0'] +neatvnc_version = ['>=0.8', '<0.9.0'] neatvnc_project = subproject( 'neatvnc', diff --git a/src/ctl-client.c b/src/ctl-client.c index 97010e4..d7b36a5 100644 --- a/src/ctl-client.c +++ b/src/ctl-client.c @@ -354,17 +354,17 @@ static void pretty_client_list(json_t* data) json_t* value; json_array_foreach(data, i, value) { char* id = NULL; - char* hostname = NULL; + char* address = NULL; char* username = NULL; - json_unpack(value, "{s:s, s?s, s?s}", "id", &id, "hostname", - &hostname, "username", &username); + json_unpack(value, "{s:s, s?s, s?s}", "id", &id, "address", + &address, "username", &username); printf(" %s: ", id); if (username) printf("%s@", username); - printf("%s\n", hostname ? hostname : ""); + printf("%s\n", address ? address : ""); } } diff --git a/src/ctl-commands.c b/src/ctl-commands.c index ee22c17..afd4b22 100644 --- a/src/ctl-commands.c +++ b/src/ctl-commands.c @@ -98,8 +98,8 @@ struct cmd_info ctl_command_list[] = { { "connection_count", \ "The total number of connected VNC clients " including " this one.", \ "" }, \ - { "hostname", \ - "The hostname or IP address of this client (may be null)", \ + { "address", \ + "The IP address of this client (may be null)", \ "" }, \ { "username", \ "The username used to authentice this client (may be null).", \ diff --git a/src/ctl-server.c b/src/ctl-server.c index fd01854..b1d81a6 100644 --- a/src/ctl-server.c +++ b/src/ctl-server.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "output.h" #include "ctl-commands.h" @@ -362,6 +363,25 @@ static struct ctl_server_client* ctl_server_client_next(struct ctl* self, return self->actions.client_next(self, prev); } +static int sockaddr_to_string(char* dst, size_t sz, const struct sockaddr* addr) +{ + struct sockaddr_in* sa_in = (struct sockaddr_in*)addr; + struct sockaddr_in6* sa_in6 = (struct sockaddr_in6*)addr; + + switch (addr->sa_family) { + case AF_INET: + inet_ntop(addr->sa_family, &sa_in->sin_addr, dst, sz); + return 0; + case AF_INET6: + inet_ntop(addr->sa_family, &sa_in6->sin6_addr, dst, sz); + return 0; + } + nvnc_log(NVNC_LOG_DEBUG, + "Don't know how to convert sa_family %d to string", + addr->sa_family); + return -1; +} + static void ctl_server_client_get_info(struct ctl* self, const struct ctl_server_client* client, struct ctl_server_client_info* info) @@ -384,9 +404,12 @@ static struct cmd_response* generate_vnc_client_list(struct ctl* self) snprintf(id_str, sizeof(id_str), "%d", info.id); json_t* packed = json_pack("{s:s}", "id", id_str); - if (info.hostname) - json_object_set_new(packed, "hostname", - json_string(info.hostname)); + char address_string[256]; + if (sockaddr_to_string(address_string, sizeof(address_string), + &info.address) == 0) { + json_object_set_new(packed, "address", + json_string(address_string)); + } if (info.username) json_object_set_new(packed, "username", @@ -897,9 +920,13 @@ json_t* pack_connection_event_params( char id_str[64]; snprintf(id_str, sizeof(id_str), "%d", info->id); + char address_string[256]; + bool have_addr = sockaddr_to_string(address_string, + sizeof(address_string), &info->address) == 0; + return json_pack("{s:s, s:s?, s:s?, s:s?, s:i}", "id", id_str, - "hostname", info->hostname, + "address", have_addr ? address_string : NULL, "username", info->username, "seat", info->seat, "connection_count", new_connection_count); diff --git a/src/main.c b/src/main.c index 0e4aa2d..187c5bf 100644 --- a/src/main.c +++ b/src/main.c @@ -636,17 +636,24 @@ static struct ctl_server_client *client_next(struct ctl* ctl, (struct ctl_server_client*)nvnc_client_first(self->nvnc); } +static void compose_client_info(const struct wayvnc_client* client, + struct ctl_server_client_info* info) +{ + info->id = client->id; + socklen_t addrlen = sizeof(info->address); + nvnc_client_get_address(client->nvnc_client, + (struct sockaddr*)&info->address, &addrlen); + info->username = nvnc_client_get_auth_username(client->nvnc_client); + info->seat = client->seat ? client->seat->name : NULL; +} + static void client_info(const struct ctl_server_client* client_handle, struct ctl_server_client_info* info) { const struct nvnc_client *vnc_client = (const struct nvnc_client*)client_handle; const struct wayvnc_client *client = nvnc_get_userdata(vnc_client); - - info->id = client->id; - info->hostname = nvnc_client_get_hostname(vnc_client); - info->username = nvnc_client_get_auth_username(vnc_client); - info->seat = client->seat ? client->seat->name : NULL; + compose_client_info(client, info); } static int get_output_list(struct ctl* ctl, @@ -1279,13 +1286,8 @@ static void client_destroy(void* obj) wayvnc->nr_clients); if (wayvnc->ctl) { - struct ctl_server_client_info info = { - .id = self->id, - .hostname = nvnc_client_get_hostname(self->nvnc_client), - .username = nvnc_client_get_auth_username( - self->nvnc_client), - .seat = self->seat ? self->seat->name : NULL, - }; + struct ctl_server_client_info info = {}; + compose_client_info(self, &info); ctl_server_event_disconnected(wayvnc->ctl, &info, wayvnc->nr_clients); @@ -1335,12 +1337,8 @@ static void on_nvnc_client_new(struct nvnc_client* client) nvnc_log(NVNC_LOG_DEBUG, "Client connected, new client count: %d", self->nr_clients); - struct ctl_server_client_info info = { - .id = wayvnc_client->id, - .hostname = nvnc_client_get_hostname(client), - .username = nvnc_client_get_auth_username(client), - .seat = wayvnc_client->seat ? wayvnc_client->seat->name : NULL, - }; + struct ctl_server_client_info info = {}; + compose_client_info(wayvnc_client, &info); ctl_server_event_connected(self->ctl, &info, self->nr_clients); } diff --git a/wayvnc.scd b/wayvnc.scd index 0b9d7b1..93f84c9 100644 --- a/wayvnc.scd +++ b/wayvnc.scd @@ -269,8 +269,8 @@ Parameters: *connection_count=...* The total number of connected VNC clients including this one. -*hostname=...* - The hostname or IP of this client. May be null. +*address=...* + The IP address of this client. May be null. *username=...* The username used to authenticate this client. May be null. @@ -288,8 +288,8 @@ Parameters: *connection_count=...* The total number of connected VNC clients not including this one. -*hostname=...* - The hostname or IP of this client. May be null. +*address=...* + The IP address of this client. May be null. *username=...* The username used to authenticate this client. May be null. diff --git a/wayvncctl.scd b/wayvncctl.scd index abc8040..c341716 100644 --- a/wayvncctl.scd +++ b/wayvncctl.scd @@ -63,8 +63,8 @@ the end, for ease in scripting: ``` $ wayvncctl --json event-receive -{"method":"client-connected","params":{"id":"0x10ef670","hostname":null,"username":null,"connection_count":1}} -{"method":"client-disconnected","params":{"id":"0x10ef670","hostname":null,"username":null,"connection_count":0}} +{"method":"client-connected","params":{"id":"0x10ef670","address":null,"username":null,"connection_count":1}} +{"method":"client-disconnected","params":{"id":"0x10ef670","address":null,"username":null,"connection_count":0}} ``` The default human-readible output is a multi-line yaml-like format, with two @@ -75,12 +75,12 @@ $ wayvncctl event-receive client-connected: id: 0x10ef670 - hostname: 192.168.1.18 + address: 192.168.1.18 connection_count: 1 client-disconnected: id: 0x10ef670 - hostname: 192.168.1.18 + address: 192.168.1.18 connection_count: 0 ```