From c0ca4b8cbc365df4139dff081d3fc7ecafaf40ee Mon Sep 17 00:00:00 2001 From: Alejandro Sirgo Rica Date: Fri, 21 Jun 2024 12:26:07 +0200 Subject: rest: add shell/list Add GET shell/list request to obtain the list of scripts available in /opt/opengnsys/client/shell Resquest payload structure: no paylaod Response's structure: { 'scripts': ['script', 'script2'] } --- src/rest.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/rest.h | 1 + 2 files changed, 105 insertions(+) diff --git a/src/rest.c b/src/rest.c index 59b165c..93e8084 100644 --- a/src/rest.c +++ b/src/rest.c @@ -832,6 +832,102 @@ static int og_cmd_run_get(json_t *element, struct og_msg_params *params, return 0; } +#define OG_SCRIPT_PATH "/opt/opengnsys/client/shell" + +struct script_entry { + char name[FILENAME_MAX]; + struct list_head list; +}; + +static void og_script_list_free(struct list_head *script_list) +{ + struct script_entry *script, *tmp; + + list_for_each_entry_safe(script, tmp, script_list, list) { + list_del(&script->list); + free(script); + } +} + +static int og_get_client_scripts(struct list_head *script_list) +{ + struct script_entry *script; + struct dirent *dent; + DIR *d; + + d = opendir(OG_SCRIPT_PATH); + if (!d) { + syslog(LOG_ERR, "Cannot open directory %s (%s:%d)\n", + OG_SCRIPT_PATH, __func__, __LINE__); + return -1; + } + + dent = readdir(d); + while (dent) { + if (dent->d_type != DT_REG) { + dent = readdir(d); + continue; + } + + script = calloc(1, sizeof(struct script_entry)); + if (!script) { + closedir(d); + og_script_list_free(script_list); + return -1; + } + + snprintf(script->name, FILENAME_MAX, "%s", dent->d_name); + list_add_tail(&script->list, script_list); + + dent = readdir(d); + } + closedir(d); + + return 0; +} + +static int og_cmd_shell_list(char *buffer_reply) +{ + struct og_buffer og_buffer = { + .data = buffer_reply + }; + struct script_entry *entry; + json_t *root, *script_arr; + LIST_HEAD(script_list); + + if (og_get_client_scripts(&script_list) < 0) + return -1; + + root = json_object(); + if (!root) { + og_script_list_free(&script_list); + return -1; + } + + script_arr = json_array(); + if (!script_arr) { + og_script_list_free(&script_list); + json_decref(root); + return -1; + } + + list_for_each_entry(entry, &script_list, list) + json_array_append_new(script_arr, json_string(entry->name)); + + json_object_set_new(root, "scripts", script_arr); + + if (json_dump_callback(root, og_json_dump_clients, &og_buffer, 0)) { + og_script_list_free(&script_list); + json_decref(root); + return -1; + } + + og_script_list_free(&script_list); + json_decref(root); + + return 0; +} + static int og_cmd_session(json_t *element, struct og_msg_params *params) { json_t *clients, *value; @@ -7640,6 +7736,7 @@ struct { [OG_URI_WOL] = { "wol", }, [OG_URI_SHELL_RUN] = { "shell/run", }, [OG_URI_SHELL_OUTPUT] = { "shell/output", }, + [OG_URI_SHELL_LIST] = { "shell/list", }, [OG_URI_SESSION] = { "session", }, [OG_URI_SCOPES] = { "scopes", }, [OG_URI_POWEROFF] = { "poweroff", }, @@ -8009,6 +8106,13 @@ int og_client_state_process_payload_rest(struct og_client *cli) } err = og_cmd_run_get(root, ¶ms, buf_reply); + } else if (!strncmp(cmd, "shell/list", strlen("shell/list"))) { + if (method != OG_METHOD_GET) { + err = og_client_method_not_found(cli); + goto err_process_rest_payload; + } + + err = og_cmd_shell_list(buf_reply); } else if (!strncmp(cmd, "session", strlen("session"))) { if (method != OG_METHOD_POST && method != OG_METHOD_GET) { err = og_client_method_not_found(cli); diff --git a/src/rest.h b/src/rest.h index fad2e9b..f70af75 100644 --- a/src/rest.h +++ b/src/rest.h @@ -105,6 +105,7 @@ enum og_rest_uri { OG_URI_WOL, OG_URI_SHELL_RUN, OG_URI_SHELL_OUTPUT, + OG_URI_SHELL_LIST, OG_URI_SESSION, OG_URI_SCOPES, OG_URI_POWEROFF, -- cgit v1.2.3-18-g5258