Merge branch 'v0.8' into pios

pios
Andri Yngvason 2024-02-25 13:06:13 +00:00
commit aabed33a7a
8 changed files with 105 additions and 46 deletions

View File

@ -19,6 +19,8 @@
#include "output.h"
#include <sys/socket.h>
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 {

View File

@ -1,7 +1,7 @@
project(
'wayvnc',
'c',
version: '0.8-rc0',
version: '0.8.0',
license: 'ISC',
default_options: [
'c_std=gnu11',
@ -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',

View File

@ -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 : "<unknown>");
printf("%s\n", address ? address : "<unknown>");
}
}

View File

@ -98,8 +98,8 @@ struct cmd_info ctl_command_list[] = {
{ "connection_count", \
"The total number of connected VNC clients " including " this one.", \
"<integer>" }, \
{ "hostname", \
"The hostname or IP address of this client (may be null)", \
{ "address", \
"The IP address of this client (may be null)", \
"<name|ip>" }, \
{ "username", \
"The username used to authentice this client (may be null).", \

View File

@ -27,6 +27,7 @@
#include <neatvnc.h>
#include <aml.h>
#include <jansson.h>
#include <arpa/inet.h>
#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);

View File

@ -580,8 +580,11 @@ static int init_wayland(struct wayvnc* self, const char* display)
failure:
wl_display_disconnect(self->display);
self->display = NULL;
handler_failure:
if (self->wl_handler)
aml_unref(self->wl_handler);
self->wl_handler = NULL;
return -1;
}
@ -633,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,
@ -1276,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);
@ -1332,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);
}
@ -1558,16 +1559,42 @@ void switch_to_prev_output(struct wayvnc* self)
switch_to_output(self, prev);
}
static char intercepted_error[256];
static void intercept_cmd_error(const struct nvnc_log_data* meta,
const char* message)
{
if (meta->level != NVNC_LOG_ERROR) {
nvnc_default_logger(meta, message);
return;
}
struct nvnc_log_data meta_override = *meta;
meta_override.level = NVNC_LOG_DEBUG;
nvnc_default_logger(&meta_override, message);
size_t len = strlen(intercepted_error);
if (len != 0 && len < sizeof(intercepted_error) - 2)
intercepted_error[len++] = '\n';
strlcpy(intercepted_error + len, message,
sizeof(intercepted_error) - len);
}
static struct cmd_response* on_attach(struct ctl* ctl, const char* display)
{
struct wayvnc* self = ctl_server_userdata(ctl);
assert(self);
// TODO: Add optional output argument
if (!wayland_attach(self, display, NULL))
return cmd_failed("Failed to attach to %s", display);
memset(intercepted_error, 0, sizeof(intercepted_error));
nvnc_set_log_fn_thread_local(intercept_cmd_error);
return cmd_ok();
// TODO: Add optional output argument
bool ok = wayland_attach(self, display, NULL);
nvnc_set_log_fn_thread_local(NULL);
return ok ? cmd_ok() : cmd_failed("%s", intercepted_error);
}
static bool wayland_attach(struct wayvnc* self, const char* display,

View File

@ -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.

View File

@ -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
```