Merge branch 'master' into v0.8

v0.8
Andri Yngvason 2024-01-04 21:10:35 +00:00
commit 2a41005a87
8 changed files with 104 additions and 45 deletions

View File

@ -19,6 +19,8 @@
#include "output.h" #include "output.h"
#include <sys/socket.h>
struct ctl; struct ctl;
struct cmd_response; struct cmd_response;
@ -26,7 +28,10 @@ struct ctl_server_client;
struct ctl_server_client_info { struct ctl_server_client_info {
int id; int id;
const char *hostname; union {
struct sockaddr_storage address_storage;
struct sockaddr address;
};
const char* username; const char* username;
const char* seat; const char* seat;
}; };

View File

@ -57,7 +57,7 @@ wayland_client = dependency('wayland-client')
jansson = dependency('jansson') jansson = dependency('jansson')
aml_version = ['>=0.3.0', '<0.4.0'] 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_project = subproject(
'neatvnc', 'neatvnc',

View File

@ -354,17 +354,17 @@ static void pretty_client_list(json_t* data)
json_t* value; json_t* value;
json_array_foreach(data, i, value) { json_array_foreach(data, i, value) {
char* id = NULL; char* id = NULL;
char* hostname = NULL; char* address = NULL;
char* username = NULL; char* username = NULL;
json_unpack(value, "{s:s, s?s, s?s}", "id", &id, "hostname", json_unpack(value, "{s:s, s?s, s?s}", "id", &id, "address",
&hostname, "username", &username); &address, "username", &username);
printf(" %s: ", id); printf(" %s: ", id);
if (username) if (username)
printf("%s@", 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", \ { "connection_count", \
"The total number of connected VNC clients " including " this one.", \ "The total number of connected VNC clients " including " this one.", \
"<integer>" }, \ "<integer>" }, \
{ "hostname", \ { "address", \
"The hostname or IP address of this client (may be null)", \ "The IP address of this client (may be null)", \
"<name|ip>" }, \ "<name|ip>" }, \
{ "username", \ { "username", \
"The username used to authentice this client (may be null).", \ "The username used to authentice this client (may be null).", \

View File

@ -27,6 +27,7 @@
#include <neatvnc.h> #include <neatvnc.h>
#include <aml.h> #include <aml.h>
#include <jansson.h> #include <jansson.h>
#include <arpa/inet.h>
#include "output.h" #include "output.h"
#include "ctl-commands.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); 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, static void ctl_server_client_get_info(struct ctl* self,
const struct ctl_server_client* client, const struct ctl_server_client* client,
struct ctl_server_client_info* info) 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); snprintf(id_str, sizeof(id_str), "%d", info.id);
json_t* packed = json_pack("{s:s}", "id", id_str); json_t* packed = json_pack("{s:s}", "id", id_str);
if (info.hostname) char address_string[256];
json_object_set_new(packed, "hostname", if (sockaddr_to_string(address_string, sizeof(address_string),
json_string(info.hostname)); &info.address) == 0) {
json_object_set_new(packed, "address",
json_string(address_string));
}
if (info.username) if (info.username)
json_object_set_new(packed, "username", json_object_set_new(packed, "username",
@ -897,9 +920,13 @@ json_t* pack_connection_event_params(
char id_str[64]; char id_str[64];
snprintf(id_str, sizeof(id_str), "%d", info->id); 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}", return json_pack("{s:s, s:s?, s:s?, s:s?, s:i}",
"id", id_str, "id", id_str,
"hostname", info->hostname, "address", have_addr ? address_string : NULL,
"username", info->username, "username", info->username,
"seat", info->seat, "seat", info->seat,
"connection_count", new_connection_count); "connection_count", new_connection_count);

View File

@ -580,8 +580,11 @@ static int init_wayland(struct wayvnc* self, const char* display)
failure: failure:
wl_display_disconnect(self->display); wl_display_disconnect(self->display);
self->display = NULL;
handler_failure: handler_failure:
if (self->wl_handler)
aml_unref(self->wl_handler); aml_unref(self->wl_handler);
self->wl_handler = NULL;
return -1; 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); (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, static void client_info(const struct ctl_server_client* client_handle,
struct ctl_server_client_info* info) struct ctl_server_client_info* info)
{ {
const struct nvnc_client *vnc_client = const struct nvnc_client *vnc_client =
(const struct nvnc_client*)client_handle; (const struct nvnc_client*)client_handle;
const struct wayvnc_client *client = nvnc_get_userdata(vnc_client); const struct wayvnc_client *client = nvnc_get_userdata(vnc_client);
compose_client_info(client, info);
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;
} }
static int get_output_list(struct ctl* ctl, static int get_output_list(struct ctl* ctl,
@ -1276,13 +1286,8 @@ static void client_destroy(void* obj)
wayvnc->nr_clients); wayvnc->nr_clients);
if (wayvnc->ctl) { if (wayvnc->ctl) {
struct ctl_server_client_info info = { struct ctl_server_client_info info = {};
.id = self->id, compose_client_info(self, &info);
.hostname = nvnc_client_get_hostname(self->nvnc_client),
.username = nvnc_client_get_auth_username(
self->nvnc_client),
.seat = self->seat ? self->seat->name : NULL,
};
ctl_server_event_disconnected(wayvnc->ctl, &info, ctl_server_event_disconnected(wayvnc->ctl, &info,
wayvnc->nr_clients); 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", nvnc_log(NVNC_LOG_DEBUG, "Client connected, new client count: %d",
self->nr_clients); self->nr_clients);
struct ctl_server_client_info info = { struct ctl_server_client_info info = {};
.id = wayvnc_client->id, compose_client_info(wayvnc_client, &info);
.hostname = nvnc_client_get_hostname(client),
.username = nvnc_client_get_auth_username(client),
.seat = wayvnc_client->seat ? wayvnc_client->seat->name : NULL,
};
ctl_server_event_connected(self->ctl, &info, self->nr_clients); 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); 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) static struct cmd_response* on_attach(struct ctl* ctl, const char* display)
{ {
struct wayvnc* self = ctl_server_userdata(ctl); struct wayvnc* self = ctl_server_userdata(ctl);
assert(self); assert(self);
// TODO: Add optional output argument memset(intercepted_error, 0, sizeof(intercepted_error));
if (!wayland_attach(self, display, NULL)) nvnc_set_log_fn_thread_local(intercept_cmd_error);
return cmd_failed("Failed to attach to %s", display);
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, static bool wayland_attach(struct wayvnc* self, const char* display,

View File

@ -269,8 +269,8 @@ Parameters:
*connection_count=...* *connection_count=...*
The total number of connected VNC clients including this one. The total number of connected VNC clients including this one.
*hostname=...* *address=...*
The hostname or IP of this client. May be null. The IP address of this client. May be null.
*username=...* *username=...*
The username used to authenticate this client. May be null. The username used to authenticate this client. May be null.
@ -288,8 +288,8 @@ Parameters:
*connection_count=...* *connection_count=...*
The total number of connected VNC clients not including this one. The total number of connected VNC clients not including this one.
*hostname=...* *address=...*
The hostname or IP of this client. May be null. The IP address of this client. May be null.
*username=...* *username=...*
The username used to authenticate this client. May be null. 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 $ wayvncctl --json event-receive
{"method":"client-connected","params":{"id":"0x10ef670","hostname":null,"username":null,"connection_count":1}} {"method":"client-connected","params":{"id":"0x10ef670","address":null,"username":null,"connection_count":1}}
{"method":"client-disconnected","params":{"id":"0x10ef670","hostname":null,"username":null,"connection_count":0}} {"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 The default human-readible output is a multi-line yaml-like format, with two
@ -75,12 +75,12 @@ $ wayvncctl event-receive
client-connected: client-connected:
id: 0x10ef670 id: 0x10ef670
hostname: 192.168.1.18 address: 192.168.1.18
connection_count: 1 connection_count: 1
client-disconnected: client-disconnected:
id: 0x10ef670 id: 0x10ef670
hostname: 192.168.1.18 address: 192.168.1.18
connection_count: 0 connection_count: 0
``` ```