diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client.c | 35 | ||||
-rw-r--r-- | src/core.c | 30 | ||||
-rw-r--r-- | src/dbi.h | 1 | ||||
-rw-r--r-- | src/json.c | 1 | ||||
-rw-r--r-- | src/json.h | 24 | ||||
-rw-r--r-- | src/legacy.c | 278 | ||||
-rw-r--r-- | src/legacy.h | 6 | ||||
-rw-r--r-- | src/main.c | 8 | ||||
-rw-r--r-- | src/ogAdmServer.c | 1 | ||||
-rw-r--r-- | src/rest.c | 2871 | ||||
-rw-r--r-- | src/rest.h | 31 | ||||
-rw-r--r-- | src/schedule.c | 482 | ||||
-rw-r--r-- | src/schedule.h | 66 | ||||
-rw-r--r-- | src/scope.c | 427 |
14 files changed, 437 insertions, 3824 deletions
diff --git a/src/client.c b/src/client.c index 17bc8a7..96b522f 100644 --- a/src/client.c +++ b/src/client.c @@ -14,7 +14,6 @@ #include "list.h" #include "rest.h" #include "json.h" -#include "schedule.h" #include <syslog.h> #include <sys/ioctl.h> #include <ifaddrs.h> @@ -371,30 +370,6 @@ static int og_json_parse_partition_array(json_t *value, return 0; } -static int og_dbi_queue_autorun(uint32_t computer_id, uint32_t proc_id) -{ - struct og_task dummy_task = { - .scope = computer_id, - .type_scope = AMBITO_ORDENADORES, - .procedure_id = proc_id, - }; - struct og_dbi *dbi; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database " - "(%s:%d)\n", __func__, __LINE__); - return -1; - } - if (og_dbi_queue_procedure(dbi, &dummy_task)) { - og_dbi_close(dbi); - return -1; - } - og_dbi_close(dbi); - - return 0; -} - static int og_update_cache_info(struct og_dbi *dbi, struct list_head *cache_list, int clientid) { struct og_cache_image *cache_image; @@ -651,13 +626,6 @@ static int og_resp_refresh(json_t *data, struct og_client *cli) goto err_out; } - if (!cli->autorun && computer.procedure_id) { - cli->autorun = true; - - if (og_dbi_queue_autorun(computer.id, computer.procedure_id)) - goto err_out; - } - og_cache_image_free(&cache_list); og_boot_entry_free(&boot_entry_list); return 0; @@ -1108,13 +1076,11 @@ int og_agent_state_process_response(struct og_client *cli) cli->last_cmd_result = OG_FAILURE; if (code != 200 && code != 103) { - og_dbi_update_action(cli->last_cmd_id, success); cli->last_cmd_id = 0; return ret; } if (!cli->content_length) { - og_dbi_update_action(cli->last_cmd_id, true); cli->last_cmd_id = 0; cli->last_cmd = OG_CMD_UNSPEC; return 0; @@ -1182,7 +1148,6 @@ int og_agent_state_process_response(struct og_client *cli) /* ... cancel pending actions related to this task for this client here */ } - og_dbi_update_action(cli->last_cmd_id, success); cli->last_cmd_id = 0; cli->last_cmd = OG_CMD_UNSPEC; @@ -15,7 +15,6 @@ #include "wol.h" #include "client.h" #include "json.h" -#include "schedule.h" #include <syslog.h> #include <sys/ioctl.h> #include <ifaddrs.h> @@ -207,30 +206,6 @@ static void og_agent_reset_state(struct og_client *cli) #define OG_AGENT_CMD_TIMEOUT 900 -static void og_agent_deliver_pending_cmd(struct og_client *cli) -{ - struct timeval now, elapsed; - const struct og_cmd *cmd; - - cmd = og_cmd_find(inet_ntoa(cli->addr.sin_addr)); - if (!cmd) - return; - - gettimeofday(&now, NULL); - timersub(&now, &cmd->tv, &elapsed); - if (elapsed.tv_sec >= OG_AGENT_CMD_TIMEOUT) { - og_dbi_update_action(cmd->id, false); - og_cmd_free(cmd); - return; - } - - json_incref(cmd->json); - og_send_request(cmd->method, cmd->type, &cmd->params, cmd->json); - cli->last_cmd_id = cmd->id; - - og_cmd_free(cmd); -} - static void og_agent_read_cb(struct ev_loop *loop, struct ev_io *io, int events) { struct og_client *cli; @@ -270,11 +245,8 @@ static void og_agent_read_cb(struct ev_loop *loop, struct ev_io *io, int events) /* fall through. */ case OG_AGENT_PROCESSING_RESPONSE: ret = og_agent_state_process_response(cli); - if (ret < 0) { + if (ret < 0) goto close; - } else if (ret == 0) { - og_agent_deliver_pending_cmd(cli); - } og_agent_reset_state(cli); break; @@ -4,6 +4,7 @@ #include <dbi/dbi.h> #include <stdbool.h> #include <sys/stat.h> +#include <stdint.h> struct og_dbi_config { const char *user; @@ -9,6 +9,7 @@ #include "json.h" #include <stdint.h> +#include <string.h> int og_json_parse_string(const json_t *element, const char **str) { @@ -3,7 +3,9 @@ #include <jansson.h> #include <stdint.h> -#include "schedule.h" +#include <stdbool.h> +#include "list.h" +#include "dbi.h" int og_json_parse_string(const json_t *element, const char **str); int og_json_parse_string_copy(const json_t *element, char *str, size_t size); @@ -41,21 +43,6 @@ int og_json_parse_partition(json_t *element, struct og_partition *part, #define OG_CLIENTS_MAX 4096 -struct og_sync_params { - const char *sync; - const char *diff; - const char *remove; - const char *compress; - const char *cleanup; - const char *cache; - const char *cleanup_cache; - const char *remove_dst; - const char *diff_id; - const char *diff_name; - const char *path; - const char *method; -}; - #define OG_PARAM_SCOPE_ID (1UL << 0) #define OG_PARAM_SCOPE_TYPE (1UL << 1) @@ -87,10 +74,7 @@ struct og_msg_params { const char *comment; bool echo; struct og_partition partition_setup[OG_PARTITION_MAX]; - struct og_sync_params sync_setup; - struct og_schedule_time time; - struct og_image image; - const char *task_id; + struct og_image image; uint64_t flags; bool backup; }; diff --git a/src/legacy.c b/src/legacy.c deleted file mode 100644 index c4ed971..0000000 --- a/src/legacy.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2020-2021 Soleta Networks <info@soleta.eu> - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - */ - -#include <jansson.h> -#include <netinet/in.h> -#include <stdlib.h> -#include <syslog.h> - -#include "json.h" -#include "rest.h" -#include "legacy.h" - -#define LEGACY_CMD_MAX 4096 - -static const char *og_cmd_wol_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - const json_t *root = cmd->json; - const char *wol_type; - uint32_t type; - int len; - - wol_type = json_string_value(json_object_get(root, "type")); - if (!wol_type) - return NULL; - - if (!strcmp(wol_type, "broadcast")) - type = 1; - else - type = 2; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), "nfn=Arrancar\rmar=%u", type); - if (len >= (int)sizeof(legacy_cmd)) - return NULL; - - return strdup(legacy_cmd); -} - -static const char *og_cmd_poweroff_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - int len; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), "nfn=Apagar"); - if (len >= (int)sizeof(legacy_cmd)) - return NULL; - - return strdup(legacy_cmd); -} - -static const char *og_cmd_reboot_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - int len; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), "nfn=Reiniciar"); - if (len >= (int)sizeof(legacy_cmd)) - return NULL; - - return strdup(legacy_cmd); -} - -static const char *og_cmd_session_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - const json_t *root = cmd->json; - const char *dsk, *par; - int len; - - dsk = json_string_value(json_object_get(root, "disk")); - if (!dsk) - return NULL; - par = json_string_value(json_object_get(root, "part")); - if (!par) - return NULL; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), - "nfn=IniciarSesion\rdsk=%s\rpar=%s", - dsk, par); - if (len >= (int)sizeof(legacy_cmd)) - return NULL; - - return strdup(legacy_cmd); -} - -static const char *og_cmd_software_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - const json_t *root = cmd->json; - const char *dsk, *par; - int len; - - dsk = json_string_value(json_object_get(root, "disk")); - if (!dsk) - return NULL; - par = json_string_value(json_object_get(root, "partition")); - if (!par) - return NULL; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), - "nfn=InventarioSoftware\rdsk=%s\rpar=%s", - dsk, par); - if (len >= (int)sizeof(legacy_cmd)) - return NULL; - - return strdup(legacy_cmd); -} - -static const char *og_cmd_hardware_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - int len; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), - "nfn=InventarioHardware"); - if (len >= (int)sizeof(legacy_cmd)) - return NULL; - - return strdup(legacy_cmd); -} - -static const char *og_cmd_shell_run_to_legacy(struct og_cmd_json *cmd) -{ - const json_t *root = cmd->json; - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - const char *scp; - int len; - - scp = json_string_value(json_object_get(root, "run")); - if (!scp) - return NULL; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), - "nfn=EjecutarScript\rscp=%s", scp); - if (len >= (int)sizeof(legacy_cmd)) { - syslog(LOG_ERR, "script payload too large (%s:%d)\n", - __func__, __LINE__); - return NULL; - } - - return strdup(legacy_cmd); -} - -static char *og_cmd_image_create_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - struct og_msg_params params = {}; - json_t *root = cmd->json; - int len; - - if (og_json_parse_create_image(root, ¶ms) < 0) - return NULL; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), - "nfn=CrearImagen\rdsk=%s\rpar=%s\rcpt=%s\ridi=%s\rnci=%s\ripr=%s", - params.disk, params.partition, params.code, params.id, - params.name, params.repository); - if (len >= (int)sizeof(legacy_cmd)) - return NULL; - - return strdup(legacy_cmd); -} - -static const char *og_cmd_image_restore_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - struct og_msg_params params = {}; - json_t *root = cmd->json; - int len; - - if (og_json_parse_restore_image(root, ¶ms) < 0) - return NULL; - - len = snprintf(legacy_cmd, sizeof(legacy_cmd), - "nfn=RestaurarImagen\rdsk=%s\rpar=%s\ridi=%s\rnci=%s\ripr=%s\rifs=%s\rptc=%s", - params.disk, params.partition, params.id, params.name, - params.repository, params.profile, params.type); - if (len >= (int)sizeof(legacy_cmd)) { - return NULL; - } - - return strdup(legacy_cmd); -} - -static const char *og_cmd_setup_to_legacy(struct og_cmd_json *cmd) -{ - char legacy_cmd[LEGACY_CMD_MAX + 1] = {}; - uint32_t bufsiz = sizeof(legacy_cmd); - const char *dsk, *ttp, *che, *tch; - struct og_msg_params params = {}; - json_t *partition_setup, *value; - const json_t *root = cmd->json; - uint32_t consumed = 0; - size_t index; - int len; - - dsk = json_string_value(json_object_get(root, "disk")); - if (!dsk) - return NULL; - ttp = json_string_value(json_object_get(root, "type")); - if (!ttp) - return NULL; - che = json_string_value(json_object_get(root, "cache")); - if (!che) - return NULL; - tch = json_string_value(json_object_get(root, "cache_size")); - if (!tch) - return NULL; - - len = snprintf(legacy_cmd + consumed, bufsiz, "nfn=Configurar\rttp=%s\rdsk=%s\rcfg=dis=%s*che=%s*tch=%s!", - ttp, dsk, dsk, che, tch); - if (len >= bufsiz) - return NULL; - consumed += len; - if (consumed < bufsiz) - bufsiz -= len; - - partition_setup = json_object_get(root, "partition_setup"); - if (!partition_setup) - return NULL; - if (og_json_parse_partition_setup(partition_setup, ¶ms) < 0) - return NULL; - - json_array_foreach(partition_setup, index, value) { - len = snprintf(legacy_cmd + consumed, bufsiz, "par=%s*cpt=%s*sfi=%s*tam=%s*ope=%s%%", - params.partition_setup[index].number, - params.partition_setup[index].code, - params.partition_setup[index].filesystem, - params.partition_setup[index].size, - params.partition_setup[index].format); - if (len >= bufsiz) - return NULL; - consumed += len; - if (consumed < bufsiz) - bufsiz -= len; - } - - return strdup(legacy_cmd); -} - -const char *og_msg_params_to_legacy(struct og_cmd_json *cmd) -{ - const char *legacy_cmd = NULL; - - if (!strncmp(cmd->type, "wol", strlen("wol"))) - legacy_cmd = og_cmd_wol_to_legacy(cmd); - else if (!strncmp(cmd->type, "poweroff", strlen("poweroff"))) - legacy_cmd = og_cmd_poweroff_to_legacy(cmd); - else if (!strncmp(cmd->type, "reboot", strlen("reboot"))) - legacy_cmd = og_cmd_reboot_to_legacy(cmd); - else if (!strncmp(cmd->type, "session", strlen("session"))) - legacy_cmd = og_cmd_session_to_legacy(cmd); - else if (!strncmp(cmd->type, "software", strlen("software"))) - legacy_cmd = og_cmd_software_to_legacy(cmd); - else if (!strncmp(cmd->type, "hardware", strlen("hardware"))) - legacy_cmd = og_cmd_hardware_to_legacy(cmd); - else if (!strncmp(cmd->type, "run", strlen("run"))) - legacy_cmd = og_cmd_shell_run_to_legacy(cmd); - else if (!strncmp(cmd->type, "image_create", strlen("image_create"))) - legacy_cmd = og_cmd_image_create_to_legacy(cmd); - else if (!strncmp(cmd->type, "image_restore", strlen("image_restore"))) - legacy_cmd = og_cmd_image_restore_to_legacy(cmd); - else if (!strncmp(cmd->type, "setup", strlen("setup"))) - legacy_cmd = og_cmd_setup_to_legacy(cmd); - - if (!legacy_cmd) { - syslog(LOG_ERR, "failed to translate command %s (%s:%d)\n", - cmd->type, __func__, __LINE__); - } - - return legacy_cmd; -} diff --git a/src/legacy.h b/src/legacy.h deleted file mode 100644 index d72963c..0000000 --- a/src/legacy.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _OG_LEGACY_H -#define _OG_LEGACY_H - -const char *og_msg_params_to_legacy(struct og_cmd_json *cmd); - -#endif @@ -14,7 +14,6 @@ #include "rest.h" #include "client.h" #include "json.h" -#include "schedule.h" #include "core.h" #include "cfg.h" #include <syslog.h> @@ -97,13 +96,6 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - if (og_dbi_schedule_get() < 0) { - syslog(LOG_ERR, "Cannot connect to database\n"); - exit(EXIT_FAILURE); - } - - og_schedule_next(og_loop); - syslog(LOG_INFO, "Waiting for connections\n"); while (1) diff --git a/src/ogAdmServer.c b/src/ogAdmServer.c index 915f69c..107342d 100644 --- a/src/ogAdmServer.c +++ b/src/ogAdmServer.c @@ -13,7 +13,6 @@ #include "rest.h" #include "client.h" #include "json.h" -#include "schedule.h" #include "wol.h" #include <syslog.h> #include <sys/ioctl.h> @@ -16,8 +16,6 @@ #include "wol.h" #include "cfg.h" #include "repo.h" -#include "schedule.h" -#include "legacy.h" #include <ev.h> #include <syslog.h> #include <sys/ioctl.h> @@ -219,46 +217,6 @@ int og_json_parse_partition_setup(json_t *element, struct og_msg_params *params) return 0; } -static int og_json_parse_time_params(json_t *element, - struct og_msg_params *params) -{ - const char *key; - json_t *value; - int err = 0; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "years")) { - err = og_json_parse_uint(value, ¶ms->time.years); - params->flags |= OG_REST_PARAM_TIME_YEARS; - } else if (!strcmp(key, "months")) { - err = og_json_parse_uint(value, ¶ms->time.months); - params->flags |= OG_REST_PARAM_TIME_MONTHS; - } else if (!strcmp(key, "weeks")) { - err = og_json_parse_uint(value, ¶ms->time.weeks); - params->flags |= OG_REST_PARAM_TIME_WEEKS; - } else if (!strcmp(key, "week_days")) { - err = og_json_parse_uint(value, ¶ms->time.week_days); - params->flags |= OG_REST_PARAM_TIME_WEEK_DAYS; - } else if (!strcmp(key, "days")) { - err = og_json_parse_uint(value, ¶ms->time.days); - params->flags |= OG_REST_PARAM_TIME_DAYS; - } else if (!strcmp(key, "hours")) { - err = og_json_parse_uint(value, ¶ms->time.hours); - params->flags |= OG_REST_PARAM_TIME_HOURS; - } else if (!strcmp(key, "am_pm")) { - err = og_json_parse_uint(value, ¶ms->time.am_pm); - params->flags |= OG_REST_PARAM_TIME_AM_PM; - } else if (!strcmp(key, "minutes")) { - err = og_json_parse_uint(value, ¶ms->time.minutes); - params->flags |= OG_REST_PARAM_TIME_MINUTES; - } - if (err != 0) - return err; - } - - return err; -} - static const char *og_cmd_to_uri[OG_CMD_MAX] = { [OG_CMD_WOL] = "wol", [OG_CMD_PROBE] = "probe", @@ -274,7 +232,6 @@ static const char *og_cmd_to_uri[OG_CMD_MAX] = { [OG_CMD_IMAGE_UPDATE] = "image/update", [OG_CMD_IMAGE_RESTORE] = "image/restore", [OG_CMD_SETUP] = "setup", - [OG_CMD_RUN_SCHEDULE] = "run/schedule", [OG_CMD_IMAGES] = "images", [OG_CMD_CACHE_DELETE] = "cache/delete", [OG_CMD_CACHE_FETCH] = "cache/fetch", @@ -372,29 +329,6 @@ int og_send_request(enum og_rest_method method, enum og_cmd_type type, return 0; } -static int og_cmd_post_clients(json_t *element, struct og_msg_params *params) -{ - const char *key; - json_t *value; - int err = 0; - - if (json_typeof(element) != JSON_OBJECT) - return -1; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "clients")) - err = og_json_parse_clients(value, params); - - if (err < 0) - return err; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR)) - return -1; - - return og_send_request(OG_METHOD_POST, OG_CMD_PROBE, params, NULL); -} - struct og_buffer { char *data; int len; @@ -4613,1350 +4547,6 @@ static int og_cmd_setup(json_t *element, struct og_msg_params *params) return og_send_request(OG_METHOD_POST, OG_CMD_SETUP, params, clients); } -static int og_cmd_run_schedule(json_t *element, struct og_msg_params *params) -{ - const char *key; - json_t *value; - int err = 0; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "clients")) - err = og_json_parse_clients(value, params); - - if (err < 0) - return err; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR)) - return -1; - - return og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, params, - NULL); -} - -static LIST_HEAD(cmd_list); - -const struct og_cmd *og_cmd_find(const char *client_ip) -{ - struct og_cmd *cmd, *next; - - list_for_each_entry_safe(cmd, next, &cmd_list, list) { - if (strcmp(cmd->ip, client_ip)) - continue; - - list_del(&cmd->list); - return cmd; - } - - return NULL; -} - -void og_cmd_free(const struct og_cmd *cmd) -{ - struct og_msg_params *params = (struct og_msg_params *)&cmd->params; - int i; - - for (i = 0; i < params->ips_array_len; i++) { - free((void *)params->netmask_array[i]); - free((void *)params->ips_array[i]); - free((void *)params->mac_array[i]); - } - free((void *)params->wol_type); - - if (cmd->json) - json_decref(cmd->json); - - free((void *)cmd->ip); - free((void *)cmd->mac); - free((void *)cmd); -} - -static void og_cmd_init(struct og_cmd *cmd, enum og_rest_method method, - enum og_cmd_type type, json_t *root) -{ - cmd->type = type; - cmd->method = method; - cmd->params.ips_array[0] = strdup(cmd->ip); - cmd->params.ips_array_len = 1; - cmd->json = root; - gettimeofday(&cmd->tv, NULL); -} - -static int og_cmd_legacy_wol(const char *input, struct og_cmd *cmd) -{ - char wol_type[2] = {}; - const char *msglog; - struct og_dbi *dbi; - dbi_result result; - - if (sscanf(input, "mar=%s", wol_type) != 1) { - syslog(LOG_ERR, "malformed database legacy input\n"); - return -1; - } - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - result = dbi_conn_queryf(dbi->conn, - "SELECT aulas.netmask " - "FROM ordenadores " - "INNER JOIN aulas " - "ON ordenadores.idaula = aulas.idaula " - "WHERE ordenadores.ip = '%s'", - cmd->ip); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_next_row(result); - - og_cmd_init(cmd, OG_METHOD_NO_HTTP, OG_CMD_WOL, NULL); - cmd->params.netmask_array[0] = dbi_result_get_string_copy(result, - "netmask"); - cmd->params.mac_array[0] = strdup(cmd->mac); - cmd->params.wol_type = strdup(wol_type); - - dbi_result_free(result); - og_dbi_close(dbi); - - return 0; -} - -static int og_cmd_legacy_shell_run(const char *input, struct og_cmd *cmd) -{ - json_t *root, *script, *echo; - - script = json_string(input + 4); - echo = json_boolean(false); - - root = json_object(); - if (!root) - return -1; - json_object_set_new(root, "run", script); - json_object_set_new(root, "echo", echo); - - og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SHELL_RUN, root); - - return 0; -} - -static int og_cmd_legacy_session(const char *input, struct og_cmd *cmd) -{ - char part_str[OG_DB_SMALLINT_MAXLEN + 1]; - char disk_str[OG_DB_SMALLINT_MAXLEN + 1]; - json_t *root, *disk, *partition; - - if (sscanf(input, "dsk=%s\rpar=%s\r", disk_str, part_str) != 2) - return -1; - partition = json_string(part_str); - disk = json_string(disk_str); - - root = json_object(); - if (!root) - return -1; - json_object_set_new(root, "partition", partition); - json_object_set_new(root, "disk", disk); - - og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SESSION, root); - - return 0; -} - -static int og_cmd_legacy_poweroff(const char *input, struct og_cmd *cmd) -{ - og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_POWEROFF, NULL); - - return 0; -} - -static int og_cmd_legacy_refresh(const char *input, struct og_cmd *cmd) -{ - og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_REFRESH, NULL); - - return 0; -} - -static int og_cmd_legacy_reboot(const char *input, struct og_cmd *cmd) -{ - og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_REBOOT, NULL); - - return 0; -} - -static int og_cmd_legacy_stop(const char *input, struct og_cmd *cmd) -{ - og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_STOP, NULL); - - return 0; -} - -static int og_cmd_legacy_hardware(const char *input, struct og_cmd *cmd) -{ - og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_HARDWARE, NULL); - - return 0; -} - -static int og_cmd_legacy_software(const char *input, struct og_cmd *cmd) -{ - char part_str[OG_DB_SMALLINT_MAXLEN + 1]; - char disk_str[OG_DB_SMALLINT_MAXLEN + 1]; - json_t *root, *disk, *partition; - - if (sscanf(input, "dsk=%s\rpar=%s\r", disk_str, part_str) != 2) - return -1; - partition = json_string(part_str); - disk = json_string(disk_str); - - root = json_object(); - if (!root) - return -1; - json_object_set_new(root, "partition", partition); - json_object_set_new(root, "disk", disk); - - og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_SOFTWARE, root); - - return 0; -} - -static int og_cmd_legacy_image_create(const char *input, struct og_cmd *cmd) -{ - json_t *root, *disk, *partition, *code, *image_id, *name, *repo; - struct og_image_legacy img = {}; - - if (sscanf(input, "dsk=%s\rpar=%s\rcpt=%s\ridi=%s\rnci=%s\ripr=%s\r", - img.disk, img.part, img.code, img.image_id, img.name, - img.repo) != 6) - return -1; - image_id = json_string(img.image_id); - partition = json_string(img.part); - code = json_string(img.code); - name = json_string(img.name); - repo = json_string(img.repo); - disk = json_string(img.disk); - - root = json_object(); - if (!root) - return -1; - json_object_set_new(root, "partition", partition); - json_object_set_new(root, "repository", repo); - json_object_set_new(root, "id", image_id); - json_object_set_new(root, "code", code); - json_object_set_new(root, "name", name); - json_object_set_new(root, "disk", disk); - - og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_IMAGE_CREATE, root); - - return 0; -} - -#define OG_DB_RESTORE_TYPE_MAXLEN 64 - -static int og_cmd_legacy_image_restore(const char *input, struct og_cmd *cmd) -{ - json_t *root, *disk, *partition, *image_id, *name, *repo; - char restore_type_str[OG_DB_RESTORE_TYPE_MAXLEN + 1] = {}; - char software_id_str[OG_DB_INT_MAXLEN + 1] = {}; - json_t *software_id, *restore_type; - struct og_image_legacy img = {}; - - if (sscanf(input, - "dsk=%s\rpar=%s\ridi=%s\rnci=%s\r" - "ipr=%s\rifs=%s\rptc=%[^\r]\r", - img.disk, img.part, img.image_id, img.name, img.repo, - software_id_str, restore_type_str) != 7) - return -1; - - restore_type = json_string(restore_type_str); - software_id = json_string(software_id_str); - image_id = json_string(img.image_id); - partition = json_string(img.part); - name = json_string(img.name); - repo = json_string(img.repo); - disk = json_string(img.disk); - - root = json_object(); - if (!root) - return -1; - json_object_set_new(root, "profile", software_id); - json_object_set_new(root, "partition", partition); - json_object_set_new(root, "type", restore_type); - json_object_set_new(root, "repository", repo); - json_object_set_new(root, "id", image_id); - json_object_set_new(root, "name", name); - json_object_set_new(root, "disk", disk); - - og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_IMAGE_RESTORE, root); - - return 0; -} - -#define OG_PARTITION_TABLE_TYPE_MAXLEN 5 - -static int og_cmd_legacy_setup(const char *input, struct og_cmd *cmd) -{ - json_t *root, *disk, *cache, *cache_size, *partition_setup, *object; - char part_table_type_str[OG_PARTITION_TABLE_TYPE_MAXLEN + 1]; - struct og_legacy_partition part_cfg[OG_PARTITION_MAX] = {}; - json_t *part_table_type, *part, *code, *fs, *size, *format; - char cache_size_str [OG_DB_INT_MAXLEN + 1]; - char disk_str [OG_DB_SMALLINT_MAXLEN + 1]; - unsigned int partition_len = 0; - const char *in_ptr; - char cache_str[2]; - - if (sscanf(input, "ttp=%s\rdsk=%s\rcfg=dis=%*[^*]*che=%[^*]*tch=%[^!]!", - part_table_type_str, disk_str, cache_str, cache_size_str) != 4) - return -1; - - in_ptr = strstr(input, "!") + 1; - while (strlen(in_ptr) > 0) { - if(sscanf(in_ptr, - "par=%[^*]*cpt=%[^*]*sfi=%[^*]*tam=%[^*]*ope=%[^%%]%%", - part_cfg[partition_len].partition, - part_cfg[partition_len].code, - part_cfg[partition_len].filesystem, - part_cfg[partition_len].size, - part_cfg[partition_len].format) != 5) - return -1; - in_ptr = strstr(in_ptr, "%") + 1; - partition_len++; - } - - root = json_object(); - if (!root) - return -1; - - part_table_type = json_string(part_table_type_str); - cache_size = json_string(cache_size_str); - cache = json_string(cache_str); - partition_setup = json_array(); - disk = json_string(disk_str); - - for (unsigned int i = 0; i < partition_len; ++i) { - object = json_object(); - if (!object) { - json_decref(root); - return -1; - } - - part = json_string(part_cfg[i].partition); - fs = json_string(part_cfg[i].filesystem); - format = json_string(part_cfg[i].format); - code = json_string(part_cfg[i].code); - size = json_string(part_cfg[i].size); - - json_object_set_new(object, "partition", part); - json_object_set_new(object, "filesystem", fs); - json_object_set_new(object, "format", format); - json_object_set_new(object, "code", code); - json_object_set_new(object, "size", size); - - json_array_append_new(partition_setup, object); - } - - json_object_set_new(root, "partition_setup", partition_setup); - json_object_set_new(root, "cache_size", cache_size); - json_object_set_new(root, "type", part_table_type); - json_object_set_new(root, "cache", cache); - json_object_set_new(root, "disk", disk); - - og_cmd_init(cmd, OG_METHOD_POST, OG_CMD_SETUP, root); - - return 0; -} - -static int og_cmd_legacy_run_schedule(const char *input, struct og_cmd *cmd) -{ - og_cmd_init(cmd, OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, NULL); - - return 0; -} - -static int og_cmd_legacy(const char *input, struct og_cmd *cmd) -{ - char legacy_cmd[32] = {}; - int err = -1; - - if (sscanf(input, "nfn=%31s\r", legacy_cmd) != 1) { - syslog(LOG_ERR, "malformed database legacy input\n"); - return -1; - } - input = strchr(input, '\r') + 1; - - if (!strcmp(legacy_cmd, "Arrancar")) { - err = og_cmd_legacy_wol(input, cmd); - } else if (!strcmp(legacy_cmd, "EjecutarScript")) { - err = og_cmd_legacy_shell_run(input, cmd); - } else if (!strcmp(legacy_cmd, "IniciarSesion")) { - err = og_cmd_legacy_session(input, cmd); - } else if (!strcmp(legacy_cmd, "Apagar")) { - err = og_cmd_legacy_poweroff(input, cmd); - } else if (!strcmp(legacy_cmd, "Actualizar")) { - err = og_cmd_legacy_refresh(input, cmd); - } else if (!strcmp(legacy_cmd, "Reiniciar")) { - err = og_cmd_legacy_reboot(input, cmd); - } else if (!strcmp(legacy_cmd, "Purgar")) { - err = og_cmd_legacy_stop(input, cmd); - } else if (!strcmp(legacy_cmd, "InventarioHardware")) { - err = og_cmd_legacy_hardware(input, cmd); - } else if (!strcmp(legacy_cmd, "InventarioSoftware")) { - err = og_cmd_legacy_software(input, cmd); - } else if (!strcmp(legacy_cmd, "CrearImagen")) { - err = og_cmd_legacy_image_create(input, cmd); - } else if (!strcmp(legacy_cmd, "RestaurarImagen")) { - err = og_cmd_legacy_image_restore(input, cmd); - } else if (!strcmp(legacy_cmd, "Configurar")) { - err = og_cmd_legacy_setup(input, cmd); - } else if (!strcmp(legacy_cmd, "EjecutaComandosPendientes") || - !strcmp(legacy_cmd, "Actualizar")) { - err = og_cmd_legacy_run_schedule(input, cmd); - } - - return err; -} - -static int og_dbi_add_action(const struct og_dbi *dbi, struct og_task *task, - struct og_cmd *cmd) -{ - char start_date_string[24]; - struct tm *start_date; - const char *msglog; - dbi_result result; - time_t now; - - time(&now); - start_date = localtime(&now); - - sprintf(start_date_string, "%hu/%hhu/%hhu %hhu:%hhu:%hhu", - start_date->tm_year + 1900, start_date->tm_mon + 1, - start_date->tm_mday, start_date->tm_hour, start_date->tm_min, - start_date->tm_sec); - result = dbi_conn_queryf(dbi->conn, - "INSERT INTO acciones (idordenador, " - "tipoaccion, idtipoaccion, descriaccion, ip, " - "sesion, idcomando, parametros, fechahorareg, " - "estado, resultado, ambito, idambito, " - "restrambito, idprocedimiento, idcentro, " - "idprogramacion) " - "VALUES (%d, %d, %d, '%s', '%s', %d, %d, '%s', " - "'%s', %d, %d, %d, %d, '%s', %d, %d, %d)", - cmd->client_id, EJECUCION_TAREA, task->task_id, - "", cmd->ip, task->session, task->command_id, - task->params, start_date_string, - ACCION_INICIADA, ACCION_SINRESULTADO, - task->type_scope, task->scope, "", - task->procedure_id, task->center_id, - task->schedule_id); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - cmd->id = dbi_conn_sequence_last(dbi->conn, NULL); - if (!task->session) { - task->session = cmd->id; - dbi_result_free(result); - result = dbi_conn_queryf(dbi->conn, - "UPDATE acciones SET sesion=%d " - "WHERE idaccion=%d", - task->session, cmd->id); - } - - dbi_result_free(result); - - return 0; -} - -static int og_queue_task_command(struct og_dbi *dbi, struct og_task *task, - char *query) -{ - struct og_cmd *cmd; - const char *msglog; - dbi_result result; - - result = dbi_conn_queryf(dbi->conn, query); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - cmd = (struct og_cmd *)calloc(1, sizeof(struct og_cmd)); - if (!cmd) { - dbi_result_free(result); - return -1; - } - - cmd->client_id = dbi_result_get_uint(result, "idordenador"); - cmd->ip = strdup(dbi_result_get_string(result, "ip")); - cmd->mac = strdup(dbi_result_get_string(result, "mac")); - - og_cmd_legacy(task->params, cmd); - - if (task->procedure_id) { - if (og_dbi_add_action(dbi, task, cmd)) { - dbi_result_free(result); - return -1; - } - } else { - cmd->id = task->task_id; - } - - list_add_tail(&cmd->list, &cmd_list); - } - - dbi_result_free(result); - - return 0; -} - -static int og_queue_task_group_clients(struct og_dbi *dbi, struct og_task *task, - char *query) -{ - - const char *msglog; - dbi_result result; - - result = dbi_conn_queryf(dbi->conn, query); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - uint32_t group_id = dbi_result_get_uint(result, "idgrupo"); - - sprintf(query, "SELECT idgrupo FROM gruposordenadores " - "WHERE grupoid=%d", group_id); - if (og_queue_task_group_clients(dbi, task, query)) { - dbi_result_free(result); - return -1; - } - - sprintf(query,"SELECT ip, mac, idordenador FROM ordenadores " - "WHERE grupoid=%d", group_id); - if (og_queue_task_command(dbi, task, query)) { - dbi_result_free(result); - return -1; - } - - } - - dbi_result_free(result); - - return 0; -} - -static int og_queue_task_group_classrooms(struct og_dbi *dbi, - struct og_task *task, char *query) -{ - - const char *msglog; - dbi_result result; - - result = dbi_conn_queryf(dbi->conn, query); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - uint32_t group_id = dbi_result_get_uint(result, "idgrupo"); - - sprintf(query, "SELECT idgrupo FROM grupos " - "WHERE grupoid=%d AND tipo=%d", group_id, AMBITO_GRUPOSAULAS); - if (og_queue_task_group_classrooms(dbi, task, query)) { - dbi_result_free(result); - return -1; - } - - sprintf(query, - "SELECT ip,mac,idordenador " - "FROM ordenadores INNER JOIN aulas " - "WHERE ordenadores.idaula=aulas.idaula " - "AND aulas.grupoid=%d", - group_id); - if (og_queue_task_command(dbi, task, query)) { - dbi_result_free(result); - return -1; - } - - } - - dbi_result_free(result); - - return 0; -} - -static int og_queue_task_clients(struct og_dbi *dbi, struct og_task *task) -{ - char query[4096]; - - switch (task->type_scope) { - case AMBITO_CENTROS: - sprintf(query, - "SELECT ip,mac,idordenador " - "FROM ordenadores INNER JOIN aulas " - "WHERE ordenadores.idaula=aulas.idaula " - "AND idcentro=%d", - task->scope); - return og_queue_task_command(dbi, task, query); - case AMBITO_GRUPOSAULAS: - sprintf(query, - "SELECT idgrupo FROM grupos " - "WHERE idgrupo=%i AND tipo=%d", - task->scope, AMBITO_GRUPOSAULAS); - return og_queue_task_group_classrooms(dbi, task, query); - case AMBITO_AULAS: - sprintf(query, - "SELECT ip,mac,idordenador FROM ordenadores " - "WHERE idaula=%d", - task->scope); - return og_queue_task_command(dbi, task, query); - case AMBITO_GRUPOSORDENADORES: - sprintf(query, - "SELECT idgrupo FROM gruposordenadores " - "WHERE idgrupo = %d", - task->scope); - return og_queue_task_group_clients(dbi, task, query); - case AMBITO_ORDENADORES: - sprintf(query, - "SELECT ip, mac, idordenador FROM ordenadores " - "WHERE idordenador = %d", - task->scope); - return og_queue_task_command(dbi, task, query); - } - return 0; -} - -int og_dbi_queue_procedure(struct og_dbi *dbi, struct og_task *task) -{ - uint32_t procedure_id; - const char *msglog; - dbi_result result; - - result = dbi_conn_queryf(dbi->conn, - "SELECT parametros, procedimientoid, idcomando " - "FROM procedimientos_acciones " - "WHERE idprocedimiento=%d ORDER BY orden", task->procedure_id); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - procedure_id = dbi_result_get_uint(result, "procedimientoid"); - if (procedure_id > 0) { - task->procedure_id = procedure_id; - if (og_dbi_queue_procedure(dbi, task)) - return -1; - continue; - } - - task->params = dbi_result_get_string(result, "parametros"); - task->command_id = dbi_result_get_uint(result, "idcomando"); - if (og_queue_task_clients(dbi, task)) - return -1; - } - - dbi_result_free(result); - - return 0; -} - -static int og_dbi_queue_task(struct og_dbi *dbi, uint32_t task_id, - uint32_t schedule_id) -{ - struct og_task task = {}; - uint32_t task_id_next; - const char *msglog; - dbi_result result; - - task.schedule_id = schedule_id; - - result = dbi_conn_queryf(dbi->conn, - "SELECT tareas_acciones.orden, " - "tareas_acciones.idprocedimiento, " - "tareas_acciones.tareaid, " - "tareas.idtarea, " - "tareas.idcentro, " - "tareas.ambito, " - "tareas.idambito, " - "tareas.restrambito " - " FROM tareas" - " INNER JOIN tareas_acciones ON tareas_acciones.idtarea=tareas.idtarea" - " WHERE tareas_acciones.idtarea=%u ORDER BY tareas_acciones.orden ASC", task_id); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - task_id_next = dbi_result_get_uint(result, "tareaid"); - - if (task_id_next > 0) { - if (og_dbi_queue_task(dbi, task_id_next, schedule_id)) - return -1; - - continue; - } - task.task_id = dbi_result_get_uint(result, "idtarea"); - task.center_id = dbi_result_get_uint(result, "idcentro"); - task.procedure_id = dbi_result_get_uint(result, "idprocedimiento"); - task.type_scope = dbi_result_get_uint(result, "ambito"); - task.scope = dbi_result_get_uint(result, "idambito"); - task.filtered_scope = dbi_result_get_string(result, "restrambito"); - - og_dbi_queue_procedure(dbi, &task); - } - - dbi_result_free(result); - - return 0; -} - -static int og_dbi_queue_command(struct og_dbi *dbi, uint32_t task_id, - uint32_t schedule_id) -{ - struct og_task task = {}; - const char *msglog; - dbi_result result; - char query[4096]; - - result = dbi_conn_queryf(dbi->conn, - "SELECT idaccion, idcentro, idordenador, parametros " - "FROM acciones " - "WHERE sesion = %u", task_id); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - task.task_id = dbi_result_get_uint(result, "idaccion"); - task.center_id = dbi_result_get_uint(result, "idcentro"); - task.scope = dbi_result_get_uint(result, "idordenador"); - task.params = dbi_result_get_string(result, "parametros"); - - sprintf(query, - "SELECT ip, mac, idordenador FROM ordenadores " - "WHERE idordenador = %d", - task.scope); - if (og_queue_task_command(dbi, &task, query)) { - dbi_result_free(result); - return -1; - } - } - - dbi_result_free(result); - - return 0; -} - -int og_dbi_update_action(uint32_t id, bool success) -{ - char end_date_string[24]; - struct tm *end_date; - const char *msglog; - struct og_dbi *dbi; - uint8_t status = 2; - dbi_result result; - time_t now; - - if (!id) - return 0; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - time(&now); - end_date = localtime(&now); - - sprintf(end_date_string, "%hu/%hhu/%hhu %hhu:%hhu:%hhu", - end_date->tm_year + 1900, end_date->tm_mon + 1, - end_date->tm_mday, end_date->tm_hour, end_date->tm_min, - end_date->tm_sec); - result = dbi_conn_queryf(dbi->conn, - "UPDATE acciones SET fechahorafin='%s', " - "estado=%d, resultado=%d WHERE idaccion=%d", - end_date_string, ACCION_FINALIZADA, - status - success, id); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - og_dbi_close(dbi); - - return 0; -} - -void og_schedule_run(unsigned int task_id, unsigned int schedule_id, - enum og_schedule_type type) -{ - struct og_msg_params params = {}; - struct in_addr addr, netmask; - struct og_cmd *cmd, *next; - bool duplicated = false; - struct og_dbi *dbi; - unsigned int i; - int sd; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return; - } - - switch (type) { - case OG_SCHEDULE_TASK: - og_dbi_queue_task(dbi, task_id, schedule_id); - break; - case OG_SCHEDULE_PROCEDURE: - case OG_SCHEDULE_COMMAND: - og_dbi_queue_command(dbi, task_id, schedule_id); - break; - } - og_dbi_close(dbi); - - list_for_each_entry(cmd, &cmd_list, list) { - for (i = 0; i < params.ips_array_len; i++) { - if (!strncmp(cmd->ip, params.ips_array[i], - OG_DB_IP_MAXLEN)) { - duplicated = true; - break; - } - } - - if (!duplicated) - params.ips_array[params.ips_array_len++] = strdup(cmd->ip); - else - duplicated = false; - } - - sd = wol_socket_open(); - if (sd < 0) { - syslog(LOG_ERR, "cannot open wol socket (%s:%d)\n", - __func__, __LINE__); - goto err_out; - } - - list_for_each_entry_safe(cmd, next, &cmd_list, list) { - if (cmd->type != OG_CMD_WOL) - continue; - - for (i = 0; i < cmd->params.ips_array_len; i++) { - if (inet_aton(cmd->params.ips_array[i], &addr) < 0) - continue; - if (inet_aton(cmd->params.netmask_array[i], &netmask) < 0) - continue; - - if (wake_up(sd, &addr, &netmask, - cmd->params.mac_array[i], - atoi(cmd->params.wol_type)) < 0) { - syslog(LOG_ERR, "Failed to send wol packet to %s\n", - params.ips_array[i]); - continue; - } - og_dbi_update_action(cmd->id, true); - } - - list_del(&cmd->list); - og_cmd_free(cmd); - } - - close(sd); - - og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, ¶ms, NULL); - -err_out: - for (i = 0; i < params.ips_array_len; i++) - free((void *)params.ips_array[i]); -} - -static int og_cmd_task_post(json_t *element, struct og_msg_params *params) -{ - struct og_cmd *cmd; - struct og_dbi *dbi; - const char *key; - json_t *value; - int err = 0; - - if (json_typeof(element) != JSON_OBJECT) - return -1; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "task")) { - err = og_json_parse_string(value, ¶ms->task_id); - params->flags |= OG_REST_PARAM_TASK; - } - - if (err < 0) - return err; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_TASK)) - return -1; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - og_schedule_run(atoi(params->task_id), 0, OG_SCHEDULE_TASK); - og_dbi_close(dbi); - - list_for_each_entry(cmd, &cmd_list, list) - params->ips_array[params->ips_array_len++] = cmd->ip; - - return og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, params, - NULL); -} - -#define OG_QUERY_MAXLEN 4096 - -static int og_dbi_scope_get_computer(const struct og_dbi *dbi, json_t *array, - const char* query) -{ - const char *computer_name, *computer_ip; - uint32_t computer_id; - const char *msglog; - dbi_result result; - json_t *computer; - - result = dbi_conn_queryf(dbi->conn, query); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - computer_id = dbi_result_get_uint(result, "idordenador"); - computer_name = dbi_result_get_string(result, "nombreordenador"); - computer_ip = dbi_result_get_string(result, "ip"); - - computer = json_object(); - if (!computer) { - dbi_result_free(result); - return -1; - } - - json_object_set_new(computer, "name", json_string(computer_name)); - json_object_set_new(computer, "type", json_string("computer")); - json_object_set_new(computer, "id", json_integer(computer_id)); - json_object_set_new(computer, "scope", json_array()); - json_object_set_new(computer, "ip", json_string(computer_ip)); - json_array_append(array, computer); - json_decref(computer); - } - dbi_result_free(result); - - return 0; -} - -static int og_dbi_scope_get_computer_from_room(const struct og_dbi *dbi, - json_t *array, char *query, - const uint32_t room_id) -{ - int ret = snprintf(query, OG_QUERY_MAXLEN, - "SELECT idordenador, nombreordenador, ip " - "FROM ordenadores WHERE idaula=%d and grupoid=0", - room_id); - if (ret <= 0 || ret >= OG_QUERY_MAXLEN) - return -1; - - return og_dbi_scope_get_computer(dbi, array, query); -} - -static int og_dbi_scope_get_computer_from_computers(const struct og_dbi *dbi, - json_t *array, - char *query, - const uint32_t computers_id) -{ - int ret = snprintf(query, OG_QUERY_MAXLEN, - "SELECT idordenador, nombreordenador, ip " - "FROM ordenadores WHERE grupoid=%d", - computers_id); - if (ret <= 0 || ret >= OG_QUERY_MAXLEN) - return -1; - - return og_dbi_scope_get_computer(dbi, array, query); -} - -static int og_dbi_scope_get_computers_from_computers(const struct og_dbi *dbi, - json_t *array, - char *query, - const uint32_t group_id); - -static int og_dbi_scope_get_computers(const struct og_dbi *dbi, json_t *array, - char *query, bool in_room) -{ - const char *msglog, *computers_name; - json_t *computers, *scope_array; - uint32_t computers_id; - uint32_t marker = 0; - dbi_result result; - - if (in_room) - marker = OG_COMPUTER_FOLDER_MARKER; - - result = dbi_conn_queryf(dbi->conn, query); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - computers_id = dbi_result_get_uint(result, "idgrupo"); - computers_name = dbi_result_get_string(result, - "nombregrupoordenador"); - - computers = json_object(); - if (!computers) { - dbi_result_free(result); - return -1; - } - - json_object_set_new(computers, "name", - json_string(computers_name)); - json_object_set_new(computers, "type", json_string("folder")); - json_object_set_new(computers, "id", - json_integer(computers_id | marker)); - json_object_set_new(computers, "scope", json_array()); - json_array_append(array, computers); - json_decref(computers); - - scope_array = json_object_get(computers, "scope"); - if (!scope_array) { - dbi_result_free(result); - return -1; - } - - if (og_dbi_scope_get_computers_from_computers(dbi, - scope_array, - query, - computers_id)) { - dbi_result_free(result); - return -1; - } - - if (og_dbi_scope_get_computer_from_computers(dbi, - scope_array, - query, - computers_id)) { - dbi_result_free(result); - return -1; - } - } - dbi_result_free(result); - - return 0; -} - -static int og_dbi_scope_get_computers_from_room(const struct og_dbi *dbi, - json_t *array, char *query, - const uint32_t room_id) -{ - int ret = snprintf(query, OG_QUERY_MAXLEN, - "SELECT idgrupo, nombregrupoordenador " - "FROM gruposordenadores " - "WHERE idaula=%d AND grupoid=0", - room_id); - if (ret <= 0 || ret >= OG_QUERY_MAXLEN) - return -1; - - return og_dbi_scope_get_computers(dbi, array, query, true); -} - -static int og_dbi_scope_get_computers_from_computers(const struct og_dbi *dbi, - json_t *array, - char *query, - const uint32_t group_id) -{ - int ret = snprintf(query, OG_QUERY_MAXLEN, - "SELECT idgrupo, nombregrupoordenador " - "FROM gruposordenadores WHERE grupoid=%d", - group_id); - if (ret <= 0 || ret >= OG_QUERY_MAXLEN) - return -1; - - return og_dbi_scope_get_computers(dbi, array, query, false); -} - -static int og_dbi_scope_get_room(const struct og_dbi *dbi, json_t *array, - char *query) -{ - const char *msglog, *room_name; - json_t *room, *scope_array; - dbi_result result; - uint32_t room_id; - - result = dbi_conn_queryf(dbi->conn, query); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - room_id = dbi_result_get_uint(result, "idaula"); - room_name = dbi_result_get_string(result, "nombreaula"); - - room = json_object(); - if (!room) { - dbi_result_free(result); - return -1; - } - - json_object_set_new(room, "name", json_string(room_name)); - json_object_set_new(room, "type", json_string("room")); - json_object_set_new(room, "id", json_integer(room_id)); - json_object_set_new(room, "scope", json_array()); - json_array_append(array, room); - json_decref(room); - - scope_array = json_object_get(room, "scope"); - if (!scope_array) { - dbi_result_free(result); - return -1; - } - - if (og_dbi_scope_get_computers_from_room(dbi, scope_array, - query, room_id)) { - dbi_result_free(result); - return -1; - } - - if (og_dbi_scope_get_computer_from_room(dbi, scope_array, - query, room_id)) { - dbi_result_free(result); - return -1; - } - } - dbi_result_free(result); - - return 0; -} - -static int og_dbi_scope_get_room_from_group(const struct og_dbi *dbi, - json_t *array, - char *query, - const uint32_t group_id) -{ - int ret = snprintf(query, OG_QUERY_MAXLEN, - "SELECT idaula, nombreaula " - "FROM aulas WHERE grupoid=%d", group_id); - if (ret <= 0 || ret >= OG_QUERY_MAXLEN) - return -1; - - return og_dbi_scope_get_room(dbi, array, query); -} - -static int og_dbi_scope_get_room_from_center(const struct og_dbi *dbi, - json_t *array, - char *query, - const uint32_t center_id) -{ - int ret = snprintf(query, OG_QUERY_MAXLEN, - "SELECT idaula, nombreaula " - "FROM aulas WHERE idcentro=%d AND grupoid=0", - center_id); - if (ret <= 0 || ret >= OG_QUERY_MAXLEN) - return -1; - - return og_dbi_scope_get_room(dbi, array, query); -} - -static int og_dbi_scope_get_group_from_group(const struct og_dbi *dbi, - json_t *array, - char *query, - const uint32_t group_id); - -static int og_dbi_scope_get_group(const struct og_dbi *dbi, - json_t *array, - char *query) -{ - const char *msglog, *group_name; - json_t *group, *scope_array; - dbi_result result; - uint32_t group_id; - - result = dbi_conn_queryf(dbi->conn, query); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - group_id = dbi_result_get_uint(result, "idgrupo"); - group_name = dbi_result_get_string(result, "nombregrupo"); - - group = json_object(); - if (!group) { - dbi_result_free(result); - return -1; - } - - json_object_set_new(group, "name", json_string(group_name)); - json_object_set_new(group, "type", json_string("folder")); - json_object_set_new(group, "id", json_integer(group_id)); - json_object_set_new(group, "scope", json_array()); - json_array_append(array, group); - json_decref(group); - - scope_array = json_object_get(group, "scope"); - if (!scope_array) { - dbi_result_free(result); - return -1; - } - - if (og_dbi_scope_get_group_from_group(dbi, scope_array, query, - group_id)) { - dbi_result_free(result); - return -1; - } - - if (og_dbi_scope_get_room_from_group(dbi, scope_array, query, - group_id)) { - dbi_result_free(result); - return -1; - } - } - dbi_result_free(result); - - return 0; -} - -static int og_dbi_scope_get_group_from_group(const struct og_dbi *dbi, - json_t *array, - char *query, - const uint32_t group_id) -{ - int ret = snprintf(query, OG_QUERY_MAXLEN, - "SELECT idgrupo, nombregrupo " - "FROM grupos WHERE grupoid=%d", group_id); - if (ret <= 0 || ret >= OG_QUERY_MAXLEN) - return -1; - - return og_dbi_scope_get_group(dbi, array, query); -} - -static int og_dbi_scope_get_group_from_center(const struct og_dbi *dbi, - json_t *array, - char *query, - const uint32_t center_id) -{ - int group_type_room = 2; - int ret = snprintf(query, OG_QUERY_MAXLEN, - "SELECT idgrupo, nombregrupo " - "FROM grupos " - "WHERE idcentro=%d AND grupoid=0 AND tipo=%d", - center_id, group_type_room); - if (ret <= 0 || ret >= OG_QUERY_MAXLEN) - return -1; - - return og_dbi_scope_get_group(dbi, array, query); -} - -static int og_dbi_scope_get(struct og_dbi *dbi, json_t *array) -{ - const char *msglog, *center_name; - json_t *center, *scope_array; - char query[OG_QUERY_MAXLEN]; - uint32_t center_id; - dbi_result result; - - result = dbi_conn_queryf(dbi->conn, - "SELECT nombrecentro, idcentro FROM centros"); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - while (dbi_result_next_row(result)) { - center_id = dbi_result_get_uint(result, "idcentro"); - center_name = dbi_result_get_string(result, "nombrecentro"); - - center = json_object(); - if (!center) { - dbi_result_free(result); - return -1; - } - - scope_array = json_array(); - if (!scope_array) { - dbi_result_free(result); - json_decref(center); - return -1; - } - - json_object_set_new(center, "name", json_string(center_name)); - json_object_set_new(center, "type", json_string("center")); - json_object_set_new(center, "id", json_integer(center_id)); - json_object_set_new(center, "scope", scope_array); - json_array_append(array, center); - json_decref(center); - - if (og_dbi_scope_get_group_from_center(dbi, scope_array, query, - center_id)) { - dbi_result_free(result); - return -1; - } - - if (og_dbi_scope_get_room_from_center(dbi, scope_array, query, - center_id)) { - dbi_result_free(result); - return -1; - } - } - - dbi_result_free(result); - - return 0; -} - static int og_cmd_scope_get(json_t *element, struct og_msg_params *params, char *buffer_reply) { @@ -6003,576 +4593,6 @@ static int og_cmd_scope_get(json_t *element, struct og_msg_params *params, return 0; } -int og_dbi_schedule_get(void) -{ - uint32_t schedule_id, task_id; - struct og_schedule_time time; - struct og_dbi *dbi; - const char *msglog; - dbi_result result; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - result = dbi_conn_queryf(dbi->conn, - "SELECT idprogramacion, tipoaccion, identificador, " - "sesion, annos, meses, diario, dias, semanas, horas, " - "ampm, minutos FROM programaciones " - "WHERE suspendida = 0"); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - - while (dbi_result_next_row(result)) { - memset(&time, 0, sizeof(time)); - schedule_id = dbi_result_get_uint(result, "idprogramacion"); - task_id = dbi_result_get_uint(result, "identificador"); - time.years = dbi_result_get_uint(result, "annos"); - time.months = dbi_result_get_uint(result, "meses"); - time.weeks = dbi_result_get_uint(result, "semanas"); - time.week_days = dbi_result_get_uint(result, "dias"); - time.days = dbi_result_get_uint(result, "diario"); - time.hours = dbi_result_get_uint(result, "horas"); - time.am_pm = dbi_result_get_uint(result, "ampm"); - time.minutes = dbi_result_get_uint(result, "minutos"); - time.check_stale = true; - - og_schedule_create(schedule_id, task_id, OG_SCHEDULE_TASK, - &time); - } - - dbi_result_free(result); - og_dbi_close(dbi); - - return 0; -} - -static int og_dbi_schedule_create(struct og_dbi *dbi, - struct og_msg_params *params, - uint32_t *schedule_id, - enum og_schedule_type schedule_type) -{ - uint8_t suspended = 0; - uint32_t session = 0; - const char *msglog; - dbi_result result; - uint8_t type; - - switch (schedule_type) { - case OG_SCHEDULE_TASK: - type = 3; - break; - case OG_SCHEDULE_PROCEDURE: - type = 2; - break; - case OG_SCHEDULE_COMMAND: - session = atoi(params->task_id); - type = 1; - break; - } - - result = dbi_conn_queryf(dbi->conn, - "INSERT INTO programaciones (tipoaccion," - " identificador, nombrebloque, annos, meses," - " semanas, dias, diario, horas, ampm, minutos," - " suspendida, sesion) VALUES (%d, %s, '%s'," - " %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", - type, params->task_id, params->name, - params->time.years, params->time.months, - params->time.weeks, params->time.week_days, - params->time.days, params->time.hours, - params->time.am_pm, params->time.minutes, - suspended, session); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - dbi_result_free(result); - - *schedule_id = dbi_conn_sequence_last(dbi->conn, NULL); - - return 0; -} - -static int og_dbi_schedule_update(struct og_dbi *dbi, - struct og_msg_params *params) -{ - const char *msglog; - dbi_result result; - uint8_t type = 3; - - result = dbi_conn_queryf(dbi->conn, - "UPDATE programaciones SET tipoaccion=%d, " - "identificador='%s', nombrebloque='%s', " - "annos=%d, meses=%d, " - "diario=%d, horas=%d, ampm=%d, minutos=%d " - "WHERE idprogramacion='%s'", - type, params->task_id, params->name, - params->time.years, params->time.months, - params->time.days, params->time.hours, - params->time.am_pm, params->time.minutes, - params->id); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - dbi_result_free(result); - - return 0; -} - -static int og_dbi_schedule_delete(struct og_dbi *dbi, uint32_t id) -{ - const char *msglog; - dbi_result result; - - result = dbi_conn_queryf(dbi->conn, - "DELETE FROM programaciones WHERE idprogramacion=%d", - id); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - dbi_result_free(result); - - return 0; -} - -struct og_db_schedule { - uint32_t id; - uint32_t task_id; - const char *name; - struct og_schedule_time time; - uint32_t week_days; - uint32_t weeks; - uint32_t suspended; - uint32_t session; -}; - -static int og_dbi_schedule_get_json(struct og_dbi *dbi, json_t *root, - const char *task_id, const char *schedule_id) -{ - struct og_db_schedule schedule; - json_t *obj, *array; - const char *msglog; - dbi_result result; - int err = 0; - - if (task_id) { - result = dbi_conn_queryf(dbi->conn, - "SELECT idprogramacion," - " identificador, nombrebloque," - " annos, meses, diario, dias," - " semanas, horas, ampm," - " minutos,suspendida, sesion " - "FROM programaciones " - "WHERE identificador=%d", - atoi(task_id)); - } else if (schedule_id) { - result = dbi_conn_queryf(dbi->conn, - "SELECT idprogramacion," - " identificador, nombrebloque," - " annos, meses, diario, dias," - " semanas, horas, ampm," - " minutos,suspendida, sesion " - "FROM programaciones " - "WHERE idprogramacion=%d", - atoi(schedule_id)); - } else { - result = dbi_conn_queryf(dbi->conn, - "SELECT idprogramacion," - " identificador, nombrebloque," - " annos, meses, diario, dias," - " semanas, horas, ampm," - " minutos,suspendida, sesion " - "FROM programaciones"); - } - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - return -1; - } - - array = json_array(); - if (!array) - return -1; - - while (dbi_result_next_row(result)) { - schedule.id = dbi_result_get_uint(result, "idprogramacion"); - schedule.task_id = dbi_result_get_uint(result, "identificador"); - schedule.name = dbi_result_get_string(result, "nombrebloque"); - schedule.time.years = dbi_result_get_uint(result, "annos"); - schedule.time.months = dbi_result_get_uint(result, "meses"); - schedule.time.days = dbi_result_get_uint(result, "diario"); - schedule.time.hours = dbi_result_get_uint(result, "horas"); - schedule.time.am_pm = dbi_result_get_uint(result, "ampm"); - schedule.time.minutes = dbi_result_get_uint(result, "minutos"); - schedule.week_days = dbi_result_get_uint(result, "dias"); - schedule.weeks = dbi_result_get_uint(result, "semanas"); - schedule.suspended = dbi_result_get_uint(result, "suspendida"); - schedule.session = dbi_result_get_uint(result, "sesion"); - - obj = json_object(); - if (!obj) { - err = -1; - break; - } - json_object_set_new(obj, "id", json_integer(schedule.id)); - json_object_set_new(obj, "task", json_integer(schedule.task_id)); - json_object_set_new(obj, "name", json_string(schedule.name)); - json_object_set_new(obj, "years", json_integer(schedule.time.years)); - json_object_set_new(obj, "months", json_integer(schedule.time.months)); - json_object_set_new(obj, "days", json_integer(schedule.time.days)); - json_object_set_new(obj, "hours", json_integer(schedule.time.hours)); - json_object_set_new(obj, "am_pm", json_integer(schedule.time.am_pm)); - json_object_set_new(obj, "minutes", json_integer(schedule.time.minutes)); - json_object_set_new(obj, "week_days", json_integer(schedule.week_days)); - json_object_set_new(obj, "weeks", json_integer(schedule.weeks)); - json_object_set_new(obj, "suspended", json_integer(schedule.suspended)); - json_object_set_new(obj, "session", json_integer(schedule.session)); - - json_array_append_new(array, obj); - } - - json_object_set_new(root, "schedule", array); - - dbi_result_free(result); - - return err; -} - -static int og_task_schedule_create(struct og_msg_params *params) -{ - enum og_schedule_type type; - uint32_t schedule_id; - struct og_dbi *dbi; - int err; - - if (!strcmp(params->type, "task")) - type = OG_SCHEDULE_TASK; - else if (!strcmp(params->type, "procedure")) - type = OG_SCHEDULE_PROCEDURE; - else if (!strcmp(params->type, "command")) - type = OG_SCHEDULE_COMMAND; - else - return -1; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - err = og_dbi_schedule_create(dbi, params, &schedule_id, type); - if (err < 0) { - og_dbi_close(dbi); - return -1; - } - og_schedule_create(schedule_id, atoi(params->task_id), type, - ¶ms->time); - og_schedule_refresh(og_loop); - og_dbi_close(dbi); - - return 0; -} - -static uint32_t og_tm_years_mask(struct tm *tm) -{ - int i, j = 0; - - for (i = 2010; i < 2026; i++, j++) { - if (tm->tm_year + 1900 == i) - break; - } - - return (1 << j); -} - -static uint32_t og_tm_months_mask(struct tm *tm) -{ - return 1 << tm->tm_mon; -} - -static uint16_t og_tm_hours_mask(struct tm *tm) -{ - return tm->tm_hour >= 12 ? 1 << (tm->tm_hour - 12) : 1 << tm->tm_hour; -} - -static uint32_t og_tm_ampm(struct tm *tm) -{ - return tm->tm_hour < 12 ? 0 : 1; -} - -static uint32_t og_tm_days_mask(struct tm *tm) -{ - return 1 << (tm->tm_mday - 1); -} - -static void og_schedule_time_now(struct og_schedule_time *ogtime) -{ - struct tm *tm; - time_t now; - - now = time(NULL); - tm = localtime(&now); - - ogtime->years = og_tm_years_mask(tm); - ogtime->months = og_tm_months_mask(tm); - ogtime->weeks = 0; - ogtime->week_days = 0; - ogtime->days = og_tm_days_mask(tm); - ogtime->hours = og_tm_hours_mask(tm); - ogtime->am_pm = og_tm_ampm(tm); - ogtime->minutes = tm->tm_min; -} - -static int og_cmd_schedule_create(json_t *element, struct og_msg_params *params) -{ - bool when = false; - const char *key; - json_t *value; - int err = 0; - - if (json_typeof(element) != JSON_OBJECT) - return -1; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "task")) { - err = og_json_parse_string(value, ¶ms->task_id); - params->flags |= OG_REST_PARAM_TASK; - } else if (!strcmp(key, "name")) { - err = og_json_parse_string(value, ¶ms->name); - params->flags |= OG_REST_PARAM_NAME; - } else if (!strcmp(key, "when")) { - err = og_json_parse_time_params(value, params); - when = true; - } else if (!strcmp(key, "type")) { - err = og_json_parse_string(value, ¶ms->type); - params->flags |= OG_REST_PARAM_TYPE; - } - - if (err < 0) - return err; - } - - if (!when) { - params->time.check_stale = false; - og_schedule_time_now(¶ms->time); - params->flags |= OG_REST_PARAM_TIME_YEARS | - OG_REST_PARAM_TIME_MONTHS | - OG_REST_PARAM_TIME_WEEKS | - OG_REST_PARAM_TIME_WEEK_DAYS | - OG_REST_PARAM_TIME_DAYS | - OG_REST_PARAM_TIME_HOURS | - OG_REST_PARAM_TIME_AM_PM | - OG_REST_PARAM_TIME_MINUTES; - } else { - params->time.check_stale = true; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_TASK | - OG_REST_PARAM_NAME | - OG_REST_PARAM_TIME_YEARS | - OG_REST_PARAM_TIME_MONTHS | - OG_REST_PARAM_TIME_WEEKS | - OG_REST_PARAM_TIME_WEEK_DAYS | - OG_REST_PARAM_TIME_DAYS | - OG_REST_PARAM_TIME_HOURS | - OG_REST_PARAM_TIME_MINUTES | - OG_REST_PARAM_TIME_AM_PM | - OG_REST_PARAM_TYPE)) - return -1; - - return og_task_schedule_create(params); -} - -static int og_cmd_schedule_update(json_t *element, struct og_msg_params *params) -{ - struct og_dbi *dbi; - bool when = false; - const char *key; - json_t *value; - int err = 0; - - if (json_typeof(element) != JSON_OBJECT) - return -1; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "id")) { - err = og_json_parse_string(value, ¶ms->id); - params->flags |= OG_REST_PARAM_ID; - } else if (!strcmp(key, "task")) { - err = og_json_parse_string(value, ¶ms->task_id); - params->flags |= OG_REST_PARAM_TASK; - } else if (!strcmp(key, "name")) { - err = og_json_parse_string(value, ¶ms->name); - params->flags |= OG_REST_PARAM_NAME; - } else if (!strcmp(key, "when")) { - err = og_json_parse_time_params(value, params); - when = true; - } - - if (err < 0) - return err; - } - - if (!when) { - params->time.check_stale = false; - og_schedule_time_now(¶ms->time); - params->flags |= OG_REST_PARAM_TIME_YEARS | - OG_REST_PARAM_TIME_MONTHS | - OG_REST_PARAM_TIME_WEEKS | - OG_REST_PARAM_TIME_WEEK_DAYS | - OG_REST_PARAM_TIME_DAYS | - OG_REST_PARAM_TIME_HOURS | - OG_REST_PARAM_TIME_AM_PM | - OG_REST_PARAM_TIME_MINUTES; - } else { - params->time.check_stale = true; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ID | - OG_REST_PARAM_TASK | - OG_REST_PARAM_NAME | - OG_REST_PARAM_TIME_YEARS | - OG_REST_PARAM_TIME_MONTHS | - OG_REST_PARAM_TIME_DAYS | - OG_REST_PARAM_TIME_HOURS | - OG_REST_PARAM_TIME_MINUTES | - OG_REST_PARAM_TIME_AM_PM)) - return -1; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - err = og_dbi_schedule_update(dbi, params); - og_dbi_close(dbi); - - if (err < 0) - return err; - - og_schedule_update(og_loop, atoi(params->id), atoi(params->task_id), - ¶ms->time); - og_schedule_refresh(og_loop); - - return err; -} - -static int og_cmd_schedule_delete(json_t *element, struct og_msg_params *params) -{ - struct og_dbi *dbi; - const char *key; - json_t *value; - int err = 0; - - if (json_typeof(element) != JSON_OBJECT) - return -1; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "id")) { - err = og_json_parse_string(value, ¶ms->id); - params->flags |= OG_REST_PARAM_ID; - } - - if (err < 0) - return err; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ID)) - return -1; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - err = og_dbi_schedule_delete(dbi, atoi(params->id)); - og_dbi_close(dbi); - - og_schedule_delete(og_loop, atoi(params->id)); - - return err; -} - -static int og_cmd_schedule_get(json_t *element, struct og_msg_params *params, - char *buffer_reply) -{ - struct og_buffer og_buffer = { - .data = buffer_reply, - }; - json_t *schedule_root; - struct og_dbi *dbi; - const char *key; - json_t *value; - int err = 0; - - if (element) { - if (json_typeof(element) != JSON_OBJECT) - return -1; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "task")) { - err = og_json_parse_string(value, - ¶ms->task_id); - } else if (!strcmp(key, "id")) { - err = og_json_parse_string(value, ¶ms->id); - } - - if (err < 0) - return err; - } - } - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - schedule_root = json_object(); - if (!schedule_root) { - og_dbi_close(dbi); - return -1; - } - - err = og_dbi_schedule_get_json(dbi, schedule_root, - params->task_id, params->id); - og_dbi_close(dbi); - - if (err >= 0) - err = json_dump_callback(schedule_root, og_json_dump_clients, - &og_buffer, JSON_ENSURE_ASCII); - - json_decref(schedule_root); - - return err; -} - #define OG_LIVE_JSON_FILE_PATH "/opt/opengnsys/etc/ogliveinfo.json" static int og_cmd_oglive_list(char *buffer_reply) @@ -6756,456 +4776,6 @@ static int og_cmd_post_center_delete(json_t *element, return 0; } -int og_procedure_add_steps(struct og_dbi *dbi, struct og_procedure *proc) -{ - struct og_procedure_step *step; - const char *legacy_params; - const char *msglog; - dbi_result result; - int i; - - for (i = 0; i < proc->num_steps; i++) { - step = &proc->steps[i]; - switch (step->type) { - case OG_STEP_COMMAND: - legacy_params = og_msg_params_to_legacy(&step->cmd); - if (!legacy_params) { - og_dbi_close(dbi); - return -1; - } - result = dbi_conn_queryf(dbi->conn, - "INSERT INTO procedimientos_acciones " - "(idprocedimiento, orden, parametros) " - "VALUES (%d, %d, '%s')", - proc->id, - step->position, - legacy_params); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, - "failed to add procedure command to database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - free((char *)legacy_params); - return -1; - } - - dbi_result_free(result); - free((char *)legacy_params); - break; - case OG_STEP_PROCEDURE: - result = dbi_conn_queryf(dbi->conn, - "INSERT INTO procedimientos_acciones " - "(idprocedimiento, orden, procedimientoid) " - "VALUES (%d, %d, %d)", - proc->id, - step->position, - step->procedure.id); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, - "failed to add procedure child to database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - break; - case OG_STEP_TASK: - syslog(LOG_ERR, "Procedures can not include tasks. " - "Invalid step: %d\n", - step->position); - return -1; - break; - } - } - - return 0; -} - -static int og_cmd_post_procedure_add(json_t *element, - struct og_msg_params *params) -{ - struct og_procedure proc = {}; - const char *key, *msglog; - struct og_dbi *dbi; - dbi_result result; - json_t *value; - int err = 0; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "center")) { - err = og_json_parse_string(value, ¶ms->id); - params->flags |= OG_REST_PARAM_ID; - } else if (!strcmp(key, "name")) { - err = og_json_parse_string(value, ¶ms->name); - params->flags |= OG_REST_PARAM_NAME; - } else if (!strcmp(key, "description")) { - err = og_json_parse_string(value, ¶ms->comment); - } else if (!strcmp(key, "steps")) { - err = og_json_parse_procedure(value, &proc); - } - - if (err < 0) - return err; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ID | - OG_REST_PARAM_NAME)) - return -1; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open conection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - result = dbi_conn_queryf(dbi->conn, - "SELECT descripcion FROM procedimientos " - "WHERE descripcion='%s' AND idcentro=%s", - params->name, params->id); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - - if (dbi_result_get_numrows(result) > 0) { - syslog(LOG_ERR, "Procedure with name %s already exists in the " - "center with id %s\n", - params->name, params->id); - dbi_result_free(result); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - - result = dbi_conn_queryf(dbi->conn, - "INSERT INTO procedimientos(" - "idcentro, descripcion, comentarios) " - "VALUES (%s, '%s', '%s')", - params->id, params->name, params->comment); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, - "failed to add procedure to database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - - proc.id = dbi_conn_sequence_last(dbi->conn, NULL); - err = og_procedure_add_steps(dbi, &proc); - - og_dbi_close(dbi); - - return err; -} - -static int og_cmd_post_procedure_delete(json_t *element, - struct og_msg_params *params) -{ - const char *key, *msglog; - struct og_dbi *dbi; - dbi_result result; - json_t *value; - int err = 0; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "id")) { - err = og_json_parse_string(value, ¶ms->id); - params->flags |= OG_REST_PARAM_ID; - } - if (err < 0) - return err; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ID)) - return -1; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open conection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - result = dbi_conn_queryf(dbi->conn, - "DELETE FROM procedimientos WHERE idprocedimiento=%s", - params->id); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } else if (dbi_result_get_numrows_affected(result) < 1) { - syslog(LOG_ERR, "delete did not modify any row (%s:%d)\n", - __func__, __LINE__); - } - - dbi_result_free(result); - - og_dbi_close(dbi); - return 0; -} - -static int og_cmd_post_procedure_update(json_t *element, - struct og_msg_params *params) -{ - struct og_procedure proc = {}; - const char *key, *msglog; - struct og_dbi *dbi; - dbi_result result; - json_t *value; - int err = 0; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "procedure")) { - err = og_json_parse_string(value, ¶ms->task_id); - params->flags |= OG_REST_PARAM_TASK; - } else if (!strcmp(key, "center")) { - err = og_json_parse_string(value, ¶ms->id); - params->flags |= OG_REST_PARAM_ID; - } else if (!strcmp(key, "name")) { - err = og_json_parse_string(value, ¶ms->name); - params->flags |= OG_REST_PARAM_NAME; - } else if (!strcmp(key, "description")) { - err = og_json_parse_string(value, ¶ms->comment); - } else if (!strcmp(key, "steps")) { - err = og_json_parse_procedure(value, &proc); - } - - if (err < 0) - return err; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_TASK | - OG_REST_PARAM_ID | - OG_REST_PARAM_NAME)) - return -1; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open conection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - result = dbi_conn_queryf(dbi->conn, - "SELECT descripcion FROM procedimientos " - "WHERE descripcion = '%s' AND idcentro = %s " - "AND idprocedimiento <> %s", - params->name, params->id, params->task_id); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - - if (dbi_result_get_numrows(result) > 0) { - syslog(LOG_ERR, "Procedure with name %s already exists in the " - "center with id %s\n", - params->name, params->id); - dbi_result_free(result); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - - result = dbi_conn_queryf(dbi->conn, - "UPDATE procedimientos SET idcentro = %s, " - "descripcion = '%s', comentarios = '%s' " - "WHERE idprocedimiento = %s", - params->id, params->name, params->comment, - params->task_id); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, - "failed to update procedure %s (%s:%d) %s\n", - params->task_id, __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - - result = dbi_conn_queryf(dbi->conn, - "DELETE FROM procedimientos_acciones " - "WHERE idprocedimiento = %s", - params->task_id); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, - "failed to delete old procedure %s steps (%s:%d) %s\n", - params->task_id, __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - - proc.id = atoll(params->task_id); - err = og_procedure_add_steps(dbi, &proc); - - og_dbi_close(dbi); - - return err; -} - -static int og_task_add_steps(struct og_dbi *dbi, struct og_procedure *task) -{ - struct og_procedure_step *step; - const char *msglog; - dbi_result result; - int i; - - for (i = 0; i < task->num_steps; i++) { - step = &task->steps[i]; - switch (step->type) { - case OG_STEP_COMMAND: - syslog(LOG_ERR, "Tasks can not include commands. " - "Invalid step: %d\n", - step->position); - return -1; - break; - case OG_STEP_PROCEDURE: - result = dbi_conn_queryf(dbi->conn, - "INSERT INTO tareas_acciones " - "(idtarea, orden, idprocedimiento) " - "VALUES (%d, %d, %d)", - task->id, - step->position, - step->procedure.id); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, - "failed to add procedure child to database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - break; - case OG_STEP_TASK: - result = dbi_conn_queryf(dbi->conn, - "INSERT INTO tareas_acciones " - "(idtarea, orden, tareaid) " - "VALUES (%d, %d, %d)", - task->id, - step->position, - step->procedure.id); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, - "failed to add task child to database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - break; - } - } - - return 0; -} - -static int og_cmd_post_task_add(json_t *element, - struct og_msg_params *params) -{ - struct og_procedure task = {}; - const char *key, *msglog; - struct og_dbi *dbi; - dbi_result result; - json_t *value; - int err = 0; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "center")) { - err = og_json_parse_string(value, ¶ms->id); - params->flags |= OG_REST_PARAM_ID; - } else if (!strcmp(key, "name")) { - err = og_json_parse_string(value, ¶ms->name); - params->flags |= OG_REST_PARAM_NAME; - } else if (!strcmp(key, "description")) { - err = og_json_parse_string(value, ¶ms->comment); - } else if (!strcmp(key, "steps")) { - err = og_json_parse_procedure(value, &task); - } - - if (err < 0) - return err; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ID | - OG_REST_PARAM_NAME)) - return -1; - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open conection database (%s:%d)\n", - __func__, __LINE__); - return -1; - } - - result = dbi_conn_queryf(dbi->conn, - "SELECT descripcion FROM tareas " - "WHERE descripcion='%s' AND idcentro=%s", - params->name, params->id); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - - if (dbi_result_get_numrows(result) > 0) { - syslog(LOG_ERR, "Task with name %s already exists in the " - "center with id %s\n", - params->name, params->id); - dbi_result_free(result); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - - result = dbi_conn_queryf(dbi->conn, - "INSERT INTO tareas(" - "idcentro, descripcion, comentarios) " - "VALUES (%s, '%s', '%s')", - params->id, params->name, params->comment); - - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, - "failed to add task to database (%s:%d) %s\n", - __func__, __LINE__, msglog); - og_dbi_close(dbi); - return -1; - } - dbi_result_free(result); - - task.id = dbi_conn_sequence_last(dbi->conn, NULL); - err = og_task_add_steps(dbi, &task); - - og_dbi_close(dbi); - - return err; -} - static int og_cmd_post_repository_update(json_t *element, struct og_msg_params *params, char *buffer_reply) @@ -7690,273 +5260,6 @@ static int og_cmd_post_room_delete(json_t *element, return 0; } -enum { - OG_SCHEDULE_CMD_TYPE = 0, - OG_SCHEDULE_CMD_PARAMS, -}; - -static bool og_cmd_validate(const struct og_cmd_json *cmd, - const uint64_t flags) -{ - return (cmd->flags & flags) == flags; -} - - -static int og_cmd_post_schedule_command(json_t *element, - struct og_msg_params *params) -{ - char *centerid_query = "SELECT o.idordenador, c.idcentro " - "FROM `ordenadores` AS o " - "INNER JOIN aulas AS a ON o.idaula = a.idaula " - "INNER JOIN centros AS c ON a.idcentro = c.idcentro " - "WHERE o.ip = '%s';"; - uint32_t sequence, session = 0; - int center_id, client_id, len; - struct og_cmd_json cmd = {}; - const char *legacy_params; - const char *key, *msglog; - struct og_dbi *dbi; - char task_id[128]; - bool when = false; - dbi_result result; - json_t *value; - int err = 0, i; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "clients")) { - err = og_json_parse_clients(value, params); - } else if (!strcmp(key, "command")) { - err = og_json_parse_string(value, &cmd.type); - cmd.flags |= OG_SCHEDULE_CMD_TYPE; - } else if (!strcmp(key, "params")) { - cmd.json = value; - cmd.flags |= OG_SCHEDULE_CMD_PARAMS; - } else if (!strcmp(key, "when")) { - err = og_json_parse_time_params(value, params); - when = true; - } - - if (err < 0) - return err; - } - - if (!og_cmd_validate(&cmd, OG_SCHEDULE_CMD_TYPE | - OG_SCHEDULE_CMD_PARAMS)) - return -1; - - if (!when) { - params->time.check_stale = false; - og_schedule_time_now(¶ms->time); - params->flags |= OG_REST_PARAM_TIME_YEARS | - OG_REST_PARAM_TIME_MONTHS | - OG_REST_PARAM_TIME_WEEKS | - OG_REST_PARAM_TIME_WEEK_DAYS | - OG_REST_PARAM_TIME_DAYS | - OG_REST_PARAM_TIME_HOURS | - OG_REST_PARAM_TIME_AM_PM | - OG_REST_PARAM_TIME_MINUTES; - } else { - params->time.check_stale = true; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR | - OG_REST_PARAM_TIME_YEARS | - OG_REST_PARAM_TIME_MONTHS | - OG_REST_PARAM_TIME_WEEKS | - OG_REST_PARAM_TIME_WEEK_DAYS | - OG_REST_PARAM_TIME_DAYS | - OG_REST_PARAM_TIME_HOURS | - OG_REST_PARAM_TIME_MINUTES | - OG_REST_PARAM_TIME_AM_PM)) - return -1; - - params->type = "command"; - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open conection database (%s:%d)\n", - __func__, __LINE__); - goto err_dbi_open; - } - - legacy_params = og_msg_params_to_legacy(&cmd); - if (!legacy_params) - goto err_legacy_params; - - /* ips_array -> ids */ - for (i = 0; i < params->ips_array_len; i++) { - - result = dbi_conn_queryf(dbi->conn, centerid_query, params->ips_array[i]); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - goto err_dbi_result; - } - if (dbi_result_get_numrows(result) != 1) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "client not found (%s:%d) %s\n", - __func__, __LINE__, msglog); - goto err_dbi; - } - - if (!dbi_result_next_row(result)) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to get idcentro (%s:%d) %s\n", - __func__, __LINE__, msglog); - goto err_dbi; - } - center_id = dbi_result_get_uint(result, "idcentro"); - if (!center_id) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to get idcentro (%s:%d) %s\n", - __func__, __LINE__, msglog); - goto err_dbi; - } - client_id = dbi_result_get_uint(result, "idordenador"); - dbi_result_free(result); - - result = dbi_conn_queryf(dbi->conn, "INSERT INTO acciones (idordenador, " - "idcentro, parametros)" - "VALUES (%d, %d, '%s')", - client_id, center_id, legacy_params); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - goto err_dbi_result; - } - dbi_result_free(result); - - sequence = dbi_conn_sequence_last(dbi->conn, NULL); - - /* This 'session' ID allows us to correlate the schedule with - * the commands after expansion. - */ - if (!session) - session = dbi_conn_sequence_last(dbi->conn, NULL); - - result = dbi_conn_queryf(dbi->conn, "UPDATE acciones SET idordenador=%d, " - "idcentro=%d, parametros='%s', sesion=%d" - "WHERE idaccion=%d", - client_id, center_id, legacy_params, - session, sequence); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - goto err_dbi_result; - } - dbi_result_free(result); - } - - len = snprintf(task_id, sizeof(session), "%d", session); - if (len >= (int)sizeof(task_id)) { - syslog(LOG_ERR, "truncated snprintf (%s:%d)\n", - __func__, __LINE__); - goto err_dbi_result; - } - params->task_id = task_id; - - og_task_schedule_create(params); - - free((char *)legacy_params); - og_dbi_close(dbi); - return 0; - -err_dbi: - dbi_result_free(result); -err_dbi_result: - free((char *)legacy_params); -err_legacy_params: - og_dbi_close(dbi); -err_dbi_open: - return -1; -} - -static int og_cmd_post_procedure_run(json_t *element, - struct og_msg_params *params) -{ - const char *centerid_query = "SELECT o.idordenador, c.idcentro " - "FROM `ordenadores` AS o " - "INNER JOIN aulas AS a " - "ON o.idaula = a.idaula " - "INNER JOIN centros AS c " - "ON a.idcentro = c.idcentro " - "WHERE o.ip = '%s';"; - struct og_task task = {}; - const char *key, *msglog; - struct og_dbi *dbi; - dbi_result result; - int i, err = 0; - json_t *value; - - json_object_foreach(element, key, value) { - if (!strcmp(key, "clients")) { - err = og_json_parse_clients(value, params); - } else if (!strcmp(key, "procedure")) { - err = og_json_parse_string(value, ¶ms->id); - params->flags |= OG_REST_PARAM_ID; - } - - if (err < 0) - goto err_return; - } - - if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR | - OG_REST_PARAM_ID )) - goto err_return; - - task.type_scope = AMBITO_ORDENADORES; - task.procedure_id = atoi(params->id); - - dbi = og_dbi_open(&ogconfig.db); - if (!dbi) { - syslog(LOG_ERR, "cannot open conection database (%s:%d)\n", - __func__, __LINE__); - goto err_return; - } - - for (i = 0; i < params->ips_array_len; i++) { - - result = dbi_conn_queryf(dbi->conn, centerid_query, params->ips_array[i]); - if (!result) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", - __func__, __LINE__, msglog); - goto err_close_dbi; - } - - if (dbi_result_get_numrows(result) != 1 || - !dbi_result_next_row(result) || - !dbi_result_get_uint(result, "idcentro") || - !dbi_result_get_uint(result, "idordenador")) { - dbi_conn_error(dbi->conn, &msglog); - syslog(LOG_ERR, "failed to get query data (%s:%d) %s\n", - __func__, __LINE__, msglog); - goto err_free_result; - } - - task.center_id = dbi_result_get_uint(result, "idcentro"); - task.scope = dbi_result_get_uint(result, "idordenador"); - dbi_result_free(result); - - if (og_dbi_queue_procedure(dbi, &task)) - goto err_close_dbi; - } - - og_dbi_close(dbi); - - return og_send_request(OG_METHOD_GET, OG_CMD_RUN_SCHEDULE, params, - NULL); - -err_free_result: - dbi_result_free(result); -err_close_dbi: - og_dbi_close(dbi); -err_return: - return -1; -} - static int og_cmd_get_servers(char *buffer_reply) { json_t *root, *servers, *address; @@ -8456,12 +5759,6 @@ struct { [OG_URI_CACHE_FETCH] = { "cache/fetch", }, [OG_URI_EFI] = { "efi", }, [OG_URI_PART_SETUP] = { "setup", }, - [OG_URI_RUN_SCHEDULE] = { "run/schedule", }, - [OG_URI_TASK_RUN] = { "task/run", }, - [OG_URI_SCHEDULE_CREATE] = { "schedule/create", }, - [OG_URI_SCHEDULE_DELETE] = { "schedule/delete", }, - [OG_URI_SCHEDULE_UPDATE] = { "schedule/update", }, - [OG_URI_SCHEDULE_GET] = { "schedule/get", }, [OG_URI_OGLIVE_LIST] = { "oglive/list", }, [OG_URI_OGLIVE_SET] = { "oglive/set", }, [OG_URI_CENTER_ADD] = { "center/add", }, @@ -8472,12 +5769,6 @@ struct { [OG_URI_ROOM_UPDATE] = { "room/update", }, [OG_URI_ROOM_DELETE] = { "room/delete", }, [OG_URI_ROOM_INFO] = { "room/info", }, - [OG_URI_PROC_ADD] = { "procedure/add", }, - [OG_URI_PROC_UPDATE] = { "procedure/update", }, - [OG_URI_PROC_RUN] = { "procedure/run", }, - [OG_URI_SCHEDULE_RUN] = { "schedule/command", }, - [OG_URI_PROC_DEL] = { "procedure/delete", }, - [OG_URI_TASK_ADD] = { "task/add", }, [OG_URI_SERVER] = { "server", }, [OG_URI_STATS] = { "stats", }, [OG_URI_FOLDER_ADD] = { "folder/add", }, @@ -8587,21 +5878,12 @@ int og_client_state_process_payload_rest(struct og_client *cli) uri = og_str_to_uri(cmd); if (!strncmp(cmd, "clients", strlen("clients"))) { - if (method != OG_METHOD_POST && - method != OG_METHOD_GET) { + if (method != OG_METHOD_GET) { err = og_client_method_not_found(cli); goto err_process_rest_payload; } - if (method == OG_METHOD_POST && !root) { - syslog(LOG_ERR, "command clients with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } switch (method) { - case OG_METHOD_POST: - err = og_cmd_post_clients(root, ¶ms); - break; case OG_METHOD_GET: err = og_cmd_get_clients(root, ¶ms, buf_reply); break; @@ -9117,78 +6399,6 @@ int og_client_state_process_payload_rest(struct og_client *cli) goto err_process_rest_payload; } err = og_cmd_setup(root, ¶ms); - } else if (!strncmp(cmd, "run/schedule", strlen("run/schedule"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, "command create with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - - err = og_cmd_run_schedule(root, ¶ms); - } else if (!strncmp(cmd, "task/run", strlen("task/run"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, "command task with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_task_post(root, ¶ms); - } else if (!strncmp(cmd, "schedule/create", - strlen("schedule/create"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, "command task with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_schedule_create(root, ¶ms); - } else if (!strncmp(cmd, "schedule/delete", - strlen("schedule/delete"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, "command task with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_schedule_delete(root, ¶ms); - } else if (!strncmp(cmd, "schedule/update", - strlen("schedule/update"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, "command task with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_schedule_update(root, ¶ms); - } else if (!strncmp(cmd, "schedule/get", - strlen("schedule/get"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - err = og_cmd_schedule_get(root, ¶ms, buf_reply); } else if (!strncmp(cmd, "oglive/list", strlen("oglive/list"))) { if (method != OG_METHOD_GET) { @@ -9310,85 +6520,6 @@ int og_client_state_process_payload_rest(struct og_client *cli) } err = og_cmd_get_room_info(root, ¶ms, buf_reply); - } else if (!strncmp(cmd, "procedure/add", strlen("procedure/add"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, - "command procedure add with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_post_procedure_add(root, ¶ms); - } else if (!strncmp(cmd, "procedure/update", - strlen("procedure/update"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, - "command procedure update with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_post_procedure_update(root, ¶ms); - } else if (!strncmp(cmd, "procedure/run", strlen("procedure/run"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, - "command procedure run with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_post_procedure_run(root, ¶ms); - } else if (!strncmp(cmd, "schedule/command", strlen("schedule/command"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, - "command schedule action with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_post_schedule_command(root, ¶ms); - } else if (!strncmp(cmd, "procedure/delete", strlen("schedule/command"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, - "command procedure delete with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_post_procedure_delete(root, ¶ms); - } else if (!strncmp(cmd, "task/add", strlen("task/add"))) { - if (method != OG_METHOD_POST) { - err = og_client_method_not_found(cli); - goto err_process_rest_payload; - } - - if (!root) { - syslog(LOG_ERR, - "command task add with no payload\n"); - err = og_client_bad_request(cli); - goto err_process_rest_payload; - } - err = og_cmd_post_task_add(root, ¶ms); } else if (!strncmp(cmd, "server", strlen("server"))) { switch (method) { case OG_METHOD_GET: @@ -3,6 +3,7 @@ #include <ev.h> #include <sys/time.h> +#include <netinet/in.h> extern struct ev_loop *og_loop; @@ -39,7 +40,6 @@ enum og_cmd_type { OG_CMD_IMAGE_RESTORE, OG_CMD_IMAGE_RESTRICT, OG_CMD_SETUP, - OG_CMD_RUN_SCHEDULE, OG_CMD_IMAGES, OG_CMD_CACHE_DELETE, OG_CMD_CACHE_FETCH, @@ -70,7 +70,6 @@ struct og_client { enum og_cmd_type last_cmd; unsigned int last_cmd_id; enum og_cmd_result last_cmd_result; - bool autorun; uint32_t speed; uint32_t seq; struct { @@ -132,12 +131,6 @@ enum og_rest_uri { OG_URI_CACHE_DELETE, OG_URI_CACHE_FETCH, OG_URI_PART_SETUP, - OG_URI_RUN_SCHEDULE, - OG_URI_TASK_RUN, - OG_URI_SCHEDULE_CREATE, - OG_URI_SCHEDULE_DELETE, - OG_URI_SCHEDULE_UPDATE, - OG_URI_SCHEDULE_GET, OG_URI_OGLIVE_LIST, OG_URI_OGLIVE_SET, OG_URI_CENTER_ADD, @@ -148,12 +141,6 @@ enum og_rest_uri { OG_URI_ROOM_UPDATE, OG_URI_ROOM_DELETE, OG_URI_ROOM_INFO, - OG_URI_PROC_ADD, - OG_URI_PROC_UPDATE, - OG_URI_PROC_RUN, - OG_URI_SCHEDULE_RUN, - OG_URI_PROC_DEL, - OG_URI_TASK_ADD, OG_URI_SERVER, OG_URI_STATS, OG_URI_FOLDER_ADD, @@ -173,20 +160,6 @@ int og_send_request(enum og_rest_method method, enum og_cmd_type type, const struct og_msg_params *params, const json_t *data); -struct og_cmd { - uint32_t id; - struct list_head list; - uint32_t client_id; - const char *ip; - const char *mac; - enum og_cmd_type type; - enum og_rest_method method; - struct og_msg_params params; - json_t *json; - struct timeval tv; -}; - -const struct og_cmd *og_cmd_find(const char *client_ip); -void og_cmd_free(const struct og_cmd *cmd); +int og_dbi_scope_get(struct og_dbi *dbi, json_t *array); #endif diff --git a/src/schedule.c b/src/schedule.c deleted file mode 100644 index 1f0816f..0000000 --- a/src/schedule.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (C) 2020-2021 Soleta Networks <info@soleta.eu> - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - */ - -#include "schedule.h" -#include "list.h" -#include <sys/types.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdlib.h> -#include <syslog.h> -#include <time.h> -#include <ev.h> - -struct og_schedule *current_schedule = NULL; -static LIST_HEAD(schedule_list); - -static void og_schedule_add(struct og_schedule *new) -{ - struct og_schedule *schedule, *next; - - list_for_each_entry_safe(schedule, next, &schedule_list, list) { - if (new->seconds < schedule->seconds) { - list_add_tail(&new->list, &schedule->list); - return; - } - } - list_add_tail(&new->list, &schedule_list); -} - -/* Returns the days in a month from the weekday. */ -static void get_days_from_weekday(struct tm *tm, int wday, int *days, int *j) -{ - int i, mday = 0; - - tm->tm_mday = 1; - - //Shift week to start on Sunday instead of Monday - if (wday == 6) - wday = 0; - else - wday++; - - /* A bit bruteforce, but simple. */ - for (i = 0; i <= 30; i++) { - mktime(tm); - /* Not this weekday, skip. */ - if (tm->tm_wday != wday) { - tm->tm_mday++; - continue; - } - /* Not interested in next month. */ - if (tm->tm_mday < mday) - break; - - /* Found a matching. */ - mday = tm->tm_mday; - days[(*j)++] = tm->tm_mday; - tm->tm_mday++; - } -} - -/* Returns the days in the given week. */ -static void get_days_from_week(struct tm *tm, int week, int *days, int *k) -{ - int i, j, week_counter = 0; - bool week_over = false; - - tm->tm_mday = 1; - - /* Remaining days of this month. */ - for (i = 0; i <= 30; i++) { - mktime(tm); - - /* Last day of this week? */ - if (tm->tm_wday == 6) - week_over = true; - - /* Not the week we are searching for. */ - if (week != week_counter) { - tm->tm_mday++; - if (week_over) { - week_counter++; - week_over = false; - } - continue; - } - - /* Found matching. */ - for (j = tm->tm_wday; j <= 6; j++) { - days[(*k)++] = tm->tm_mday++; - mktime(tm); - } - break; - } -} - -static int monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -static int last_month_day(struct tm *tm) -{ - /* Leap year? Adjust it. */ - if (tm->tm_mon == 1) { - tm->tm_mday = 29; - mktime(tm); - if (tm->tm_mday == 29) - return 29; - - tm->tm_mon = 1; - } - - return monthdays[tm->tm_mon]; -} - -/* Returns the days in the given week. */ -static void get_last_week(struct tm *tm, int *days, int *j) -{ - int i, last_day; - - last_day = last_month_day(tm); - tm->tm_mday = last_day; - - for (i = last_day; i >= last_day - 6; i--) { - mktime(tm); - - days[(*j)++] = tm->tm_mday; - - - /* Last day of this week? */ - if (tm->tm_wday == 1) - break; - - tm->tm_mday--; - } -} - -static void og_parse_years(uint16_t years_mask, int years[]) -{ - int i, j = 0; - - for (i = 0; i < 16; i++) { - if ((1 << i) & years_mask) - years[j++] = 2010 + i - 1900; - } -} - -static void og_parse_months(uint16_t months_mask, int months[]) -{ - int i, j = 0; - - for (i = 0; i < 12; i++) { - if ((1 << i) & months_mask) - months[j++] = i + 1; - } -} - -static void og_parse_days(uint32_t days_mask, int *days) -{ - int i, j = 0; - - for (i = 0; i < 31; i++) { - if ((1 << i) & days_mask) - days[j++] = i + 1; - } -} - -static void og_parse_hours(uint16_t hours_mask, uint8_t am_pm, int hours[]) -{ - int pm = 12 * am_pm; - int i, j = 0; - - for (i = 0; i < 12; i++) { - if ((1 << i) & hours_mask) - hours[j++] = i + pm + 1; - } -} - -static void og_schedule_remove_duplicates() -{ - struct og_schedule *schedule, *next, *prev = NULL; - - list_for_each_entry_safe(schedule, next, &schedule_list, list) { - if (!prev) { - prev = schedule; - continue; - } - if (prev->seconds == schedule->seconds && - prev->task_id == schedule->task_id) { - list_del(&prev->list); - free(prev); - } - prev = schedule; - } -} - -static bool og_schedule_stale(time_t seconds) -{ - time_t now; - - now = time(NULL); - if (seconds < now) - return true; - - return false; -} - -static void og_schedule_create_weekdays(int month, int year, - int *hours, int minutes, int week_days, - uint32_t task_id, uint32_t schedule_id, - enum og_schedule_type type, - bool check_stale) -{ - struct og_schedule *schedule; - int month_days[5]; - int n_month_days; - time_t seconds; - uint32_t wday; - struct tm tm; - int k, l; - - for (wday = 0; wday < 7; wday++) { - if (!((1 << wday) & week_days)) - continue; - - memset(&tm, 0, sizeof(tm)); - tm.tm_mon = month; - tm.tm_year = year; - - n_month_days = 0; - memset(month_days, 0, sizeof(month_days)); - get_days_from_weekday(&tm, wday, month_days, &n_month_days); - - for (k = 0; month_days[k] != 0 && k < n_month_days; k++) { - for (l = 0; hours[l] != 0 && l < 31; l++) { - memset(&tm, 0, sizeof(tm)); - tm.tm_year = year; - tm.tm_mon = month; - tm.tm_mday = month_days[k]; - tm.tm_hour = hours[l] - 1; - tm.tm_min = minutes; - tm.tm_isdst = -1; - seconds = mktime(&tm); - - if (check_stale && og_schedule_stale(seconds)) - continue; - - schedule = (struct og_schedule *) - calloc(1, sizeof(struct og_schedule)); - if (!schedule) - return; - - schedule->seconds = seconds; - schedule->task_id = task_id; - schedule->schedule_id = schedule_id; - schedule->type = type; - og_schedule_add(schedule); - } - } - } -} - -static void og_schedule_create_weeks(int month, int year, - int *hours, int minutes, int weeks, - uint32_t task_id, uint32_t schedule_id, - enum og_schedule_type type, bool check_stale) -{ - struct og_schedule *schedule; - int month_days[7]; - int n_month_days; - time_t seconds; - struct tm tm; - int week; - int k, l; - - for (week = 0; week < 5; week++) { - if (!((1 << week) & weeks)) - continue; - - memset(&tm, 0, sizeof(tm)); - tm.tm_mon = month; - tm.tm_year = year; - - n_month_days = 0; - memset(month_days, 0, sizeof(month_days)); - if (week == 5) - get_last_week(&tm, month_days, &n_month_days); - else - get_days_from_week(&tm, week, month_days, &n_month_days); - - for (k = 0; month_days[k] != 0 && k < n_month_days; k++) { - for (l = 0; hours[l] != 0 && l < 31; l++) { - memset(&tm, 0, sizeof(tm)); - tm.tm_year = year; - tm.tm_mon = month; - tm.tm_mday = month_days[k]; - tm.tm_hour = hours[l] - 1; - tm.tm_min = minutes; - tm.tm_isdst = -1; - seconds = mktime(&tm); - - if (check_stale && og_schedule_stale(seconds)) - continue; - - schedule = (struct og_schedule *) - calloc(1, sizeof(struct og_schedule)); - if (!schedule) - return; - - schedule->seconds = seconds; - schedule->task_id = task_id; - schedule->schedule_id = schedule_id; - schedule->type = type; - og_schedule_add(schedule); - } - } - } -} - -static void og_schedule_create_days(int month, int year, - int *hours, int minutes, int *days, - uint32_t task_id, uint32_t schedule_id, - enum og_schedule_type type, bool check_stale) -{ - struct og_schedule *schedule; - time_t seconds; - struct tm tm; - int k, l; - - for (k = 0; days[k] != 0 && k < 31; k++) { - for (l = 0; hours[l] != 0 && l < 31; l++) { - - memset(&tm, 0, sizeof(tm)); - tm.tm_year = year; - tm.tm_mon = month; - tm.tm_mday = days[k]; - tm.tm_hour = hours[l] - 1; - tm.tm_min = minutes; - tm.tm_isdst = -1; - seconds = mktime(&tm); - - if (check_stale && og_schedule_stale(seconds)) - continue; - - schedule = (struct og_schedule *) - calloc(1, sizeof(struct og_schedule)); - if (!schedule) - return; - - schedule->seconds = seconds; - schedule->task_id = task_id; - schedule->schedule_id = schedule_id; - schedule->type = type; - og_schedule_add(schedule); - } - } -} - -void og_schedule_create(unsigned int schedule_id, unsigned int task_id, - enum og_schedule_type type, - struct og_schedule_time *time) -{ - int year, month, minutes; - int months[12] = {}; - int years[12] = {}; - int hours[12] = {}; - int days[31] = {}; - int i, j; - - og_parse_years(time->years, years); - og_parse_months(time->months, months); - og_parse_days(time->days, days); - og_parse_hours(time->hours, time->am_pm, hours); - minutes = time->minutes; - - for (i = 0; years[i] != 0 && i < 12; i++) { - for (j = 0; months[j] != 0 && j < 12; j++) { - month = months[j] - 1; - year = years[i]; - - if (time->week_days) - og_schedule_create_weekdays(month, year, - hours, minutes, - time->week_days, - task_id, - schedule_id, - type, - time->check_stale); - - if (time->weeks) - og_schedule_create_weeks(month, year, - hours, minutes, - time->weeks, - task_id, - schedule_id, - type, time->check_stale); - - if (time->days) - og_schedule_create_days(month, year, - hours, minutes, - days, - task_id, - schedule_id, - type, time->check_stale); - } - } - - og_schedule_remove_duplicates(); -} - -void og_schedule_delete(struct ev_loop *loop, uint32_t schedule_id) -{ - struct og_schedule *schedule, *next; - - list_for_each_entry_safe(schedule, next, &schedule_list, list) { - if (schedule->schedule_id != schedule_id) - continue; - - list_del(&schedule->list); - if (current_schedule == schedule) { - ev_timer_stop(loop, &schedule->timer); - current_schedule = NULL; - og_schedule_refresh(loop); - } - free(schedule); - } -} - -void og_schedule_update(struct ev_loop *loop, unsigned int schedule_id, - unsigned int task_id, struct og_schedule_time *time) -{ - og_schedule_delete(loop, schedule_id); - og_schedule_create(schedule_id, task_id, OG_SCHEDULE_TASK, time); -} - -static void og_agent_timer_cb(struct ev_loop *loop, ev_timer *timer, int events) -{ - struct og_schedule *current; - - current = container_of(timer, struct og_schedule, timer); - og_schedule_run(current->task_id, current->schedule_id, current->type); - - ev_timer_stop(loop, timer); - list_del(¤t->list); - free(current); - - og_schedule_next(loop); -} - -void og_schedule_next(struct ev_loop *loop) -{ - struct og_schedule *schedule; - time_t now, seconds; - - if (list_empty(&schedule_list)) { - current_schedule = NULL; - return; - } - - schedule = list_first_entry(&schedule_list, struct og_schedule, list); - now = time(NULL); - if (schedule->seconds <= now) - seconds = 0; - else - seconds = schedule->seconds - now; - - ev_timer_init(&schedule->timer, og_agent_timer_cb, seconds, 0.); - ev_timer_start(loop, &schedule->timer); - current_schedule = schedule; -} - -void og_schedule_refresh(struct ev_loop *loop) -{ - if (current_schedule) - ev_timer_stop(loop, ¤t_schedule->timer); - - og_schedule_next(loop); -} diff --git a/src/schedule.h b/src/schedule.h deleted file mode 100644 index 69dbde9..0000000 --- a/src/schedule.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _OG_SCHEDULE_H_ -#define _OG_SCHEDULE_H_ - -#include <stdint.h> -#include <stdbool.h> -#include "dbi.h" -#include "list.h" -#include <ev.h> - -struct og_schedule_time { - uint32_t years; - uint32_t months; - uint32_t weeks; - uint32_t week_days; - uint32_t days; - uint32_t hours; - uint32_t am_pm; - uint32_t minutes; - bool check_stale; -}; - -enum og_schedule_type { - OG_SCHEDULE_TASK, - OG_SCHEDULE_PROCEDURE, - OG_SCHEDULE_COMMAND, -}; - -struct og_schedule { - struct list_head list; - struct ev_timer timer; - time_t seconds; - unsigned int task_id; - unsigned int schedule_id; - enum og_schedule_type type; -}; - -void og_schedule_create(unsigned int schedule_id, unsigned int task_id, - enum og_schedule_type type, - struct og_schedule_time *time); -void og_schedule_update(struct ev_loop *loop, unsigned int schedule_id, - unsigned int task_id, struct og_schedule_time *time); -void og_schedule_delete(struct ev_loop *loop, uint32_t schedule_id); -void og_schedule_next(struct ev_loop *loop); -void og_schedule_refresh(struct ev_loop *loop); -void og_schedule_run(unsigned int task_id, unsigned int schedule_id, - enum og_schedule_type type); - -int og_dbi_schedule_get(void); -int og_dbi_update_action(uint32_t id, bool success); - -struct og_task { - uint32_t task_id; - uint32_t procedure_id; - uint32_t command_id; - uint32_t center_id; - uint32_t schedule_id; - uint32_t type_scope; - uint32_t session; - uint32_t scope; - const char *filtered_scope; - const char *params; -}; - -int og_dbi_queue_procedure(struct og_dbi *dbi, struct og_task *task); - -#endif diff --git a/src/scope.c b/src/scope.c new file mode 100644 index 0000000..3f8e172 --- /dev/null +++ b/src/scope.c @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2020-2021 Soleta Networks <info@soleta.eu> + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + */ + +#include <syslog.h> +#include "dbi.h" +#include "utils.h" +#include "list.h" +#include "rest.h" + +#define OG_QUERY_MAXLEN 4096 + +static int og_dbi_scope_get_computer(const struct og_dbi *dbi, json_t *array, + const char* query) +{ + const char *computer_name, *computer_ip; + uint32_t computer_id; + const char *msglog; + dbi_result result; + json_t *computer; + + result = dbi_conn_queryf(dbi->conn, query); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + while (dbi_result_next_row(result)) { + computer_id = dbi_result_get_uint(result, "idordenador"); + computer_name = dbi_result_get_string(result, "nombreordenador"); + computer_ip = dbi_result_get_string(result, "ip"); + + computer = json_object(); + if (!computer) { + dbi_result_free(result); + return -1; + } + + json_object_set_new(computer, "name", json_string(computer_name)); + json_object_set_new(computer, "type", json_string("computer")); + json_object_set_new(computer, "id", json_integer(computer_id)); + json_object_set_new(computer, "scope", json_array()); + json_object_set_new(computer, "ip", json_string(computer_ip)); + json_array_append(array, computer); + json_decref(computer); + } + dbi_result_free(result); + + return 0; +} + +static int og_dbi_scope_get_computer_from_room(const struct og_dbi *dbi, + json_t *array, char *query, + const uint32_t room_id) +{ + int ret = snprintf(query, OG_QUERY_MAXLEN, + "SELECT idordenador, nombreordenador, ip " + "FROM ordenadores WHERE idaula=%d and grupoid=0", + room_id); + if (ret <= 0 || ret >= OG_QUERY_MAXLEN) + return -1; + + return og_dbi_scope_get_computer(dbi, array, query); +} + +static int og_dbi_scope_get_computer_from_computers(const struct og_dbi *dbi, + json_t *array, + char *query, + const uint32_t computers_id) +{ + int ret = snprintf(query, OG_QUERY_MAXLEN, + "SELECT idordenador, nombreordenador, ip " + "FROM ordenadores WHERE grupoid=%d", + computers_id); + if (ret <= 0 || ret >= OG_QUERY_MAXLEN) + return -1; + + return og_dbi_scope_get_computer(dbi, array, query); +} + +#define OG_COMPUTER_FOLDER_MARKER 0x00010000 + +static int og_dbi_scope_get_computers_from_computers(const struct og_dbi *dbi, + json_t *array, + char *query, + const uint32_t group_id); + +static int og_dbi_scope_get_computers(const struct og_dbi *dbi, json_t *array, + char *query, bool in_room) +{ + const char *msglog, *computers_name; + json_t *computers, *scope_array; + uint32_t computers_id; + uint32_t marker = 0; + dbi_result result; + + if (in_room) + marker = OG_COMPUTER_FOLDER_MARKER; + + result = dbi_conn_queryf(dbi->conn, query); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + while (dbi_result_next_row(result)) { + computers_id = dbi_result_get_uint(result, "idgrupo"); + computers_name = dbi_result_get_string(result, + "nombregrupoordenador"); + + computers = json_object(); + if (!computers) { + dbi_result_free(result); + return -1; + } + + json_object_set_new(computers, "name", + json_string(computers_name)); + json_object_set_new(computers, "type", json_string("folder")); + json_object_set_new(computers, "id", + json_integer(computers_id | marker)); + json_object_set_new(computers, "scope", json_array()); + json_array_append(array, computers); + json_decref(computers); + + scope_array = json_object_get(computers, "scope"); + if (!scope_array) { + dbi_result_free(result); + return -1; + } + + if (og_dbi_scope_get_computers_from_computers(dbi, + scope_array, + query, + computers_id)) { + dbi_result_free(result); + return -1; + } + + if (og_dbi_scope_get_computer_from_computers(dbi, + scope_array, + query, + computers_id)) { + dbi_result_free(result); + return -1; + } + } + dbi_result_free(result); + + return 0; +} + +static int og_dbi_scope_get_computers_from_room(const struct og_dbi *dbi, + json_t *array, char *query, + const uint32_t room_id) +{ + int ret = snprintf(query, OG_QUERY_MAXLEN, + "SELECT idgrupo, nombregrupoordenador " + "FROM gruposordenadores " + "WHERE idaula=%d AND grupoid=0", + room_id); + if (ret <= 0 || ret >= OG_QUERY_MAXLEN) + return -1; + + return og_dbi_scope_get_computers(dbi, array, query, true); +} + +static int og_dbi_scope_get_computers_from_computers(const struct og_dbi *dbi, + json_t *array, + char *query, + const uint32_t group_id) +{ + int ret = snprintf(query, OG_QUERY_MAXLEN, + "SELECT idgrupo, nombregrupoordenador " + "FROM gruposordenadores WHERE grupoid=%d", + group_id); + if (ret <= 0 || ret >= OG_QUERY_MAXLEN) + return -1; + + return og_dbi_scope_get_computers(dbi, array, query, false); +} + +static int og_dbi_scope_get_room(const struct og_dbi *dbi, json_t *array, + char *query) +{ + const char *msglog, *room_name; + json_t *room, *scope_array; + dbi_result result; + uint32_t room_id; + + result = dbi_conn_queryf(dbi->conn, query); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + while (dbi_result_next_row(result)) { + room_id = dbi_result_get_uint(result, "idaula"); + room_name = dbi_result_get_string(result, "nombreaula"); + + room = json_object(); + if (!room) { + dbi_result_free(result); + return -1; + } + + json_object_set_new(room, "name", json_string(room_name)); + json_object_set_new(room, "type", json_string("room")); + json_object_set_new(room, "id", json_integer(room_id)); + json_object_set_new(room, "scope", json_array()); + json_array_append(array, room); + json_decref(room); + + scope_array = json_object_get(room, "scope"); + if (!scope_array) { + dbi_result_free(result); + return -1; + } + + if (og_dbi_scope_get_computers_from_room(dbi, scope_array, + query, room_id)) { + dbi_result_free(result); + return -1; + } + + if (og_dbi_scope_get_computer_from_room(dbi, scope_array, + query, room_id)) { + dbi_result_free(result); + return -1; + } + } + dbi_result_free(result); + + return 0; +} + +static int og_dbi_scope_get_room_from_group(const struct og_dbi *dbi, + json_t *array, + char *query, + const uint32_t group_id) +{ + int ret = snprintf(query, OG_QUERY_MAXLEN, + "SELECT idaula, nombreaula " + "FROM aulas WHERE grupoid=%d", group_id); + if (ret <= 0 || ret >= OG_QUERY_MAXLEN) + return -1; + + return og_dbi_scope_get_room(dbi, array, query); +} + +static int og_dbi_scope_get_room_from_center(const struct og_dbi *dbi, + json_t *array, + char *query, + const uint32_t center_id) +{ + int ret = snprintf(query, OG_QUERY_MAXLEN, + "SELECT idaula, nombreaula " + "FROM aulas WHERE idcentro=%d AND grupoid=0", + center_id); + if (ret <= 0 || ret >= OG_QUERY_MAXLEN) + return -1; + + return og_dbi_scope_get_room(dbi, array, query); +} + +static int og_dbi_scope_get_group_from_group(const struct og_dbi *dbi, + json_t *array, + char *query, + const uint32_t group_id); + +static int og_dbi_scope_get_group(const struct og_dbi *dbi, + json_t *array, + char *query) +{ + const char *msglog, *group_name; + json_t *group, *scope_array; + dbi_result result; + uint32_t group_id; + + result = dbi_conn_queryf(dbi->conn, query); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + while (dbi_result_next_row(result)) { + group_id = dbi_result_get_uint(result, "idgrupo"); + group_name = dbi_result_get_string(result, "nombregrupo"); + + group = json_object(); + if (!group) { + dbi_result_free(result); + return -1; + } + + json_object_set_new(group, "name", json_string(group_name)); + json_object_set_new(group, "type", json_string("folder")); + json_object_set_new(group, "id", json_integer(group_id)); + json_object_set_new(group, "scope", json_array()); + json_array_append(array, group); + json_decref(group); + + scope_array = json_object_get(group, "scope"); + if (!scope_array) { + dbi_result_free(result); + return -1; + } + + if (og_dbi_scope_get_group_from_group(dbi, scope_array, query, + group_id)) { + dbi_result_free(result); + return -1; + } + + if (og_dbi_scope_get_room_from_group(dbi, scope_array, query, + group_id)) { + dbi_result_free(result); + return -1; + } + } + dbi_result_free(result); + + return 0; +} + +static int og_dbi_scope_get_group_from_group(const struct og_dbi *dbi, + json_t *array, + char *query, + const uint32_t group_id) +{ + int ret = snprintf(query, OG_QUERY_MAXLEN, + "SELECT idgrupo, nombregrupo " + "FROM grupos WHERE grupoid=%d", group_id); + if (ret <= 0 || ret >= OG_QUERY_MAXLEN) + return -1; + + return og_dbi_scope_get_group(dbi, array, query); +} + +static int og_dbi_scope_get_group_from_center(const struct og_dbi *dbi, + json_t *array, + char *query, + const uint32_t center_id) +{ + int group_type_room = 2; + int ret = snprintf(query, OG_QUERY_MAXLEN, + "SELECT idgrupo, nombregrupo " + "FROM grupos " + "WHERE idcentro=%d AND grupoid=0 AND tipo=%d", + center_id, group_type_room); + if (ret <= 0 || ret >= OG_QUERY_MAXLEN) + return -1; + + return og_dbi_scope_get_group(dbi, array, query); +} + +int og_dbi_scope_get(struct og_dbi *dbi, json_t *array) +{ + const char *msglog, *center_name; + json_t *center, *scope_array; + char query[OG_QUERY_MAXLEN]; + uint32_t center_id; + dbi_result result; + + result = dbi_conn_queryf(dbi->conn, + "SELECT nombrecentro, idcentro FROM centros"); + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", + __func__, __LINE__, msglog); + return -1; + } + + while (dbi_result_next_row(result)) { + center_id = dbi_result_get_uint(result, "idcentro"); + center_name = dbi_result_get_string(result, "nombrecentro"); + + center = json_object(); + if (!center) { + dbi_result_free(result); + return -1; + } + + scope_array = json_array(); + if (!scope_array) { + dbi_result_free(result); + json_decref(center); + return -1; + } + + json_object_set_new(center, "name", json_string(center_name)); + json_object_set_new(center, "type", json_string("center")); + json_object_set_new(center, "id", json_integer(center_id)); + json_object_set_new(center, "scope", scope_array); + json_array_append(array, center); + json_decref(center); + + if (og_dbi_scope_get_group_from_center(dbi, scope_array, query, + center_id)) { + dbi_result_free(result); + return -1; + } + + if (og_dbi_scope_get_room_from_center(dbi, scope_array, query, + center_id)) { + dbi_result_free(result); + return -1; + } + } + + dbi_result_free(result); + + return 0; +} |