Merge branch 'master' into v0.8
commit
2a41005a87
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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).", \
|
||||||
|
|
|
@ -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);
|
||||||
|
|
71
src/main.c
71
src/main.c
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue