Added event help text

Signed-off-by: Jim Ramsay <i.am@jimramsay.com>
pull/183/head
Jim Ramsay 2022-11-08 07:32:04 -05:00 committed by Andri Yngvason
parent c75b64eae8
commit debd8a67cb
2 changed files with 143 additions and 40 deletions

View File

@ -263,41 +263,76 @@ out:
printf("\n");
}
static void print_help(json_t* data)
static void print_command_usage(const char* name, json_t* data)
{
char* desc = NULL;
json_t* params = NULL;
json_unpack(data, "{s:s, s?o}", "description", &desc,
"params", &params);
printf("Usage: wayvncctl [options] %s%s\n\n%s\n", name,
params ? " [params]" : "",
desc);
if (params) {
printf("\nParameters:");
const char* param_name;
json_t* param_value;
json_object_foreach(params, param_name, param_value) {
printf("\n --%s=...\n %s\n", param_name,
json_string_value(param_value));
}
}
printf("\nRun 'wayvncctl --help' for allowed Options\n");
}
static void print_event_details(const char* name, json_t* data)
{
char* desc = NULL;
json_t* params = NULL;
json_unpack(data, "{s:s, s?o}", "description", &desc,
"params", &params);
printf("Event: %s\n\n%s\n", name,
desc);
if (params) {
printf("\nParameters:");
const char* param_name;
json_t* param_value;
json_object_foreach(params, param_name, param_value) {
printf("\n %s:...\n %s\n", param_name,
json_string_value(param_value));
}
}
}
static void print_help(json_t* data, json_t* request)
{
if (json_object_get(data, "commands")) {
printf("Allowed commands:\n");
json_t* cmd_list = json_object_get(data, "commands");
size_t index;
json_t* value;
json_array_foreach(cmd_list, index, value) {
printf(" - %s\n", json_string_value(value));
}
printf("\nRun 'wayvncctl command-name --help' for command-specific details.\n");
printf("\nSupported events:\n");
json_t* evt_list = json_object_get(data, "events");
json_array_foreach(evt_list, index, value) {
printf(" - %s\n", json_string_value(value));
}
printf("\nRun 'wayvncctl help --event=event-name' for event-specific details.\n");
return;
}
bool is_command = json_object_get(request, "command");
const char* key;
json_t* value;
json_object_foreach(data, key, value) {
char* desc = NULL;
json_t* params = NULL;
json_unpack(value, "{s:s, s?o}", "description", &desc,
"params", &params);
printf("Usage: wayvncctl [options] %s%s\n\n%s\n", key,
params ? " [params]" : "",
desc);
if (params) {
printf("\nParameters:");
const char* param_name;
json_t* param_value;
json_object_foreach(params, param_name, param_value) {
printf("\n --%s=...\n %s\n", param_name,
json_string_value(param_value));
}
}
printf("\nRun 'wayvncctl --help' for allowed Options\n");
if (is_command)
print_command_usage(key, value);
else
print_event_details(key, value);
}
}
@ -310,10 +345,12 @@ static void pretty_version(json_t* data)
printf(" %s: %s\n", key, json_string_value(value));
}
static void pretty_print(json_t* data, const char* method)
static void pretty_print(json_t* data,
struct jsonipc_request* request)
{
const char* method = request->method;
if (strcmp(method, "help") == 0)
print_help(data);
print_help(data, request->params);
else if (strcmp(method, "version") == 0)
pretty_version(data);
else
@ -336,7 +373,7 @@ static int ctl_client_print_response(struct ctl_client* self,
if (flags & PRINT_JSON)
print_compact_json(response->data);
else if (response->code == 0)
pretty_print(response->data, request->method);
pretty_print(response->data, request);
else
print_error(response, request->method);
}

View File

@ -47,6 +47,14 @@ enum cmd_type {
CMD_SET_OUTPUT,
CMD_UNKNOWN,
};
#define CMD_LIST_LEN CMD_UNKNOWN
enum event_type {
EVT_CLIENT_CONNECTED,
EVT_CLIENT_DISCONNECTED,
EVT_UNKNOWN,
};
#define EVT_LIST_LEN EVT_UNKNOWN
struct cmd_param_info {
char* name;
@ -61,9 +69,10 @@ struct cmd_info {
static struct cmd_info cmd_list[] = {
[CMD_HELP] = { "help",
"List all commands, or show usage of a specific command",
"List all commands and events, or show usage of a specific command or event",
{
{"command", "The command to show (optional)"},
{"event", "The event to show (optional)"},
{NULL, NULL},
}
},
@ -86,13 +95,32 @@ static struct cmd_info cmd_list[] = {
},
};
#define CLIENT_EVENT_PARAMS(including) \
{"id", "A unique identifier for this client"}, \
{"connection_count", "The total number of connected VNC clients " including " this one."}, \
{"hostname", "The hostname or IP address of this client (may be null)"}, \
{"username", "The username used to authentice this client (may be null)."}, \
{NULL, NULL},
static struct cmd_info evt_list[] = {
[EVT_CLIENT_CONNECTED] = {"client-connected",
"Sent when a new vnc client connects to wayvnc",
{ CLIENT_EVENT_PARAMS("including") }
},
[EVT_CLIENT_DISCONNECTED] = {"client-disconnected",
"Sent when a vnc client disconnects from wayvnc",
{ CLIENT_EVENT_PARAMS("not including") }
},
};
struct cmd {
enum cmd_type type;
};
struct cmd_help {
struct cmd cmd;
char command[64];
char id[64];
bool id_is_command;
};
struct cmd_set_output {
@ -147,7 +175,7 @@ static enum cmd_type parse_command_name(const char* name)
{
if (!name || name[0] == '\0')
return CMD_UNKNOWN;
for (int i = 0; i < CMD_UNKNOWN; ++i) {
for (int i = 0; i < CMD_LIST_LEN; ++i) {
if (strcmp(name, cmd_list[i].name) == 0) {
return i;
}
@ -159,15 +187,28 @@ static struct cmd_help* cmd_help_new(json_t* args,
struct jsonipc_error* err)
{
const char* command = NULL;
if (args && json_unpack(args, "{s?s}", "command", &command) == -1) {
const char* event = NULL;
if (args && json_unpack(args, "{s?s, s?s}",
"command", &command,
"event", &event) == -1) {
jsonipc_error_printf(err, EINVAL,
"expecting \"command\" (optional)");
"expecting \"command\" or \"event\" (optional)");
return NULL;
}
if (command && event) {
jsonipc_error_printf(err, EINVAL,
"expecting exacly one of \"command\" or \"event\"");
return NULL;
}
struct cmd_help* cmd = calloc(1, sizeof(*cmd));
cmd->cmd.type = CMD_HELP;
if (command)
strlcpy(cmd->command, command, sizeof(cmd->command));
if (command) {
strlcpy(cmd->id, command, sizeof(cmd->id));
cmd->id_is_command = true;
} else if (event) {
strlcpy(cmd->id, event, sizeof(cmd->id));
cmd->id_is_command = false;
}
return cmd;
}
@ -207,14 +248,25 @@ static struct cmd_set_output* cmd_set_output_new(json_t* args,
return cmd;
}
static json_t* list_allowed_commands()
static json_t* list_allowed(struct cmd_info (*list)[], size_t len)
{
json_t* allowed = json_array();
for (int i = 0; i < CMD_UNKNOWN; ++i)
json_array_append_new(allowed, json_string(cmd_list[i].name));
for (int i = 0; i < len; ++i) {
json_array_append_new(allowed, json_string((*list)[i].name));
}
return allowed;
}
static json_t* list_allowed_commands()
{
return list_allowed(&cmd_list, CMD_LIST_LEN);
}
static json_t* list_allowed_events()
{
return list_allowed(&evt_list, EVT_LIST_LEN);
}
static struct cmd* parse_command(struct jsonipc_request* ipc,
struct jsonipc_error* err)
{
@ -316,14 +368,28 @@ static json_t* client_next_object(struct ctl_client* self, struct cmd_response**
return root;
}
static struct cmd_response* generate_help_object(const char* cmd)
static struct cmd_info* find_info(const char* id, struct cmd_info (*list)[],
size_t len)
{
enum cmd_type ctype = parse_command_name(cmd);
for (int i = 0; i < len; ++i) {
struct cmd_info* info = &(*list)[i];
if (strcmp(info->name, id) == 0)
return info;
}
return NULL;
}
static struct cmd_response* generate_help_object(const char* id, bool id_is_command)
{
struct cmd_info* info = id_is_command ?
find_info(id, &cmd_list, CMD_LIST_LEN) :
find_info(id, &evt_list, EVT_LIST_LEN);
json_t* data;
if (ctype == CMD_UNKNOWN) {
data = json_pack("{s:o}", "commands", list_allowed_commands());
if (!info) {
data = json_pack("{s:o, s:o}",
"commands", list_allowed_commands(),
"events", list_allowed_events());
} else {
struct cmd_info* info = &cmd_list[ctype];
json_t* param_list = NULL;
if (info->params[0].name) {
param_list = json_object();
@ -362,7 +428,7 @@ static struct cmd_response* ctl_server_dispatch_cmd(struct ctl* self,
switch (cmd->type) {
case CMD_HELP:{
struct cmd_help* c = (struct cmd_help*)cmd;
response = generate_help_object(c->command);
response = generate_help_object(c->id, c->id_is_command);
break;
}
case CMD_SET_OUTPUT: {
@ -799,7 +865,7 @@ int ctl_server_enqueue_event(struct ctl* self, const char* event_name,
return enqueued;
}
void ctl_server_event_connect(struct ctl* self,
static void ctl_server_event_connect(struct ctl* self,
bool connected,
const char* client_id,
const char* client_hostname,