mirror of https://git.48k.eu/ogserver
6627 lines
165 KiB
C
6627 lines
165 KiB
C
/*
|
|
* 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 "ogAdmServer.h"
|
|
#include "dbi.h"
|
|
#include "utils.h"
|
|
#include "list.h"
|
|
#include "rest.h"
|
|
#include "core.h"
|
|
#include "wol.h"
|
|
#include "cfg.h"
|
|
#include "repo.h"
|
|
#include <ev.h>
|
|
#include <syslog.h>
|
|
#include <sys/ioctl.h>
|
|
#include <ifaddrs.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <jansson.h>
|
|
#include <dirent.h>
|
|
#include <time.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/statvfs.h>
|
|
#include <sys/sysinfo.h>
|
|
|
|
struct ev_loop *og_loop;
|
|
|
|
#define OG_REST_PARAM_ADDR (1UL << 0)
|
|
#define OG_REST_PARAM_MAC (1UL << 1)
|
|
#define OG_REST_PARAM_WOL_TYPE (1UL << 2)
|
|
#define OG_REST_PARAM_RUN_CMD (1UL << 3)
|
|
#define OG_REST_PARAM_DISK (1UL << 4)
|
|
#define OG_REST_PARAM_PARTITION (1UL << 5)
|
|
#define OG_REST_PARAM_REPO (1UL << 6)
|
|
#define OG_REST_PARAM_NAME (1UL << 7)
|
|
#define OG_REST_PARAM_ID (1UL << 8)
|
|
#define OG_REST_PARAM_CODE (1UL << 9)
|
|
#define OG_REST_PARAM_TYPE (1UL << 10)
|
|
#define OG_REST_PARAM_PROFILE (1UL << 11)
|
|
#define OG_REST_PARAM_CACHE (1UL << 12)
|
|
#define OG_REST_PARAM_CACHE_SIZE (1UL << 13)
|
|
#define OG_REST_PARAM_PART_0 (1UL << 14)
|
|
#define OG_REST_PARAM_PART_1 (1UL << 15)
|
|
#define OG_REST_PARAM_PART_2 (1UL << 16)
|
|
#define OG_REST_PARAM_PART_3 (1UL << 17)
|
|
#define OG_REST_PARAM_SYNC_SYNC (1UL << 18)
|
|
#define OG_REST_PARAM_SYNC_DIFF (1UL << 19)
|
|
#define OG_REST_PARAM_SYNC_REMOVE (1UL << 20)
|
|
#define OG_REST_PARAM_SYNC_COMPRESS (1UL << 21)
|
|
#define OG_REST_PARAM_SYNC_CLEANUP (1UL << 22)
|
|
#define OG_REST_PARAM_SYNC_CACHE (1UL << 23)
|
|
#define OG_REST_PARAM_SYNC_CLEANUP_CACHE (1UL << 24)
|
|
#define OG_REST_PARAM_SYNC_REMOVE_DST (1UL << 25)
|
|
#define OG_REST_PARAM_SYNC_DIFF_ID (1UL << 26)
|
|
#define OG_REST_PARAM_SYNC_DIFF_NAME (1UL << 27)
|
|
#define OG_REST_PARAM_SYNC_PATH (1UL << 28)
|
|
#define OG_REST_PARAM_SYNC_METHOD (1UL << 29)
|
|
#define OG_REST_PARAM_ECHO (1UL << 30)
|
|
#define OG_REST_PARAM_TASK (1UL << 31)
|
|
#define OG_REST_PARAM_TIME_YEARS (1UL << 32)
|
|
#define OG_REST_PARAM_TIME_MONTHS (1UL << 33)
|
|
#define OG_REST_PARAM_TIME_WEEKS (1UL << 34)
|
|
#define OG_REST_PARAM_TIME_WEEK_DAYS (1UL << 35)
|
|
#define OG_REST_PARAM_TIME_DAYS (1UL << 36)
|
|
#define OG_REST_PARAM_TIME_HOURS (1UL << 37)
|
|
#define OG_REST_PARAM_TIME_AM_PM (1UL << 38)
|
|
#define OG_REST_PARAM_TIME_MINUTES (1UL << 39)
|
|
#define OG_REST_PARAM_NETMASK (1UL << 40)
|
|
#define OG_REST_PARAM_SCOPE (1UL << 41)
|
|
#define OG_REST_PARAM_MODE (1UL << 42)
|
|
#define OG_REST_PARAM_CENTER (1UL << 43)
|
|
#define OG_REST_PARAM_BACKUP (1UL << 44)
|
|
#define OG_REST_PARAM_ROOM (1UL << 45)
|
|
#define OG_REST_PARAM_GATEWAY (1UL << 46)
|
|
#define OG_REST_PARAM_FOLDER (1UL << 47)
|
|
|
|
static LIST_HEAD(client_list);
|
|
static LIST_HEAD(client_wol_list);
|
|
|
|
void og_client_add(struct og_client *cli)
|
|
{
|
|
list_add(&cli->list, &client_list);
|
|
}
|
|
|
|
struct og_client *__og_client_find(const struct in_addr *addr)
|
|
{
|
|
struct og_client *client;
|
|
|
|
list_for_each_entry(client, &client_list, list) {
|
|
if (!client->agent)
|
|
continue;
|
|
|
|
if (client->addr.sin_addr.s_addr == addr->s_addr)
|
|
return client;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static struct og_client *og_client_find(const char *ip)
|
|
{
|
|
struct in_addr addr;
|
|
int res;
|
|
|
|
res = inet_aton(ip, &addr);
|
|
if (!res) {
|
|
syslog(LOG_ERR, "Invalid IP string: %s\n", ip);
|
|
return NULL;
|
|
}
|
|
|
|
return __og_client_find(&addr);
|
|
}
|
|
|
|
static const char *og_client_status(const struct og_client *cli)
|
|
{
|
|
switch (cli->last_cmd) {
|
|
case OG_CMD_UNSPEC:
|
|
break;
|
|
default:
|
|
return "BSY";
|
|
}
|
|
|
|
switch (cli->status) {
|
|
case OG_CLIENT_STATUS_BUSY:
|
|
return "BSY";
|
|
case OG_CLIENT_STATUS_OGLIVE:
|
|
return "OPG";
|
|
case OG_CLIENT_STATUS_VIRTUAL:
|
|
return "VDI";
|
|
case OG_CLIENT_STATUS_LINUX:
|
|
return "LNX";
|
|
case OG_CLIENT_STATUS_LINUX_SESSION:
|
|
return "LNXS";
|
|
case OG_CLIENT_STATUS_WIN:
|
|
return "WIN";
|
|
case OG_CLIENT_STATUS_WIN_SESSION:
|
|
return "WINS";
|
|
default:
|
|
return "OFF";
|
|
}
|
|
}
|
|
|
|
static bool og_msg_params_validate(const struct og_msg_params *params,
|
|
const uint64_t flags)
|
|
{
|
|
return (params->flags & flags) == flags;
|
|
}
|
|
|
|
static bool og_flags_validate(const uint64_t flags,
|
|
const uint64_t required_flags)
|
|
{
|
|
return (flags & required_flags) == required_flags;
|
|
}
|
|
|
|
static int og_json_parse_clients(json_t *element, struct og_msg_params *params)
|
|
{
|
|
unsigned int i;
|
|
json_t *k;
|
|
|
|
if (json_typeof(element) != JSON_ARRAY)
|
|
return -1;
|
|
|
|
for (i = 0; i < json_array_size(element); i++) {
|
|
if (params->ips_array_len >= OG_CLIENTS_MAX)
|
|
return -1;
|
|
|
|
k = json_array_get(element, i);
|
|
if (json_typeof(k) != JSON_STRING)
|
|
return -1;
|
|
|
|
params->ips_array[params->ips_array_len++] =
|
|
json_string_value(k);
|
|
}
|
|
|
|
if (params->ips_array_len == 0)
|
|
return -1;
|
|
|
|
params->flags |= OG_REST_PARAM_ADDR;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int og_json_parse_partition_setup(json_t *element, struct og_msg_params *params)
|
|
{
|
|
unsigned int i;
|
|
json_t *k;
|
|
|
|
if (json_typeof(element) != JSON_ARRAY)
|
|
return -1;
|
|
|
|
for (i = 0; i < json_array_size(element) && i < OG_PARTITION_MAX; ++i) {
|
|
k = json_array_get(element, i);
|
|
|
|
if (json_typeof(k) != JSON_OBJECT)
|
|
return -1;
|
|
|
|
if (og_json_parse_partition(k, ¶ms->partition_setup[i],
|
|
OG_PARAM_PART_NUMBER |
|
|
OG_PARAM_PART_CODE |
|
|
OG_PARAM_PART_FILESYSTEM |
|
|
OG_PARAM_PART_SIZE |
|
|
OG_PARAM_PART_FORMAT) < 0)
|
|
return -1;
|
|
|
|
params->flags |= (OG_REST_PARAM_PART_0 << i);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static const char *og_cmd_to_uri[OG_CMD_MAX] = {
|
|
[OG_CMD_WOL] = "wol",
|
|
[OG_CMD_SHELL_RUN] = "shell/run",
|
|
[OG_CMD_SESSION] = "session",
|
|
[OG_CMD_POWEROFF] = "poweroff",
|
|
[OG_CMD_REFRESH] = "refresh",
|
|
[OG_CMD_REBOOT] = "reboot",
|
|
[OG_CMD_STOP] = "stop",
|
|
[OG_CMD_HARDWARE] = "hardware",
|
|
[OG_CMD_SOFTWARE] = "software",
|
|
[OG_CMD_IMAGE_CREATE] = "image/create",
|
|
[OG_CMD_IMAGE_UPDATE] = "image/update",
|
|
[OG_CMD_IMAGE_RESTORE] = "image/restore",
|
|
[OG_CMD_SETUP] = "setup",
|
|
[OG_CMD_IMAGES] = "images",
|
|
[OG_CMD_CACHE_DELETE] = "cache/delete",
|
|
[OG_CMD_CACHE_FETCH] = "cache/fetch",
|
|
};
|
|
|
|
static bool og_client_is_busy(const struct og_client *cli,
|
|
enum og_cmd_type type)
|
|
{
|
|
switch (type) {
|
|
case OG_CMD_REBOOT:
|
|
case OG_CMD_POWEROFF:
|
|
case OG_CMD_STOP:
|
|
break;
|
|
default:
|
|
if (cli->last_cmd != OG_CMD_UNSPEC)
|
|
return true;
|
|
break;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int og_send_request(enum og_rest_method method, enum og_cmd_type type,
|
|
const struct og_msg_params *params,
|
|
const json_t *data)
|
|
{
|
|
const char *content_type = "Content-Type: application/json";
|
|
char content [OG_MSG_REQUEST_MAXLEN - 700] = {};
|
|
char buf[OG_MSG_REQUEST_MAXLEN] = {};
|
|
unsigned int content_length;
|
|
char method_str[5] = {};
|
|
struct og_client *cli;
|
|
const char *uri;
|
|
unsigned int i;
|
|
int client_sd;
|
|
bool has_seq;
|
|
|
|
if (method == OG_METHOD_GET)
|
|
snprintf(method_str, 5, "GET");
|
|
else if (method == OG_METHOD_POST)
|
|
snprintf(method_str, 5, "POST");
|
|
else
|
|
return -1;
|
|
|
|
if (!data)
|
|
content_length = 0;
|
|
else
|
|
content_length = json_dumpb(data, content,
|
|
OG_MSG_REQUEST_MAXLEN - 700,
|
|
JSON_COMPACT | JSON_ENSURE_ASCII);
|
|
|
|
uri = og_cmd_to_uri[type];
|
|
|
|
switch (type) {
|
|
case OG_CMD_POWEROFF:
|
|
case OG_CMD_REBOOT:
|
|
case OG_CMD_STOP:
|
|
has_seq = false;
|
|
break;
|
|
default:
|
|
has_seq = true;
|
|
break;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
cli = og_client_find(params->ips_array[i]);
|
|
if (!cli)
|
|
continue;
|
|
|
|
if (og_client_is_busy(cli, type))
|
|
continue;
|
|
|
|
client_sd = cli->io.fd;
|
|
if (client_sd < 0) {
|
|
syslog(LOG_INFO, "Client %s not conected\n",
|
|
params->ips_array[i]);
|
|
continue;
|
|
}
|
|
|
|
if (++cli->seq == 0)
|
|
cli->seq++;
|
|
|
|
snprintf(buf, OG_MSG_REQUEST_MAXLEN,
|
|
"%s /%s HTTP/1.1\r\nContent-Length: %d\r\nX-Sequence: %u\r\n%s\r\n\r\n%s",
|
|
method_str, uri, content_length, has_seq ? cli->seq : 0, content_type, content);
|
|
|
|
if (send(client_sd, buf, strlen(buf), 0) < 0)
|
|
continue;
|
|
|
|
cli->last_cmd = type;
|
|
}
|
|
|
|
json_decref((json_t *)data);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct og_buffer {
|
|
char *data;
|
|
int len;
|
|
};
|
|
|
|
#define OG_MSG_RESPONSE_MAXLEN 262144
|
|
|
|
static int og_json_dump_clients(const char *buffer, size_t size, void *data)
|
|
{
|
|
struct og_buffer *og_buffer = (struct og_buffer *)data;
|
|
|
|
if (size >= OG_MSG_RESPONSE_MAXLEN - og_buffer->len) {
|
|
syslog(LOG_ERR, "Response JSON body is too large\n");
|
|
return -1;
|
|
}
|
|
|
|
memcpy(og_buffer->data + og_buffer->len, buffer, size);
|
|
og_buffer->len += size;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const char *og_cmd_result_str_array[] = {
|
|
[OG_UNKNOWN] = "unknown",
|
|
[OG_FAILURE] = "failure",
|
|
[OG_SUCCESS] = "success",
|
|
};
|
|
|
|
static const char *og_cmd_result_str(const enum og_cmd_result result)
|
|
{
|
|
if (result > OG_SUCCESS)
|
|
return "unknown";
|
|
|
|
return og_cmd_result_str_array[result];
|
|
}
|
|
|
|
static json_t *og_json_client_cmd_result(const enum og_cmd_result result)
|
|
{
|
|
const char *result_str;
|
|
json_t *last_cmd;
|
|
|
|
last_cmd = json_object();
|
|
result_str = og_cmd_result_str(result);
|
|
json_object_set_new(last_cmd, "result", json_string(result_str));
|
|
|
|
return last_cmd;
|
|
}
|
|
|
|
static int og_json_client_append(json_t *array, struct og_client *client)
|
|
{
|
|
json_t *addr, *state, *last_cmd, *object;
|
|
|
|
object = json_object();
|
|
if (!object)
|
|
return -1;
|
|
|
|
addr = json_string(inet_ntoa(client->addr.sin_addr));
|
|
if (!addr) {
|
|
json_decref(object);
|
|
return -1;
|
|
}
|
|
json_object_set_new(object, "addr", addr);
|
|
state = json_string(og_client_status(client));
|
|
if (!state) {
|
|
json_decref(object);
|
|
return -1;
|
|
}
|
|
json_object_set_new(object, "state", state);
|
|
json_object_set_new(object, "speed", json_integer(client->speed));
|
|
last_cmd = og_json_client_cmd_result(client->last_cmd_result);
|
|
json_object_set_new(object, "last_cmd", last_cmd);
|
|
json_array_append_new(array, object);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_json_client_wol_append(json_t *array,
|
|
struct og_client_wol *cli_wol)
|
|
{
|
|
json_t *addr, *state, *last_cmd, *object;
|
|
|
|
object = json_object();
|
|
if (!object)
|
|
return -1;
|
|
|
|
addr = json_string(inet_ntoa(cli_wol->addr));
|
|
if (!addr) {
|
|
json_decref(object);
|
|
return -1;
|
|
}
|
|
json_object_set_new(object, "addr", addr);
|
|
state = json_string(og_client_wol_status(cli_wol));
|
|
if (!state) {
|
|
json_decref(object);
|
|
return -1;
|
|
}
|
|
json_object_set_new(object, "state", state);
|
|
last_cmd = og_json_client_cmd_result(OG_UNKNOWN);
|
|
json_object_set_new(object, "last_cmd", last_cmd);
|
|
json_array_append_new(array, object);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_clients(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply,
|
|
};
|
|
struct og_client_wol *cli_wol;
|
|
struct og_client *client;
|
|
json_t *array, *root;
|
|
|
|
array = json_array();
|
|
if (!array)
|
|
return -1;
|
|
|
|
list_for_each_entry(cli_wol, &client_wol_list, list) {
|
|
if (og_json_client_wol_append(array, cli_wol) < 0) {
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
list_for_each_entry(client, &client_list, list) {
|
|
if (!client->agent)
|
|
continue;
|
|
|
|
if (og_json_client_append(array, client) < 0) {
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
root = json_pack("{s:o}", "clients", array);
|
|
if (!root) {
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_json_parse_type(json_t *element, struct og_msg_params *params)
|
|
{
|
|
const char *type;
|
|
|
|
if (json_typeof(element) != JSON_STRING)
|
|
return -1;
|
|
|
|
params->wol_type = json_string_value(element);
|
|
|
|
type = json_string_value(element);
|
|
if (!strcmp(type, "unicast"))
|
|
params->wol_type = "2";
|
|
else if (!strcmp(type, "broadcast"))
|
|
params->wol_type = "1";
|
|
|
|
params->flags |= OG_REST_PARAM_WOL_TYPE;
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct og_client_wol *og_client_wol_find(const struct in_addr *addr)
|
|
{
|
|
struct og_client_wol *cli_wol;
|
|
|
|
list_for_each_entry(cli_wol, &client_wol_list, list) {
|
|
if (cli_wol->addr.s_addr == addr->s_addr)
|
|
return cli_wol;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int og_cmd_wol(json_t *element, struct og_msg_params *params)
|
|
{
|
|
char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {};
|
|
struct og_msg_params new_params = {};
|
|
struct og_client_wol *cli_wol;
|
|
struct in_addr addr, netmask;
|
|
int ips_str_len = 0;
|
|
const char *msglog;
|
|
struct og_dbi *dbi;
|
|
int err = 0, i = 0;
|
|
dbi_result result;
|
|
const char *key;
|
|
json_t *value;
|
|
int sd;
|
|
|
|
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);
|
|
} else if (!strcmp(key, "type")) {
|
|
err = og_json_parse_type(value, params);
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_WOL_TYPE))
|
|
return -1;
|
|
|
|
for (i = 0; i < params->ips_array_len; ++i) {
|
|
ips_str_len += snprintf(ips_str + ips_str_len,
|
|
sizeof(ips_str) - ips_str_len,
|
|
"'%s',", params->ips_array[i]);
|
|
}
|
|
ips_str[ips_str_len - 1] = '\0';
|
|
|
|
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 ordenadores.ip, ordenadores.mac, "
|
|
"aulas.netmask "
|
|
"FROM ordenadores "
|
|
"INNER JOIN aulas "
|
|
"ON ordenadores.idaula = aulas.idaula "
|
|
"WHERE ordenadores.ip IN (%s)",
|
|
ips_str);
|
|
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;
|
|
}
|
|
|
|
for (i = 0; dbi_result_next_row(result); i++) {
|
|
if (i >= OG_CLIENTS_MAX) {
|
|
syslog(LOG_ERR, "too many IPs in WoL (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
goto err_free_params;
|
|
}
|
|
new_params.ips_array[i] = dbi_result_get_string_copy(result, "ip");
|
|
new_params.mac_array[i] = dbi_result_get_string_copy(result, "mac");
|
|
new_params.netmask_array[i] = dbi_result_get_string_copy(result, "netmask");
|
|
}
|
|
new_params.ips_array_len = i;
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
if (i == 0)
|
|
return 0;
|
|
|
|
sd = wol_socket_open();
|
|
if (sd < 0) {
|
|
syslog(LOG_ERR, "cannot open wol socket (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
goto err_free_params;
|
|
}
|
|
|
|
for (i = 0; i < new_params.ips_array_len; i++) {
|
|
if (og_client_find(new_params.ips_array[i]))
|
|
continue;
|
|
|
|
if (!inet_aton(new_params.ips_array[i], &addr))
|
|
continue;
|
|
|
|
cli_wol = og_client_wol_find(&addr);
|
|
if (cli_wol) {
|
|
og_client_wol_refresh(cli_wol);
|
|
continue;
|
|
}
|
|
|
|
cli_wol = og_client_wol_create(&addr);
|
|
if (!cli_wol)
|
|
goto err_out;
|
|
|
|
list_add_tail(&cli_wol->list, &client_wol_list);
|
|
|
|
if (!inet_aton(new_params.netmask_array[i], &netmask))
|
|
continue;
|
|
|
|
if (wake_up(sd, &addr, &netmask, new_params.mac_array[i],
|
|
atoi(params->wol_type)) < 0) {
|
|
syslog(LOG_ERR, "Failed to send wol packet to %s\n",
|
|
new_params.ips_array[i]);
|
|
continue;
|
|
}
|
|
}
|
|
err_out:
|
|
close(sd);
|
|
err_free_params:
|
|
for (i = 0; i < new_params.ips_array_len; ++i) {
|
|
free((void *)new_params.ips_array[i]);
|
|
free((void *)new_params.mac_array[i]);
|
|
free((void *)new_params.netmask_array[i]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_json_parse_run(json_t *element, struct og_msg_params *params)
|
|
{
|
|
if (json_typeof(element) != JSON_STRING)
|
|
return -1;
|
|
|
|
snprintf(params->run_cmd, sizeof(params->run_cmd), "%s",
|
|
json_string_value(element));
|
|
|
|
params->flags |= OG_REST_PARAM_RUN_CMD;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_run_post(json_t *element, struct og_msg_params *params)
|
|
{
|
|
json_t *value, *clients;
|
|
const char *key;
|
|
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);
|
|
else if (!strcmp(key, "run"))
|
|
err = og_json_parse_run(value, params);
|
|
else if (!strcmp(key, "echo")) {
|
|
err = og_json_parse_bool(value, ¶ms->echo);
|
|
params->flags |= OG_REST_PARAM_ECHO;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_RUN_CMD |
|
|
OG_REST_PARAM_ECHO))
|
|
return -1;
|
|
|
|
clients = json_copy(element);
|
|
json_object_del(clients, "clients");
|
|
|
|
return og_send_request(OG_METHOD_POST, OG_CMD_SHELL_RUN, params, clients);
|
|
}
|
|
|
|
static int og_cmd_run_get(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply,
|
|
};
|
|
json_t *root, *value, *array;
|
|
const char *key;
|
|
unsigned int i;
|
|
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;
|
|
|
|
array = json_array();
|
|
if (!array)
|
|
return -1;
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
json_t *object, *output, *addr, *cmd;
|
|
struct og_client *cli;
|
|
|
|
cli = og_client_find(params->ips_array[i]);
|
|
if (!cli || !cli->shell.tstamp)
|
|
continue;
|
|
|
|
object = json_object();
|
|
if (!object) {
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
addr = json_string(params->ips_array[i]);
|
|
if (!addr) {
|
|
json_decref(object);
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
json_object_set_new(object, "addr", addr);
|
|
|
|
cmd = json_string(cli->shell.cmd);
|
|
if (!cmd) {
|
|
json_decref(object);
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
json_object_set_new(object, "cmd", cmd);
|
|
|
|
output = json_string(cli->shell.output);
|
|
if (!output) {
|
|
json_decref(object);
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
json_object_set_new(object, "output", output);
|
|
json_object_set_new(object, "retcode", json_integer(cli->shell.retcode));
|
|
json_object_set_new(object, "tstamp", json_integer(cli->shell.tstamp));
|
|
|
|
json_array_append_new(array, object);
|
|
}
|
|
|
|
root = json_pack("{s:o}", "clients", array);
|
|
if (!root)
|
|
return -1;
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define OG_SCRIPT_PATH "/opt/opengnsys/client/shell"
|
|
|
|
struct script_entry {
|
|
char name[FILENAME_MAX];
|
|
struct list_head list;
|
|
};
|
|
|
|
static void og_script_list_free(struct list_head *script_list)
|
|
{
|
|
struct script_entry *script, *tmp;
|
|
|
|
list_for_each_entry_safe(script, tmp, script_list, list) {
|
|
list_del(&script->list);
|
|
free(script);
|
|
}
|
|
}
|
|
|
|
static int og_get_client_scripts(struct list_head *script_list)
|
|
{
|
|
struct script_entry *script;
|
|
struct dirent *dent;
|
|
struct stat st;
|
|
DIR *d;
|
|
|
|
if (stat(OG_SCRIPT_PATH, &st) < 0 && errno == ENOENT)
|
|
mkdir(OG_SCRIPT_PATH, 0755);
|
|
|
|
d = opendir(OG_SCRIPT_PATH);
|
|
if (!d) {
|
|
syslog(LOG_ERR, "Cannot open directory %s (%s:%d)\n",
|
|
OG_SCRIPT_PATH, __func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
dent = readdir(d);
|
|
while (dent) {
|
|
if (dent->d_type != DT_REG) {
|
|
dent = readdir(d);
|
|
continue;
|
|
}
|
|
|
|
script = calloc(1, sizeof(struct script_entry));
|
|
if (!script) {
|
|
closedir(d);
|
|
og_script_list_free(script_list);
|
|
return -1;
|
|
}
|
|
|
|
snprintf(script->name, FILENAME_MAX, "%s", dent->d_name);
|
|
list_add_tail(&script->list, script_list);
|
|
|
|
dent = readdir(d);
|
|
}
|
|
closedir(d);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_shell_list(char *buffer_reply)
|
|
{
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
struct script_entry *entry;
|
|
json_t *root, *script_arr;
|
|
LIST_HEAD(script_list);
|
|
|
|
if (og_get_client_scripts(&script_list) < 0)
|
|
return -1;
|
|
|
|
root = json_object();
|
|
if (!root) {
|
|
og_script_list_free(&script_list);
|
|
return -1;
|
|
}
|
|
|
|
script_arr = json_array();
|
|
if (!script_arr) {
|
|
og_script_list_free(&script_list);
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
list_for_each_entry(entry, &script_list, list)
|
|
json_array_append_new(script_arr, json_string(entry->name));
|
|
|
|
json_object_set_new(root, "scripts", script_arr);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
og_script_list_free(&script_list);
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
og_script_list_free(&script_list);
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_session(json_t *element, struct og_msg_params *params)
|
|
{
|
|
json_t *clients, *value;
|
|
const char *key;
|
|
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);
|
|
} else if (!strcmp(key, "disk")) {
|
|
err = og_json_parse_string(value, ¶ms->disk);
|
|
params->flags |= OG_REST_PARAM_DISK;
|
|
} else if (!strcmp(key, "partition")) {
|
|
err = og_json_parse_string(value, ¶ms->partition);
|
|
params->flags |= OG_REST_PARAM_PARTITION;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_DISK |
|
|
OG_REST_PARAM_PARTITION))
|
|
return -1;
|
|
|
|
clients = json_copy(element);
|
|
json_object_del(clients, "clients");
|
|
|
|
return og_send_request(OG_METHOD_POST, OG_CMD_SESSION, params, clients);
|
|
}
|
|
|
|
static int og_json_os_array_get(struct og_dbi *dbi, json_t *array, const char *ip)
|
|
{
|
|
unsigned int disk, partition;
|
|
const char *os_name;
|
|
const char *msglog;
|
|
dbi_result result;
|
|
json_t *item;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT op.numdisk, op.numpar, nom.nombreso "
|
|
"FROM ordenadores o "
|
|
"INNER JOIN ordenadores_particiones op "
|
|
" ON o.idordenador = op.idordenador "
|
|
"INNER JOIN nombresos nom "
|
|
" ON op.idnombreso = nom.idnombreso "
|
|
"WHERE o.ip = '%s'", ip);
|
|
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)) {
|
|
item = json_object();
|
|
if (!item) {
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
|
|
disk = dbi_result_get_uint(result, "numdisk");
|
|
partition = dbi_result_get_uint(result, "numpar");
|
|
os_name = dbi_result_get_string(result, "nombreso");
|
|
|
|
json_object_set_new(item, "disk", json_integer(disk));
|
|
json_object_set_new(item, "partition", json_integer(partition));
|
|
json_object_set_new(item, "name", json_string(os_name));
|
|
json_array_append_new(array, item);
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_session(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
json_t *value, *root, *array;
|
|
struct og_dbi *dbi;
|
|
const char *key;
|
|
int err = 0, i;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "client")) /* alias for backward compatibility */
|
|
err = og_json_parse_clients(value, params);
|
|
else if (!strcmp(key, "clients"))
|
|
err = og_json_parse_clients(value, params);
|
|
else
|
|
err = -1;
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
array = json_array();
|
|
if (!array) {
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
if (og_json_os_array_get(dbi, array, params->ips_array[i]) < 0) {
|
|
json_decref(array);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
root = json_object();
|
|
if (!root){
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(root, "sessions", array);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_poweroff(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_POWEROFF, params, NULL);
|
|
}
|
|
|
|
static int og_cmd_refresh(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_GET, OG_CMD_REFRESH, params, NULL);
|
|
}
|
|
|
|
static int og_cmd_reboot(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_REBOOT, params, NULL);
|
|
}
|
|
|
|
#define OG_TFTP_TMPL_PATH_UEFI "/opt/opengnsys/tftpboot/grub/templates"
|
|
#define OG_TFTP_TMPL_PATH "/opt/opengnsys/tftpboot/menu.lst/templates"
|
|
|
|
struct og_boot_mode {
|
|
struct list_head list;
|
|
char name[FILENAME_MAX];
|
|
};
|
|
|
|
static void og_boot_mode_free(struct list_head *boot_mode_list)
|
|
{
|
|
struct og_boot_mode *mode, *tmp;
|
|
|
|
list_for_each_entry_safe(mode, tmp, boot_mode_list, list) {
|
|
list_del(&mode->list);
|
|
free(mode);
|
|
}
|
|
}
|
|
|
|
static int og_get_boot_modes(struct list_head *boot_mode_list)
|
|
{
|
|
struct og_boot_mode *mode;
|
|
struct dirent *dent;
|
|
DIR *d;
|
|
|
|
d = opendir(OG_TFTP_TMPL_PATH);
|
|
if (!d) {
|
|
syslog(LOG_ERR, "Cannot open directory %s (%s:%d)\n",
|
|
OG_TFTP_TMPL_PATH, __func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
dent = readdir(d);
|
|
while (dent) {
|
|
if (dent->d_type != DT_REG) {
|
|
dent = readdir(d);
|
|
continue;
|
|
}
|
|
|
|
mode = calloc(1, sizeof(struct og_boot_mode));
|
|
if (!mode) {
|
|
closedir(d);
|
|
og_boot_mode_free(boot_mode_list);
|
|
return -1;
|
|
}
|
|
|
|
snprintf(mode->name, FILENAME_MAX, "%s", dent->d_name);
|
|
list_add_tail(&mode->list, boot_mode_list);
|
|
|
|
dent = readdir(d);
|
|
}
|
|
closedir(d);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_modes(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
struct og_boot_mode *mode;
|
|
LIST_HEAD(boot_mode_list);
|
|
json_t *root, *modes;
|
|
int ret;
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
modes = json_array();
|
|
if (!modes) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
if (og_get_boot_modes(&boot_mode_list) < 0) {
|
|
json_decref(modes);
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
list_for_each_entry(mode, &boot_mode_list, list)
|
|
json_array_append_new(modes, json_string(mode->name));
|
|
|
|
og_boot_mode_free(&boot_mode_list);
|
|
json_object_set_new(root, "modes", modes);
|
|
|
|
ret = json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII);
|
|
json_decref(root);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int og_change_db_mode(struct og_dbi *dbi, const char *mac,
|
|
const char * mode)
|
|
{
|
|
const char *msglog;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE ordenadores SET arranque='%s' "
|
|
"WHERE mac='%s'",
|
|
mode, mac);
|
|
|
|
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 bool og_boot_mode_is_valid(const char *name)
|
|
{
|
|
struct og_boot_mode *mode;
|
|
LIST_HEAD(boot_mode_list);
|
|
bool found = false;
|
|
|
|
if (og_get_boot_modes(&boot_mode_list) < 0) {
|
|
syslog(LOG_ERR, "failed to get boot mode list (%s:%d)\n",
|
|
__FILE__, __LINE__);
|
|
return false;
|
|
}
|
|
|
|
list_for_each_entry(mode, &boot_mode_list, list) {
|
|
if (!strncmp(name, mode->name, FILENAME_MAX)) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
og_boot_mode_free(&boot_mode_list);
|
|
|
|
return found;
|
|
}
|
|
|
|
enum {
|
|
OG_TFTP_BOOT_BIOS,
|
|
OG_TFTP_BOOT_UEFI,
|
|
PXE_BOOT_TYPE_MAX,
|
|
};
|
|
|
|
const char *pxe_boot_type_to_dir[] = {
|
|
[OG_TFTP_BOOT_BIOS] = "/opt/opengnsys/tftpboot/menu.lst",
|
|
[OG_TFTP_BOOT_UEFI] = "/opt/opengnsys/tftpboot/grub"
|
|
};
|
|
|
|
static const char *pxe_boot_type(const int boot_type)
|
|
{
|
|
if (boot_type < 0 || boot_type >= PXE_BOOT_TYPE_MAX)
|
|
return NULL;
|
|
|
|
return pxe_boot_type_to_dir[boot_type];
|
|
}
|
|
|
|
static int get_grub_filename(unsigned int boot_type, const char *mac,
|
|
char *pxe_filename, size_t pxe_filename_size)
|
|
{
|
|
const char *fmt;
|
|
|
|
switch (boot_type) {
|
|
case OG_TFTP_BOOT_BIOS:
|
|
fmt = "01-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c";
|
|
break;
|
|
case OG_TFTP_BOOT_UEFI:
|
|
fmt = "01-%c%c:%c%c:%c%c:%c%c:%c%c:%c%c";
|
|
break;
|
|
default:
|
|
syslog(LOG_ERR, "unknown boot type %d", boot_type);
|
|
return -1;
|
|
}
|
|
|
|
snprintf(pxe_filename, pxe_filename_size, fmt,
|
|
mac[0], mac[1],
|
|
mac[2], mac[3],
|
|
mac[4], mac[5],
|
|
mac[6], mac[7],
|
|
mac[8], mac[9],
|
|
mac[10], mac[11]);
|
|
|
|
switch (boot_type) {
|
|
case OG_TFTP_BOOT_BIOS:
|
|
str_toupper(pxe_filename);
|
|
break;
|
|
case OG_TFTP_BOOT_UEFI:
|
|
str_tolower(pxe_filename);
|
|
break;
|
|
default:
|
|
syslog(LOG_ERR, "unknown boot type %d", boot_type);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int get_grub_file_path(unsigned int boot_type, const char *mac,
|
|
char *pxe_path, size_t pxe_path_size)
|
|
{
|
|
char pxe_filename[PATH_MAX + 1];
|
|
const char *pxe_dir;
|
|
int ret;
|
|
|
|
pxe_dir = pxe_boot_type(boot_type);
|
|
if (!pxe_dir) {
|
|
syslog(LOG_ERR, "Invalid boot type parameter (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
ret = get_grub_filename(boot_type, mac, pxe_filename, sizeof(pxe_filename));
|
|
|
|
if (ret < 0)
|
|
return -1;
|
|
|
|
ret = snprintf(pxe_path, pxe_path_size,
|
|
"%s/%s", pxe_dir, pxe_filename);
|
|
|
|
if (ret >= pxe_path_size) {
|
|
syslog(LOG_ERR, "failed to generate pxe file path (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int og_remove_tftpboot_file(unsigned int boot_type, const char *mac)
|
|
{
|
|
char pxe_file_path[PATH_MAX + 1];
|
|
int ret;
|
|
|
|
ret = get_grub_file_path(boot_type, mac, pxe_file_path, sizeof(pxe_file_path));
|
|
if (ret < 0)
|
|
return -1;
|
|
|
|
if (unlink(pxe_file_path) < 0) {
|
|
syslog(LOG_ERR, "failed to delete file (%s:%d) %s\n",
|
|
__func__, __LINE__, pxe_file_path);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int og_remove_tftpboot_files(struct og_dbi *dbi, const char *ip)
|
|
{
|
|
const char *msglog, *old_mac;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT mac FROM ordenadores WHERE ip='%s'", 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;
|
|
}
|
|
if (dbi_result_next_row(result)) {
|
|
old_mac = dbi_result_get_string(result, "mac");
|
|
og_remove_tftpboot_file(OG_TFTP_BOOT_BIOS, old_mac);
|
|
og_remove_tftpboot_file(OG_TFTP_BOOT_UEFI, old_mac);
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
return 0;
|
|
}
|
|
|
|
static int og_create_boot_file(unsigned int boot_type, const char *mac,
|
|
const char *mode, char *params)
|
|
{
|
|
char tmp_filename[] = "/tmp/mode_params_XXXXXX";
|
|
char pxe_template_path[PATH_MAX + 1];
|
|
char pxe_file_path[PATH_MAX + 1];
|
|
char cmd_params[16384] = {};
|
|
const char *pxe_dir;
|
|
int status;
|
|
pid_t pid;
|
|
int ret;
|
|
int fd;
|
|
|
|
pxe_dir = pxe_boot_type(boot_type);
|
|
if (!pxe_dir) {
|
|
syslog(LOG_ERR, "Invalid boot type parameter (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
snprintf(pxe_template_path, sizeof(pxe_template_path),
|
|
"%s/templates/%s", pxe_dir, mode);
|
|
|
|
ret = get_grub_file_path(boot_type, mac, pxe_file_path, sizeof(pxe_file_path));
|
|
if (ret < 0)
|
|
return -1;
|
|
|
|
if (unlink(pxe_file_path) < 0)
|
|
syslog(LOG_INFO, "failed to delete file %s (%s:%d)\n",
|
|
pxe_file_path, __func__, __LINE__);
|
|
|
|
snprintf(cmd_params, sizeof(cmd_params),
|
|
"DATA='%s'\nTEMPLATE_PATH='%s'\nPXEFILE_PATH='%s'",
|
|
params, pxe_template_path, pxe_file_path);
|
|
|
|
fd = mkstemp(tmp_filename);
|
|
if (fd < 0) {
|
|
syslog(LOG_ERR, "cannot generate temp file %s: %s (%s:%d)\n",
|
|
tmp_filename, strerror(errno), __func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
ret = write(fd, cmd_params, strlen(cmd_params) + 1);
|
|
close(fd);
|
|
|
|
if (ret < 0) {
|
|
syslog(LOG_ERR, "cannot write file %s: %s (%s:%d)\n",
|
|
tmp_filename, strerror(errno), __func__, __LINE__);
|
|
unlink(tmp_filename);
|
|
return -1;
|
|
}
|
|
|
|
pid = fork();
|
|
if (pid < 0) {
|
|
syslog(LOG_ERR, "fork failed (%s:%d) %s\n",
|
|
__func__, __LINE__, strerror(errno));
|
|
unlink(tmp_filename);
|
|
return -1;
|
|
}
|
|
|
|
if (pid == 0) {
|
|
execlp("/bin/bash", "/bin/bash",
|
|
"/opt/opengnsys/bin/updategrubprofile", tmp_filename, NULL);
|
|
syslog(LOG_ERR, "failed script execution (%s:%d) %s\n",
|
|
__func__, __LINE__, strerror(errno));
|
|
_exit(-1);
|
|
} else if (waitpid(pid, &status, 0) < 0) {
|
|
syslog(LOG_ERR, "waitpid failed (%s:%d) %s\n",
|
|
__func__, __LINE__, strerror(errno));
|
|
unlink(tmp_filename);
|
|
return -1;
|
|
}
|
|
|
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
|
syslog(LOG_ERR, "failed script execution %s (%s:%d)\n",
|
|
strerror(errno), __func__, __LINE__);
|
|
unlink(tmp_filename);
|
|
return -1;
|
|
}
|
|
|
|
unlink(tmp_filename);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct og_boot_mode_params {
|
|
const char *ntp;
|
|
const char *dns;
|
|
const char *proxy;
|
|
const char *ip;
|
|
const char *nombreaula;
|
|
const char *oglivedir;
|
|
const char *hardprofile;
|
|
const char *router;
|
|
const char *netmask;
|
|
const char *nombreordenador;
|
|
const char *netiface;
|
|
const char *directorio;
|
|
const char *resolucion;
|
|
uint32_t repoid;
|
|
int is_prof;
|
|
int has_unit;
|
|
};
|
|
|
|
static int og_get_client_mode_params(struct og_dbi *dbi, const char *mac, char *params, size_t params_size)
|
|
{
|
|
char repository_ip[OG_DB_IP_MAXLEN + 1] = {};
|
|
struct og_boot_mode_params boot_params = {};
|
|
char server_ip[OG_DB_IP_MAXLEN + 1] = {};
|
|
const char *res_prefix = " vga=";
|
|
const char *res_value = "788";
|
|
char *lang = getenv("LANG");
|
|
const char *msglog;
|
|
dbi_result result;
|
|
int err = 0;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT "
|
|
"ordenadores.ip AS ip, "
|
|
"aulas.router AS router, "
|
|
"aulas.netmask AS netmask, "
|
|
"ordenadores.nombreordenador AS nombreordenador, "
|
|
"ordenadores.netiface AS netiface, "
|
|
"REPLACE(TRIM(aulas.nombreaula), ' ', '_') AS nombreaula, "
|
|
"repositorios.idrepositorio AS repoid, "
|
|
"ordenadores.oglivedir AS oglivedir, "
|
|
"IF(ordenadores.idordenador = aulas.idordprofesor, 1, 0) AS is_prof, "
|
|
"REPLACE(TRIM(IFNULL(perfileshard.descripcion, '')), ' ', '_') AS hardprofile, "
|
|
"IFNULL(aulas.ntp, '') AS ntp, "
|
|
"IFNULL(aulas.dns, '') AS dns, "
|
|
"IFNULL(aulas.proxy, '') AS proxy, "
|
|
"IF(entidades.ogunit = 1 AND NOT centros.directorio = '', 1, 0) AS has_unit, "
|
|
"centros.directorio AS directorio, "
|
|
"IFNULL(menus.resolucion, '') AS resolucion "
|
|
"FROM ordenadores "
|
|
"JOIN aulas USING(idaula) "
|
|
"JOIN centros USING(idcentro) "
|
|
"JOIN entidades USING(identidad) "
|
|
"LEFT JOIN repositorios USING(idrepositorio) "
|
|
"LEFT JOIN perfileshard USING(idperfilhard) "
|
|
"LEFT JOIN menus USING(idmenu) "
|
|
"WHERE ordenadores.mac = '%s'", mac);
|
|
|
|
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_next_row(result)) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", // TODO
|
|
__func__, __LINE__, msglog);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
boot_params.ip = dbi_result_get_string_copy(result, "ip");
|
|
boot_params.router = dbi_result_get_string_copy(result, "router");
|
|
boot_params.netmask = dbi_result_get_string_copy(result, "netmask");
|
|
boot_params.nombreordenador = dbi_result_get_string_copy(result, "nombreordenador");
|
|
boot_params.netiface = dbi_result_get_string_copy(result, "netiface");
|
|
boot_params.nombreaula = dbi_result_get_string_copy(result, "nombreaula");
|
|
boot_params.oglivedir = dbi_result_get_string_copy(result, "oglivedir");
|
|
boot_params.hardprofile = dbi_result_get_string_copy(result, "hardprofile");
|
|
boot_params.ntp = dbi_result_get_string_copy(result, "ntp");
|
|
boot_params.dns = dbi_result_get_string_copy(result, "dns");
|
|
boot_params.proxy = dbi_result_get_string_copy(result, "proxy");
|
|
boot_params.directorio = dbi_result_get_string_copy(result, "directorio");
|
|
boot_params.resolucion = dbi_result_get_string_copy(result, "resolucion");
|
|
boot_params.repoid = dbi_result_get_uint(result, "repoid");
|
|
boot_params.has_unit = dbi_result_get_uint(result, "has_unit");
|
|
boot_params.is_prof = dbi_result_get_uint(result, "is_prof");
|
|
|
|
if (boot_params.resolucion[0]) {
|
|
res_value = boot_params.resolucion;
|
|
if (strchr(boot_params.resolucion, ':'))
|
|
res_prefix = " video=";
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
if (og_dbi_get_server_ip(dbi, boot_params.ip, server_ip) < 0) {
|
|
err = -1;
|
|
goto err_out;
|
|
}
|
|
|
|
if (og_dbi_get_repository_ip(dbi, boot_params.repoid, boot_params.ip,
|
|
repository_ip) < 0) {
|
|
err = -1;
|
|
goto err_out;
|
|
}
|
|
|
|
snprintf(params, params_size,
|
|
" LANG=%s ip=%s:%s:%s:%s:%s:%s:none group=%s ogrepo=%s oglive=%s oglog=%s ogshare=%s oglivedir=%s ogprof=%s server=%s fetch=http://%s/%s/filesystem.squashfs"
|
|
"%s%s%s%s%s%s%s%s%s%s%s%s",
|
|
lang,
|
|
boot_params.ip, server_ip, boot_params.router, boot_params.netmask, boot_params.nombreordenador, boot_params.netiface,
|
|
boot_params.nombreaula,
|
|
repository_ip,
|
|
server_ip, server_ip, server_ip,
|
|
boot_params.oglivedir,
|
|
boot_params.is_prof ? "true" : "false",
|
|
server_ip,
|
|
repository_ip,
|
|
boot_params.oglivedir,
|
|
boot_params.hardprofile[0] ? " hardprofile=" : "", boot_params.hardprofile[0] ? boot_params.hardprofile: "",
|
|
boot_params.ntp[0] ? " ogntp=" : "", boot_params.ntp[0] ? boot_params.ntp : "",
|
|
boot_params.dns[0] ? " ogdns=" : "", boot_params.dns[0] ? boot_params.dns : "",
|
|
boot_params.proxy[0] ? " ogproxy=" : "", boot_params.proxy[0] ? boot_params.proxy : "",
|
|
boot_params.has_unit ? " ogunit=" : "", boot_params.has_unit ? boot_params.directorio : "",
|
|
res_prefix, res_value);
|
|
err_out:
|
|
free((void *)boot_params.ip);
|
|
free((void *)boot_params.router);
|
|
free((void *)boot_params.netmask);
|
|
free((void *)boot_params.nombreordenador);
|
|
free((void *)boot_params.netiface);
|
|
free((void *)boot_params.nombreaula);
|
|
free((void *)boot_params.oglivedir);
|
|
free((void *)boot_params.hardprofile);
|
|
free((void *)boot_params.ntp);
|
|
free((void *)boot_params.dns);
|
|
free((void *)boot_params.proxy);
|
|
free((void *)boot_params.directorio);
|
|
free((void *)boot_params.resolucion);
|
|
|
|
return err;
|
|
}
|
|
|
|
static int og_set_client_mode(struct og_dbi *dbi, const char *client_ip,
|
|
const char *mac, const char *mode)
|
|
{
|
|
char params[4096];
|
|
|
|
if (!og_boot_mode_is_valid(mode)) {
|
|
syslog(LOG_ERR, "invalid boot mode in client (%s:%d)\n",
|
|
__FILE__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
if (og_get_client_mode_params(dbi, mac, params, sizeof(params)) < 0) {
|
|
syslog(LOG_ERR, "failed to get boot parameters (%s:%d)\n", __FILE__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
if (og_create_boot_file(OG_TFTP_BOOT_BIOS, mac, mode, params) < 0) {
|
|
syslog(LOG_ERR, "failed to create BIOS boot file (%s:%d)\n", __FILE__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
if (og_create_boot_file(OG_TFTP_BOOT_UEFI, mac, mode, params) < 0) {
|
|
og_remove_tftpboot_file(OG_TFTP_BOOT_BIOS, mac);
|
|
syslog(LOG_ERR, "failed to create UEFI boot file (%s:%d)\n", __FILE__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
if (og_change_db_mode(dbi, mac, mode) < 0) {
|
|
syslog(LOG_ERR, "failed to change db mode (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_modes(json_t *element, struct og_msg_params *params)
|
|
{
|
|
const char *mode_str, *mac;
|
|
const char *msglog;
|
|
struct og_dbi *dbi;
|
|
uint64_t flags = 0;
|
|
dbi_result result;
|
|
const char *key;
|
|
json_t *value;
|
|
int err = 0;
|
|
int i;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "clients")) {
|
|
err = og_json_parse_clients(value, params);
|
|
} else if (!strcmp(key, "mode")) {
|
|
err = og_json_parse_string(value, &mode_str);
|
|
flags |= OG_REST_PARAM_MODE;
|
|
} else {
|
|
err = -1;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_flags_validate(flags, OG_REST_PARAM_MODE) ||
|
|
!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT mac FROM ordenadores "
|
|
"WHERE ip = '%s'", 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);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
if (!dbi_result_next_row(result)) {
|
|
syslog(LOG_ERR, "could not find client IP: %s (%s:%d)\n",
|
|
params->ips_array[i], __func__, __LINE__);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
mac = dbi_result_get_string(result, "mac");
|
|
|
|
err = og_set_client_mode(dbi, params->ips_array[i], mac, mode_str);
|
|
if (err < 0) {
|
|
syslog(LOG_ERR, "cannot set boot mode for client IP: %s (%s:%d)\n",
|
|
params->ips_array[i], __func__, __LINE__);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_client_setup(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
json_t *value, *root, *partitions_array, *partition_json;
|
|
const char *key, *msglog;
|
|
unsigned int len_part;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
int err = 0;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
struct {
|
|
int disk;
|
|
int number;
|
|
int code;
|
|
uint64_t size;
|
|
int filesystem;
|
|
int format;
|
|
int os;
|
|
uint64_t used_size;
|
|
uint64_t free_size;
|
|
int image;
|
|
int software;
|
|
} partition;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "client")) {
|
|
err = og_json_parse_clients(value, params);
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
partitions_array = json_array();
|
|
if (!partitions_array) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
json_object_set_new(root, "partitions", partitions_array);
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
json_decref(root);
|
|
syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT numdisk, numpar, codpar, tamano, "
|
|
" idsistemafichero, idnombreso, "
|
|
" idimagen, idperfilsoft, used_size, free_size "
|
|
"FROM ordenadores_particiones "
|
|
"INNER JOIN ordenadores "
|
|
"ON ordenadores.idordenador = ordenadores_particiones.idordenador "
|
|
"WHERE ordenadores.ip='%s'",
|
|
params->ips_array[0]);
|
|
if (!result) {
|
|
json_decref(root);
|
|
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;
|
|
}
|
|
|
|
len_part = 0;
|
|
/* partition 0 represents the full disk, hence OG_PARTITION_MAX + 1. */
|
|
while (dbi_result_next_row(result) && len_part < OG_PARTITION_MAX + 1) {
|
|
partition.disk = dbi_result_get_int(result, "numdisk");
|
|
partition.number = dbi_result_get_int(result, "numpar");
|
|
partition.code = dbi_result_get_int(result, "codpar");
|
|
partition.size = dbi_result_get_longlong(result, "tamano");
|
|
partition.filesystem = dbi_result_get_int(result, "idsistemafichero");
|
|
partition.os = dbi_result_get_int(result, "idnombreso");
|
|
partition.image = dbi_result_get_int(result, "idimagen");
|
|
partition.software = dbi_result_get_int(result, "idperfilsoft");
|
|
partition.used_size = dbi_result_get_longlong(result, "used_size");
|
|
partition.free_size = dbi_result_get_longlong(result, "free_size");
|
|
|
|
partition_json = json_object();
|
|
if (!partition_json) {
|
|
json_decref(root);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(partition_json, "disk",
|
|
json_integer(partition.disk));
|
|
json_object_set_new(partition_json, "partition",
|
|
json_integer(partition.number));
|
|
json_object_set_new(partition_json, "code",
|
|
json_integer(partition.code));
|
|
json_object_set_new(partition_json, "size",
|
|
json_integer(partition.size));
|
|
json_object_set_new(partition_json, "used_size",
|
|
json_integer(partition.used_size));
|
|
json_object_set_new(partition_json, "free_size",
|
|
json_integer(partition.free_size));
|
|
json_object_set_new(partition_json, "filesystem",
|
|
json_integer(partition.filesystem));
|
|
json_object_set_new(partition_json, "os",
|
|
json_integer(partition.os));
|
|
json_object_set_new(partition_json, "image",
|
|
json_integer(partition.image));
|
|
json_object_set_new(partition_json, "software",
|
|
json_integer(partition.software));
|
|
json_array_append_new(partitions_array, partition_json);
|
|
|
|
++len_part;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
return 0;
|
|
}
|
|
|
|
static int og_dbi_update_client_repo(struct og_dbi *dbi, const char *mac,
|
|
uint32_t repo_id)
|
|
{
|
|
const char *msglog;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE ordenadores SET idrepositorio=%u "
|
|
"WHERE mac='%s'",
|
|
repo_id, mac);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to update client's server (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_client_repo(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {};
|
|
const char *key, *msglog, *mac;
|
|
int ips_str_len = 0;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
uint32_t repo_id;
|
|
int err = 0, i;
|
|
json_t *value;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "clients")) {
|
|
err = og_json_parse_clients(value, params);
|
|
} else if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, &repo_id);
|
|
params->flags |= OG_REST_PARAM_ID;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
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;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; ++i) {
|
|
ips_str_len += snprintf(ips_str + ips_str_len,
|
|
sizeof(ips_str) - ips_str_len,
|
|
"'%s',", params->ips_array[i]);
|
|
}
|
|
ips_str[ips_str_len - 1] = '\0';
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT mac FROM ordenadores "
|
|
"WHERE ip IN (%s)", ips_str);
|
|
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)) {
|
|
mac = dbi_result_get_string(result, "mac");
|
|
err = og_dbi_update_client_repo(dbi, mac, repo_id);
|
|
if (err != 0) {
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_center_info(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_center center = {};
|
|
json_t *value, *root;
|
|
struct og_dbi *dbi;
|
|
const char *key;
|
|
int err = 0;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, ¢er.id);
|
|
params->flags |= OG_REST_PARAM_CENTER;
|
|
}
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_CENTER))
|
|
return -1;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
if (og_dbi_get_center_info(dbi, ¢er)) {
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
og_dbi_close(dbi);
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
json_object_set_new(root, "comment",
|
|
json_string(center.comment));
|
|
json_object_set_new(root, "id",
|
|
json_integer(center.id));
|
|
json_object_set_new(root, "name",
|
|
json_string(center.name));
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_client_info(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_computer computer = {};
|
|
json_t *value, *root;
|
|
struct in_addr addr;
|
|
struct og_dbi *dbi;
|
|
const char *key;
|
|
int err = 0;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "client")) {
|
|
err = og_json_parse_clients(value, params);
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
if (!inet_aton(params->ips_array[0], &addr))
|
|
return -1;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
if (og_dbi_get_computer_info(dbi, &computer, addr)) {
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
json_object_set_new(root, "serial_number",
|
|
json_string(computer.serial_number));
|
|
json_object_set_new(root, "hardware_id",
|
|
json_integer(computer.hardware_id));
|
|
json_object_set_new(root, "netdriver", json_string(computer.netdriver));
|
|
json_object_set_new(root, "maintenance", json_boolean(computer.maintenance));
|
|
json_object_set_new(root, "netiface", json_string(computer.netiface));
|
|
json_object_set_new(root, "repo_id", json_integer(computer.repo_id));
|
|
json_object_set_new(root, "livedir", json_string(computer.livedir));
|
|
json_object_set_new(root, "netmask", json_string(computer.netmask));
|
|
json_object_set_new(root, "center", json_integer(computer.center));
|
|
json_object_set_new(root, "remote", json_boolean(computer.remote));
|
|
json_object_set_new(root, "room", json_integer(computer.room));
|
|
json_object_set_new(root, "name", json_string(computer.name));
|
|
json_object_set_new(root, "boot", json_string(computer.boot));
|
|
json_object_set_new(root, "mac", json_string(computer.mac));
|
|
json_object_set_new(root, "id", json_integer(computer.id));
|
|
json_object_set_new(root, "ip", json_string(computer.ip));
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_center_update(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
const char *key, *msglog;
|
|
uint32_t center_id;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
json_t *value;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "name")) {
|
|
err = og_json_parse_string(value, ¶ms->name);
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "comment")) {
|
|
err = og_json_parse_string(value, ¶ms->comment);
|
|
} else if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, ¢er_id);
|
|
params->flags |= OG_REST_PARAM_CENTER;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_CENTER | OG_REST_PARAM_NAME))
|
|
return -1;
|
|
if (!params->comment)
|
|
params->comment = "";
|
|
|
|
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 idcentro FROM centros WHERE idcentro='%u'",
|
|
center_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, "could not find a center with that id: %u\n",
|
|
center_id);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT idcentro FROM centros "
|
|
"WHERE nombrecentro='%s' and idcentro<>'%u'",
|
|
params->name, center_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_next_row(result)) {
|
|
center_id = dbi_result_get_uint(result, "idcentro");
|
|
syslog(LOG_ERR, "the center with id %u already has the name: %s\n",
|
|
center_id, params->name);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE centros"
|
|
" SET nombrecentro='%s',"
|
|
" comentarios='%s'"
|
|
" WHERE idcentro='%u';",
|
|
params->name, params->comment, center_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to update center in database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_client_update(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
const char *key, *msglog, *client_ip;
|
|
struct og_computer computer = {};
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
json_t *value;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "ip")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.ip,
|
|
sizeof(computer.ip));
|
|
params->flags |= OG_REST_PARAM_ADDR;
|
|
} else if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, &computer.id);
|
|
} else if (!strcmp(key, "serial_number")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.serial_number,
|
|
sizeof(computer.serial_number));
|
|
} else if (!strcmp(key, "netdriver")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.netdriver,
|
|
sizeof(computer.netdriver));
|
|
} else if (!strcmp(key, "maintenance")) {
|
|
err = og_json_parse_bool(value, &computer.maintenance);
|
|
} else if (!strcmp(key, "netiface")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.netiface,
|
|
sizeof(computer.netiface));
|
|
} else if (!strcmp(key, "repo_id")) {
|
|
err = og_json_parse_uint(value, &computer.repo_id);
|
|
} else if (!strcmp(key, "netmask")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.netmask,
|
|
sizeof(computer.netmask));
|
|
} else if (!strcmp(key, "remote")) {
|
|
err = og_json_parse_bool(value, &computer.remote);
|
|
} else if (!strcmp(key, "room")) {
|
|
err = og_json_parse_uint(value, &computer.room);
|
|
} else if (!strcmp(key, "name")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.name,
|
|
sizeof(computer.name));
|
|
} else if (!strcmp(key, "boot")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.boot,
|
|
sizeof(computer.boot));
|
|
} else if (!strcmp(key, "mac")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.mac,
|
|
sizeof(computer.mac));
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
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 ip FROM ordenadores WHERE ip='%s' AND idordenador<>'%u'",
|
|
computer.ip, computer.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, "client with IP %s already exist\n",
|
|
computer.ip);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT ip FROM ordenadores WHERE mac='%s' AND idordenador<>'%u'",
|
|
computer.mac, computer.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_next_row(result)) {
|
|
client_ip = dbi_result_get_string(result, "ip");
|
|
syslog(LOG_ERR, "client with MAC %s already exist in %s\n",
|
|
computer.mac, client_ip);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
og_remove_tftpboot_files(dbi, computer.ip);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE ordenadores"
|
|
" SET numserie='%s',"
|
|
" ip='%s',"
|
|
" netdriver='%s',"
|
|
" maintenance=%u,"
|
|
" netiface='%s',"
|
|
" idrepositorio=%u,"
|
|
" mascara='%s',"
|
|
" inremotepc=%u,"
|
|
" idaula=%u,"
|
|
" nombreordenador='%s',"
|
|
" mac='%s',"
|
|
" arranque='%s'"
|
|
" WHERE idordenador='%u';",
|
|
computer.serial_number,
|
|
computer.ip,
|
|
computer.netdriver, computer.maintenance,
|
|
computer.netiface, computer.repo_id,
|
|
computer.netmask, computer.remote,
|
|
computer.room, computer.name,
|
|
computer.mac, computer.boot,
|
|
computer.id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to update client in database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
if (og_set_client_mode(dbi, computer.ip, computer.mac, computer.boot)) {
|
|
syslog(LOG_ERR, "failed to set client boot mode (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int add_room_folder(struct og_dbi *dbi, struct og_folder *folder)
|
|
{
|
|
dbi_result result;
|
|
const char *msglog;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT nombregrupo FROM grupos WHERE nombregrupo='%s'",
|
|
folder->name);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
if (dbi_result_get_numrows(result) > 0) {
|
|
syslog(LOG_ERR, "room-folder with that name already exists: %s\n",
|
|
folder->name);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO grupos("
|
|
" nombregrupo,"
|
|
" grupoid,"
|
|
" tipo,"
|
|
" idcentro,"
|
|
" iduniversidad"
|
|
") VALUES ('%s', 0, 2, %u, 0)",
|
|
folder->name, folder->center);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to add room-folder to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int add_computer_folder(struct og_dbi *dbi, struct og_folder *folder)
|
|
{
|
|
dbi_result result;
|
|
const char *msglog;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT nombregrupoordenador FROM gruposordenadores WHERE nombregrupoordenador='%s'",
|
|
folder->name);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
if (dbi_result_get_numrows(result) > 0) {
|
|
syslog(LOG_ERR, "computer-folder with that name already exists: %s\n",
|
|
folder->name);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO gruposordenadores("
|
|
" nombregrupoordenador,"
|
|
" idaula,"
|
|
" grupoid"
|
|
") VALUES ('%s', %u, 0)",
|
|
folder->name, folder->room);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to add computer-folder to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
return 0;
|
|
}
|
|
|
|
static int og_computer_folder_update(struct og_dbi *dbi, struct og_folder *folder)
|
|
{
|
|
const char *msglog;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT idaula FROM gruposordenadores WHERE idgrupo='%u'",
|
|
folder->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;
|
|
}
|
|
if (!dbi_result_next_row(result)) {
|
|
syslog(LOG_ERR, "could not find a folder with that id: %u\n",
|
|
folder->id);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
folder->room = dbi_result_get_uint(result, "idaula");
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT idgrupo FROM gruposordenadores "
|
|
"WHERE nombregrupoordenador='%s' AND idaula=%u",
|
|
folder->name, folder->room);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
|
|
if (dbi_result_get_numrows(result) > 0) {
|
|
syslog(LOG_ERR, "Folder with name %s already exists in room "
|
|
"with id %d\n",
|
|
folder->name, folder->room);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE gruposordenadores"
|
|
" SET nombregrupoordenador='%s'"
|
|
" WHERE idgrupo='%u';",
|
|
folder->name, folder->id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to update room in database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_room_folder_update(struct og_dbi *dbi, struct og_folder *folder)
|
|
{
|
|
const char *msglog;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT idcentro FROM grupos WHERE idgrupo='%u'",
|
|
folder->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;
|
|
}
|
|
if (!dbi_result_next_row(result)) {
|
|
syslog(LOG_ERR, "could not find a folder with that id: %u\n",
|
|
folder->id);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
folder->center = dbi_result_get_uint(result, "idcentro");
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT idgrupo FROM grupos "
|
|
"WHERE nombregrupo='%s' AND idcentro=%u",
|
|
folder->name, folder->center);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
|
|
if (dbi_result_get_numrows(result) > 0) {
|
|
syslog(LOG_ERR, "Folder with name %s already exists in center "
|
|
"with id %d\n",
|
|
folder->name, folder->center);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE grupos"
|
|
" SET nombregrupo='%s'"
|
|
" WHERE idgrupo='%u';",
|
|
folder->name, folder->id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to update room in database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define OG_COMPUTER_FOLDER_MARKER 0x00010000
|
|
|
|
static int og_cmd_post_folder_update(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
struct og_folder folder = {};
|
|
struct og_dbi *dbi;
|
|
const char *key;
|
|
json_t *value;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "id")) {
|
|
params->flags |= OG_REST_PARAM_FOLDER;
|
|
err = og_json_parse_uint(value, &folder.id);
|
|
} else if (!strcmp(key, "name")) {
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
err = og_json_parse_string_copy(value,
|
|
folder.name,
|
|
sizeof(folder.name));
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
if (!og_msg_params_validate(params, 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;
|
|
}
|
|
if (folder.id & OG_COMPUTER_FOLDER_MARKER) {
|
|
folder.id = folder.id & 0x0000ffff;
|
|
err = og_computer_folder_update(dbi, &folder);
|
|
} else {
|
|
err = og_room_folder_update(dbi, &folder);
|
|
}
|
|
og_dbi_close(dbi);
|
|
|
|
return err;
|
|
}
|
|
|
|
static int og_cmd_post_folder_add(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
const char *key;
|
|
json_t *value;
|
|
struct og_folder folder = {};
|
|
struct og_dbi *dbi;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "center")) {
|
|
params->flags |= OG_REST_PARAM_CENTER;
|
|
err = og_json_parse_uint(value, &folder.center);
|
|
} else if (!strcmp(key, "room")) {
|
|
params->flags |= OG_REST_PARAM_ROOM;
|
|
err = og_json_parse_uint(value, &folder.room);
|
|
} else if (!strcmp(key, "name")) {
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
err = og_json_parse_string_copy(value,
|
|
folder.name,
|
|
sizeof(folder.name));
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_NAME))
|
|
return -1;
|
|
if (og_msg_params_validate(params, OG_REST_PARAM_ROOM | OG_REST_PARAM_CENTER))
|
|
return -1;
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ROOM) && !og_msg_params_validate(params, OG_REST_PARAM_CENTER))
|
|
return -1;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
if (params->flags & OG_REST_PARAM_ROOM)
|
|
err = add_computer_folder(dbi, &folder);
|
|
else if (params->flags & OG_REST_PARAM_CENTER)
|
|
err = add_room_folder(dbi, &folder);
|
|
else
|
|
err = -1;
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
return err;
|
|
}
|
|
|
|
static int og_delete_computer_folder(struct og_dbi *dbi, uint32_t folder_id)
|
|
{
|
|
const char *msglog;
|
|
dbi_result result;
|
|
|
|
folder_id = folder_id & 0x0000ffff;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"DELETE FROM gruposordenadores "
|
|
"WHERE idgrupo=%u",
|
|
folder_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to delete computer-group from database "
|
|
"(%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
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);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"DELETE FROM ordenadores "
|
|
"WHERE grupoid=%u",
|
|
folder_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to delete computers from database "
|
|
"(%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_delete_room_folder(struct og_dbi *dbi, uint32_t folder_id)
|
|
{
|
|
const char *msglog;
|
|
dbi_result result;
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"DELETE FROM grupos "
|
|
"WHERE idgrupo=%u",
|
|
folder_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to delete room-group from database "
|
|
"(%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
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);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"DELETE FROM aulas "
|
|
"WHERE grupoid=%u",
|
|
folder_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to delete rooms from database "
|
|
"(%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_folder_delete(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
struct og_dbi *dbi;
|
|
uint32_t folder_id;
|
|
const char *key;
|
|
json_t *value;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, &folder_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;
|
|
}
|
|
|
|
if (folder_id & 0x00010000) {
|
|
err = og_delete_computer_folder(dbi, folder_id);
|
|
} else {
|
|
err = og_delete_room_folder(dbi, folder_id);
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
return err;
|
|
}
|
|
|
|
static int og_cmd_post_client_add(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
const char *room_name, *computer_name, *computer_ip, *hwaddr;
|
|
struct og_computer computer = {};
|
|
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, "serial_number")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.serial_number,
|
|
sizeof(computer.serial_number));
|
|
} else if (!strcmp(key, "hardware_id")) {
|
|
err = og_json_parse_uint(value, &computer.hardware_id);
|
|
} else if (!strcmp(key, "folder_id")) {
|
|
err = og_json_parse_uint(value, &computer.folder_id);
|
|
if (!err)
|
|
computer.folder_id = computer.folder_id & 0x0000ffff;
|
|
|
|
} else if (!strcmp(key, "netdriver")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.netdriver,
|
|
sizeof(computer.netdriver));
|
|
} else if (!strcmp(key, "maintenance")) {
|
|
err = og_json_parse_bool(value, &computer.maintenance);
|
|
} else if (!strcmp(key, "netiface")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.netiface,
|
|
sizeof(computer.netiface));
|
|
} else if (!strcmp(key, "repo_id")) {
|
|
err = og_json_parse_uint(value, &computer.repo_id);
|
|
} else if (!strcmp(key, "livedir")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.livedir,
|
|
sizeof(computer.livedir));
|
|
} else if (!strcmp(key, "netmask")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.netmask,
|
|
sizeof(computer.netmask));
|
|
} else if (!strcmp(key, "remote")) {
|
|
err = og_json_parse_bool(value, &computer.remote);
|
|
} else if (!strcmp(key, "room")) {
|
|
err = og_json_parse_uint(value, &computer.room);
|
|
} else if (!strcmp(key, "name")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.name,
|
|
sizeof(computer.name));
|
|
} else if (!strcmp(key, "boot")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.boot,
|
|
sizeof(computer.boot));
|
|
} else if (!strcmp(key, "mac")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.mac,
|
|
sizeof(computer.mac));
|
|
} else if (!strcmp(key, "ip")) {
|
|
err = og_json_parse_string_copy(value,
|
|
computer.ip,
|
|
sizeof(computer.ip));
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
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 ip FROM ordenadores WHERE ip='%s'",
|
|
computer.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;
|
|
}
|
|
|
|
if (dbi_result_get_numrows(result) > 0) {
|
|
syslog(LOG_ERR, "client with the same IP already exists: %s\n",
|
|
computer.ip);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT nombreordenador, ip, nombreaula"
|
|
" FROM ordenadores"
|
|
" INNER JOIN aulas on ordenadores.idaula = aulas.idaula"
|
|
" WHERE mac='%s'",
|
|
computer.mac);
|
|
|
|
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_next_row(result)) {
|
|
room_name = dbi_result_get_string(result, "nombreaula");
|
|
computer_name = dbi_result_get_string(result, "nombreordenador");
|
|
computer_ip = dbi_result_get_string(result, "ip");
|
|
hwaddr = dbi_result_get_string(result, "mac");
|
|
syslog(LOG_ERR, "Failed to add client %s because %s (%s) in room %s already owns MAC address %s\n",
|
|
computer.ip, computer_ip, computer_name, room_name, hwaddr);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO ordenadores("
|
|
" nombreordenador,"
|
|
" numserie,"
|
|
" ip,"
|
|
" mac,"
|
|
" idaula,"
|
|
" grupoid,"
|
|
" idperfilhard,"
|
|
" idrepositorio,"
|
|
" mascara,"
|
|
" arranque,"
|
|
" netiface,"
|
|
" netdriver,"
|
|
" oglivedir,"
|
|
" inremotepc,"
|
|
" maintenance"
|
|
") VALUES ('%s', '%s', '%s', '%s', %u, %u, %u,"
|
|
" %u, '%s', '%s', '%s', '%s',"
|
|
" '%s', %u, %u)",
|
|
computer.name, computer.serial_number,
|
|
computer.ip, computer.mac, computer.room,
|
|
computer.folder_id, computer.hardware_id,
|
|
computer.repo_id, computer.netmask,
|
|
computer.boot, computer.netiface,
|
|
computer.netdriver, computer.livedir,
|
|
computer.remote, computer.maintenance);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to add client to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
if (og_set_client_mode(dbi, computer.ip, computer.mac, computer.boot)) {
|
|
syslog(LOG_ERR, "failed to set client boot mode (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_client_delete(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
const char *key, *msglog;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
unsigned int i;
|
|
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;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
og_remove_tftpboot_files(dbi, params->ips_array[i]);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"DELETE FROM ordenadores WHERE ip='%s'",
|
|
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);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
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 -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_client_move(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
struct og_computer computer = {};
|
|
const char *key, *msglog;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
unsigned int i;
|
|
json_t *value;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "clients")) {
|
|
err = og_json_parse_clients(value, params);
|
|
} else if (!strcmp(key, "room")) {
|
|
err = og_json_parse_uint(value, &computer.room);
|
|
} else if (!strcmp(key, "folder_id")) {
|
|
err = og_json_parse_uint(value, &computer.folder_id);
|
|
if (!err)
|
|
computer.folder_id = computer.folder_id & 0x0000ffff;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE ordenadores SET "
|
|
"idaula=%u, grupoid=%u WHERE ip='%s'",
|
|
computer.room, computer.folder_id,
|
|
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);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
if (dbi_result_get_numrows_affected(result) < 1) {
|
|
syslog(LOG_ERR, "client move did not modify any row (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_room_info(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_room room = {};
|
|
json_t *value, *root;
|
|
struct og_dbi *dbi;
|
|
uint32_t room_id;
|
|
const char *key;
|
|
int err = 0;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, &room_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;
|
|
}
|
|
|
|
if (og_dbi_get_room_info(dbi, &room, room_id)) {
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
json_object_set_new(root, "id", json_integer(room.id));
|
|
json_object_set_new(root, "name", json_string(room.name));
|
|
json_object_set_new(root, "gateway", json_string(room.gateway));
|
|
json_object_set_new(root, "netmask", json_string(room.netmask));
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int og_cmd_stop(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_STOP, params, NULL);
|
|
}
|
|
|
|
static int og_cmd_hardware(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_GET, OG_CMD_HARDWARE, params, NULL);
|
|
}
|
|
|
|
static int og_cmd_get_hardware(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
const char *key, *msglog, *hw_item, *hw_type;
|
|
json_t *value, *root, *array, *item;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
int err = 0;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "client"))
|
|
err = og_json_parse_clients(value, params);
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
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 hardwares.descripcion AS item, "
|
|
" tipohardwares.descripcion AS type "
|
|
"FROM hardwares "
|
|
"INNER JOIN perfileshard_hardwares "
|
|
" ON hardwares.idhardware = perfileshard_hardwares.idhardware "
|
|
"INNER JOIN ordenadores "
|
|
" ON perfileshard_hardwares.idperfilhard = ordenadores.idperfilhard "
|
|
"INNER JOIN tipohardwares "
|
|
" ON hardwares.idtipohardware = tipohardwares.idtipohardware "
|
|
"WHERE ordenadores.ip = '%s'",
|
|
params->ips_array[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;
|
|
}
|
|
|
|
array = json_array();
|
|
if (!array) {
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
while (dbi_result_next_row(result)) {
|
|
item = json_object();
|
|
if (!item) {
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
|
|
hw_item = dbi_result_get_string(result, "item");
|
|
hw_type = dbi_result_get_string(result, "type");
|
|
|
|
json_object_set_new(item, "type", json_string(hw_type));
|
|
json_object_set_new(item, "description", json_string(hw_item));
|
|
json_array_append_new(array, item);
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
root = json_object();
|
|
if (!root){
|
|
json_decref(array);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(root, "hardware", array);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_software(json_t *element, struct og_msg_params *params)
|
|
{
|
|
json_t *clients, *value;
|
|
const char *key;
|
|
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);
|
|
else if (!strcmp(key, "disk")) {
|
|
err = og_json_parse_string(value, ¶ms->disk);
|
|
params->flags |= OG_REST_PARAM_DISK;
|
|
}
|
|
else if (!strcmp(key, "partition")) {
|
|
err = og_json_parse_string(value, ¶ms->partition);
|
|
params->flags |= OG_REST_PARAM_PARTITION;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_DISK |
|
|
OG_REST_PARAM_PARTITION))
|
|
return -1;
|
|
|
|
clients = json_copy(element);
|
|
json_object_del(clients, "clients");
|
|
|
|
return og_send_request(OG_METHOD_GET, OG_CMD_SOFTWARE, params, clients);
|
|
}
|
|
|
|
static int og_cmd_get_software(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
json_t *value, *software, *root;
|
|
const char *key, *msglog, *name;
|
|
uint64_t disk, partition;
|
|
uint64_t flags = 0;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
int err = 0;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
if (json_typeof(element) != JSON_OBJECT)
|
|
return -1;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "client")) {
|
|
err = og_json_parse_clients(value, params);
|
|
} else if (!strcmp(key, "disk")) {
|
|
err = og_json_parse_uint64(value, &disk);
|
|
flags |= OG_REST_PARAM_DISK;
|
|
} else if (!strcmp(key, "partition")) {
|
|
err = og_json_parse_uint64(value, &partition);
|
|
flags |= OG_REST_PARAM_PARTITION;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR) ||
|
|
!og_flags_validate(flags, OG_REST_PARAM_DISK |
|
|
OG_REST_PARAM_PARTITION))
|
|
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 s.descripcion "
|
|
"FROM softwares s "
|
|
"INNER JOIN perfilessoft_softwares pss "
|
|
"ON s.idsoftware = pss.idsoftware "
|
|
"INNER JOIN ordenadores_particiones op "
|
|
"ON pss.idperfilsoft = op.idperfilsoft "
|
|
"INNER JOIN ordenadores o "
|
|
"ON o.idordenador = op.idordenador "
|
|
"WHERE o.ip='%s' AND "
|
|
" op.numdisk=%lu AND "
|
|
" op.numpar=%lu",
|
|
params->ips_array[0], disk, partition);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
software = json_array();
|
|
if (!software) {
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
while (dbi_result_next_row(result)) {
|
|
name = dbi_result_get_string(result, "descripcion");
|
|
json_array_append_new(software, json_string(name));
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
root = json_object();
|
|
if (!root) {
|
|
json_decref(software);
|
|
return -1;
|
|
}
|
|
json_object_set_new(root, "software", software);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
return 0;
|
|
}
|
|
|
|
static const int og_cmd_get_repositories(char *buffer_reply)
|
|
{
|
|
json_t *root, *repository, *repositories, *ips;
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply,
|
|
};
|
|
LIST_HEAD(repo_list);
|
|
struct og_repo *repo;
|
|
uint32_t i;
|
|
|
|
if (og_repo_list(&repo_list) < 0)
|
|
return -1;
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
repositories = json_array();
|
|
if (!repositories) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(root, "repositories", repositories);
|
|
|
|
list_for_each_entry(repo, &repo_list, list) {
|
|
repository = json_object();
|
|
if (!repository)
|
|
goto err_out;
|
|
|
|
ips = json_array();
|
|
if (!ips) {
|
|
json_decref(repository);
|
|
goto err_out;
|
|
}
|
|
|
|
for (i = 0; i < repo->num_ips; i++)
|
|
json_array_append_new(ips, json_string(inet_ntoa(repo->addr[i])));
|
|
|
|
json_object_set_new(repository, "id", json_integer(repo->id));
|
|
json_object_set_new(repository, "addr", ips);
|
|
json_object_set_new(repository, "name", json_string(repo->name));
|
|
json_array_append_new(repositories, repository);
|
|
}
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII))
|
|
goto err_out;
|
|
|
|
og_repo_free_list(&repo_list);
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
|
|
err_out:
|
|
og_repo_free_list(&repo_list);
|
|
json_decref(root);
|
|
|
|
return -1;
|
|
}
|
|
|
|
#define OG_IMAGE_TYPE_MAXLEN 4
|
|
|
|
static json_t *og_json_disk_alloc()
|
|
{
|
|
const char *dir = ogconfig.repo.dir;
|
|
struct statvfs buffer;
|
|
json_t *disk_json;
|
|
int ret;
|
|
|
|
ret = statvfs(dir, &buffer);
|
|
if (ret)
|
|
return NULL;
|
|
|
|
disk_json = json_object();
|
|
if (!disk_json)
|
|
return NULL;
|
|
|
|
json_object_set_new(disk_json, "total",
|
|
json_integer(buffer.f_blocks * buffer.f_frsize));
|
|
json_object_set_new(disk_json, "free",
|
|
json_integer(buffer.f_bfree * buffer.f_frsize));
|
|
|
|
return disk_json;
|
|
}
|
|
|
|
#define OG_PERMS_IRWX (S_IRWXU | S_IRWXG | S_IRWXO)
|
|
#define OG_PERMS_MAXLEN 4
|
|
|
|
static json_t *og_json_image_alloc(struct og_image *image)
|
|
{
|
|
char perms_string[OG_PERMS_MAXLEN];
|
|
json_t *image_json;
|
|
char *modified;
|
|
|
|
image_json = json_object();
|
|
if (!image_json)
|
|
return NULL;
|
|
|
|
snprintf(perms_string, sizeof(perms_string), "%o", image->perms);
|
|
|
|
modified = ctime(&image->lastupdate);
|
|
modified[strlen(modified) - 1] = '\0';
|
|
|
|
json_object_set_new(image_json, "name",
|
|
json_string(image->name));
|
|
json_object_set_new(image_json, "datasize",
|
|
json_integer(image->datasize));
|
|
json_object_set_new(image_json, "size",
|
|
json_integer(image->size));
|
|
json_object_set_new(image_json, "modified",
|
|
json_string(modified));
|
|
json_object_set_new(image_json, "permissions",
|
|
json_string(perms_string));
|
|
json_object_set_new(image_json, "software_id",
|
|
json_integer(image->software_id));
|
|
json_object_set_new(image_json, "type",
|
|
json_integer(image->type));
|
|
json_object_set_new(image_json, "id",
|
|
json_integer(image->id));
|
|
json_object_set_new(image_json, "repo_id",
|
|
json_integer(image->repo_id));
|
|
json_object_set_new(image_json, "description",
|
|
json_string(image->description));
|
|
json_object_set_new(image_json, "checksum",
|
|
json_string(image->checksum));
|
|
|
|
return image_json;
|
|
}
|
|
|
|
static int og_cmd_images(char *buffer_reply)
|
|
{
|
|
json_t *root, *images, *image_json, *disk_json;
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
struct og_image image;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
images = json_array();
|
|
if (!images) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(root, "images", images);
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT i.nombreca, o.nombreordenador, "
|
|
" i.clonator, i.compressor, "
|
|
" i.filesystem, i.datasize, i.size, "
|
|
" i.lastupdate, i.permissions, "
|
|
" i.idperfilsoft, i.tipo, "
|
|
" i.idimagen, i.idrepositorio, "
|
|
" i.descripcion, i.checksum "
|
|
"FROM imagenes i "
|
|
"LEFT JOIN ordenadores o "
|
|
"ON i.idordenador = o.idordenador ");
|
|
|
|
while (dbi_result_next_row(result)) {
|
|
image = (struct og_image){0};
|
|
image.datasize = dbi_result_get_ulonglong(result, "datasize");
|
|
image.size = dbi_result_get_ulonglong(result, "size");
|
|
image.lastupdate = dbi_result_get_ulonglong(result, "lastupdate");
|
|
image.perms = dbi_result_get_uint(result, "permissions");
|
|
image.software_id = dbi_result_get_ulonglong(result, "idperfilsoft");
|
|
image.type = dbi_result_get_ulonglong(result, "tipo");
|
|
image.id = dbi_result_get_ulonglong(result, "idimagen");
|
|
image.repo_id = dbi_result_get_ulonglong(result, "idrepositorio");
|
|
snprintf(image.checksum, sizeof(image.checksum), "%s",
|
|
dbi_result_get_string(result, "checksum"));
|
|
snprintf(image.name, sizeof(image.name), "%s",
|
|
dbi_result_get_string(result, "nombreca"));
|
|
snprintf(image.description, sizeof(image.description), "%s",
|
|
dbi_result_get_string(result, "descripcion"));
|
|
snprintf(image.checksum, sizeof(image.checksum), "%s",
|
|
dbi_result_get_string(result, "checksum"));
|
|
|
|
image_json = og_json_image_alloc(&image);
|
|
if (!image_json) {
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_array_append_new(images, image_json);
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
disk_json = og_json_disk_alloc();
|
|
if (!disk_json) {
|
|
syslog(LOG_ERR, "cannot allocate disk json");
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(root, "disk", disk_json);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int og_json_parse_create_image(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, "disk")) {
|
|
err = og_json_parse_string(value, ¶ms->disk);
|
|
params->flags |= OG_REST_PARAM_DISK;
|
|
} else if (!strcmp(key, "partition")) {
|
|
err = og_json_parse_string(value, ¶ms->partition);
|
|
params->flags |= OG_REST_PARAM_PARTITION;
|
|
} else if (!strcmp(key, "name")) {
|
|
err = og_json_parse_string_copy(value,
|
|
(char *)¶ms->image.name,
|
|
sizeof(params->image.name));
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "repository_id")) {
|
|
err = og_json_parse_uint64(value, ¶ms->image.repo_id);
|
|
params->flags |= OG_REST_PARAM_REPO;
|
|
} else if (!strcmp(key, "clients")) {
|
|
err = og_json_parse_clients(value, params);
|
|
} else if (!strcmp(key, "id")) {
|
|
err = og_json_parse_string(value, ¶ms->id);
|
|
params->flags |= OG_REST_PARAM_ID;
|
|
} else if (!strcmp(key, "code")) {
|
|
err = og_json_parse_string(value, ¶ms->code);
|
|
params->flags |= OG_REST_PARAM_CODE;
|
|
} else if (!strcmp(key, "description")) {
|
|
err = og_json_parse_string_copy(value,
|
|
(char *)¶ms->image.description,
|
|
sizeof(params->image.description));
|
|
} else if (!strcmp(key, "group_id")) {
|
|
err = og_json_parse_uint64(value, ¶ms->image.group_id);
|
|
} else if (!strcmp(key, "center_id")) {
|
|
err = og_json_parse_uint64(value, ¶ms->image.center_id);
|
|
} else if (!strcmp(key, "backup")) {
|
|
err = og_json_parse_bool(value, ¶ms->backup);
|
|
params->flags |= OG_REST_PARAM_BACKUP;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_BACKUP))
|
|
params->backup = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_add_image(json_t *element, struct og_msg_params *params,
|
|
bool update)
|
|
{
|
|
char repository_ip[OG_DB_IP_MAXLEN + 1];
|
|
char new_image_id[OG_DB_INT_MAXLEN + 1];
|
|
struct og_dbi *dbi;
|
|
json_t *body;
|
|
int err = 0;
|
|
bool found;
|
|
|
|
err = og_json_parse_create_image(element, params);
|
|
if (err < 0)
|
|
return err;
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_DISK |
|
|
OG_REST_PARAM_PARTITION |
|
|
OG_REST_PARAM_CODE |
|
|
OG_REST_PARAM_ID |
|
|
OG_REST_PARAM_NAME))
|
|
return -1;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR,
|
|
"cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
found = og_dbi_get_image(dbi, ¶ms->image);
|
|
if (!found) {
|
|
if (update) {
|
|
syslog(LOG_ERR, "cannot update image file `%s', it does not exist\n",
|
|
params->image.name);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_REPO)) {
|
|
syslog(LOG_ERR,
|
|
"missing repo parameter in request (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
err = og_dbi_add_image(dbi, ¶ms->image);
|
|
if (err < 0) {
|
|
og_dbi_close(dbi);
|
|
return err;
|
|
}
|
|
|
|
snprintf(new_image_id, sizeof(new_image_id), "%lu", params->image.id);
|
|
params->id = new_image_id;
|
|
} else {
|
|
syslog(LOG_INFO, "updating existing image `%s'\n", params->image.name);
|
|
snprintf(new_image_id, sizeof(new_image_id), "%lu", params->image.id);
|
|
params->id = new_image_id;
|
|
}
|
|
json_object_set_new(element, "id", json_string(params->id));
|
|
|
|
err = og_dbi_get_repository_ip(dbi, params->image.repo_id,
|
|
params->ips_array[0], repository_ip);
|
|
og_dbi_close(dbi);
|
|
if (err < 0)
|
|
return err;
|
|
|
|
body = json_copy(element);
|
|
json_object_del(body, "clients");
|
|
json_object_set_new(body, "repository", json_string(repository_ip));
|
|
json_object_set_new(body, "backup", json_boolean(params->backup));
|
|
|
|
return og_send_request(OG_METHOD_POST, OG_CMD_IMAGE_CREATE, params,
|
|
body);
|
|
}
|
|
|
|
static int og_cmd_create_image(json_t *element, struct og_msg_params *params)
|
|
{
|
|
return og_cmd_add_image(element, params, false);
|
|
}
|
|
|
|
static int og_cmd_update_image(json_t *element, struct og_msg_params *params)
|
|
{
|
|
return og_cmd_add_image(element, params, true);
|
|
}
|
|
|
|
int og_json_parse_restore_image(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, "disk")) {
|
|
err = og_json_parse_string(value, ¶ms->disk);
|
|
params->flags |= OG_REST_PARAM_DISK;
|
|
} else if (!strcmp(key, "partition")) {
|
|
err = og_json_parse_string(value, ¶ms->partition);
|
|
params->flags |= OG_REST_PARAM_PARTITION;
|
|
} else if (!strcmp(key, "name")) {
|
|
err = og_json_parse_string(value, ¶ms->name);
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "repository_id")) {
|
|
err = og_json_parse_uint64(value, ¶ms->image.repo_id);
|
|
params->flags |= OG_REST_PARAM_REPO;
|
|
} else if (!strcmp(key, "clients")) {
|
|
err = og_json_parse_clients(value, params);
|
|
} else if (!strcmp(key, "type")) {
|
|
err = og_json_parse_string(value, ¶ms->type);
|
|
params->flags |= OG_REST_PARAM_TYPE;
|
|
} else if (!strcmp(key, "profile")) {
|
|
err = og_json_parse_string(value, ¶ms->profile);
|
|
params->flags |= OG_REST_PARAM_PROFILE;
|
|
} else if (!strcmp(key, "id")) {
|
|
err = og_json_parse_string(value, ¶ms->id);
|
|
params->flags |= OG_REST_PARAM_ID;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_restore_image(json_t *element, struct og_msg_params *params)
|
|
{
|
|
char repository_ip[OG_DB_IP_MAXLEN + 1] = {};
|
|
struct og_dbi *dbi;
|
|
json_t *body;
|
|
int err;
|
|
|
|
err = og_json_parse_restore_image(element, params);
|
|
if (err < 0)
|
|
return err;
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_DISK |
|
|
OG_REST_PARAM_PARTITION |
|
|
OG_REST_PARAM_NAME |
|
|
OG_REST_PARAM_REPO |
|
|
OG_REST_PARAM_TYPE |
|
|
OG_REST_PARAM_PROFILE |
|
|
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_get_repository_ip(dbi, params->image.repo_id,
|
|
params->ips_array[0], repository_ip);
|
|
og_dbi_close(dbi);
|
|
if (err < 0)
|
|
return err;
|
|
|
|
body = json_copy(element);
|
|
json_object_del(body, "clients");
|
|
json_object_set_new(body, "repository", json_string(repository_ip));
|
|
|
|
return og_send_request(OG_METHOD_POST, OG_CMD_IMAGE_RESTORE, params,
|
|
body);
|
|
}
|
|
|
|
static int og_delete_image(struct og_dbi *dbi, const uint32_t image_id)
|
|
{
|
|
char filename[PATH_MAX + 1], checksum[PATH_MAX + 1];
|
|
const char *image;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT nombreca FROM imagenes "
|
|
"WHERE idimagen='%u'",
|
|
image_id);
|
|
if (!result) {
|
|
syslog(LOG_ERR, "failed to query database\n");
|
|
return -1;
|
|
}
|
|
if (!dbi_result_next_row(result)) {
|
|
dbi_result_free(result);
|
|
syslog(LOG_ERR, "image \"%u\" does not exist in database\n", image_id);
|
|
return -1;
|
|
}
|
|
|
|
image = dbi_result_get_string(result, "nombreca");
|
|
snprintf(filename, sizeof(filename), "%s/%s.img", ogconfig.repo.dir,
|
|
image);
|
|
snprintf(checksum, sizeof(checksum), "%s/%s.img.full.sum", ogconfig.repo.dir,
|
|
image);
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"DELETE FROM imagenes "
|
|
"WHERE idimagen='%u'",
|
|
image_id);
|
|
if (!result) {
|
|
syslog(LOG_ERR, "failed to query database\n");
|
|
return -1;
|
|
}
|
|
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);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
unlink(filename);
|
|
unlink(checksum);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_delete_image(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, "image")) {
|
|
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_delete_image(dbi, atoi(params->id));
|
|
if (err < 0) {
|
|
og_dbi_close(dbi);
|
|
return err;
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct og_scope_image {
|
|
struct list_head list;
|
|
uint32_t id;
|
|
};
|
|
|
|
static void og_scope_image_list_free(struct list_head *scope_list)
|
|
{
|
|
struct og_scope_image *scope, *next;
|
|
|
|
list_for_each_entry_safe(scope, next, scope_list, list) {
|
|
list_del(&scope->list);
|
|
free(scope);
|
|
}
|
|
}
|
|
|
|
static int og_json_parse_scope_image_list(json_t *element, struct list_head *scope_list)
|
|
{
|
|
struct og_scope_image *scope;
|
|
unsigned int i;
|
|
json_t *k;
|
|
|
|
if (json_typeof(element) != JSON_ARRAY)
|
|
return -1;
|
|
|
|
for (i = 0; i < json_array_size(element); i++) {
|
|
k = json_array_get(element, i);
|
|
if (json_typeof(k) != JSON_INTEGER)
|
|
goto err_out;
|
|
|
|
scope = calloc(1, sizeof(struct og_scope_image));
|
|
if (!scope)
|
|
goto err_out;
|
|
|
|
scope->id = json_integer_value(k);
|
|
|
|
list_add_tail(&scope->list, scope_list);
|
|
}
|
|
|
|
return 0;
|
|
err_out:
|
|
og_scope_image_list_free(scope_list);
|
|
return -1;
|
|
}
|
|
|
|
enum {
|
|
OG_ATTR_IMAGE_ID = (1 << 0),
|
|
OG_ATTR_IMAGE_SCOPE_ID = (1 << 0),
|
|
};
|
|
|
|
static int og_cmd_image_scope_update(json_t *element, struct og_msg_params *params)
|
|
{
|
|
struct og_scope_image *scope;
|
|
LIST_HEAD(scope_list);
|
|
struct og_dbi *dbi;
|
|
const char *msglog;
|
|
uint32_t image_id;
|
|
dbi_result result;
|
|
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, "image")) {
|
|
err = og_json_parse_uint(value, &image_id);
|
|
params->flags |= OG_ATTR_IMAGE_ID;
|
|
} else if (!strcmp(key, "scopes")) {
|
|
err = og_json_parse_scope_image_list(value, &scope_list);
|
|
if (err >= 0 && !list_empty(&scope_list))
|
|
params->flags |= OG_ATTR_IMAGE_SCOPE_ID;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_ATTR_IMAGE_ID |
|
|
OG_ATTR_IMAGE_SCOPE_ID)) {
|
|
og_scope_image_list_free(&scope_list);
|
|
return -1;
|
|
}
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
og_scope_image_list_free(&scope_list);
|
|
return -1;
|
|
}
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"DELETE FROM image_scope WHERE image_id=%d",
|
|
image_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
goto err_out;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
list_for_each_entry(scope, &scope_list, list) {
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO image_scope (image_id, scope_id) "
|
|
"VALUES (%d, %d)", image_id, scope->id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
goto err_out;
|
|
}
|
|
dbi_result_free(result);
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
og_scope_image_list_free(&scope_list);
|
|
|
|
return 0;
|
|
|
|
err_out:
|
|
og_scope_image_list_free(&scope_list);
|
|
og_dbi_close(dbi);
|
|
|
|
return -1;
|
|
}
|
|
|
|
static json_t *og_json_image_scope(struct og_dbi *dbi, uint32_t image_id)
|
|
{
|
|
json_t *scope_image, *scope_array;
|
|
const char *msglog;
|
|
uint32_t scope_id;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT scope_id FROM image_scope WHERE image_id = '%u'", image_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return NULL;
|
|
}
|
|
|
|
scope_image = json_object();
|
|
if (!scope_image) {
|
|
dbi_result_free(result);
|
|
return NULL;
|
|
}
|
|
|
|
json_object_set_new(scope_image, "id", json_integer(image_id));
|
|
|
|
scope_array = json_array();
|
|
if (!scope_array) {
|
|
json_decref(scope_image);
|
|
dbi_result_free(result);
|
|
return NULL;
|
|
}
|
|
|
|
while (dbi_result_next_row(result)) {
|
|
scope_id = dbi_result_get_uint(result, "scope_id");
|
|
json_array_append_new(scope_array, json_integer(scope_id));
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
json_object_set_new(scope_image, "scopes", scope_array);
|
|
|
|
return scope_image;
|
|
}
|
|
|
|
static int og_cmd_image_scope_list(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
json_t *value, *scope_image;
|
|
struct og_dbi *dbi;
|
|
uint32_t image_id;
|
|
const char *key;
|
|
int err = 0;
|
|
|
|
if (json_typeof(element) != JSON_OBJECT)
|
|
return -1;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "image")) {
|
|
err = og_json_parse_uint(value, &image_id);
|
|
params->flags |= OG_ATTR_IMAGE_ID;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_ATTR_IMAGE_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;
|
|
}
|
|
|
|
scope_image = og_json_image_scope(dbi, image_id);
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
if (!scope_image)
|
|
return -1;
|
|
|
|
if (json_dump_callback(scope_image, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(scope_image);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(scope_image);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_dbi_client_cache_get(struct og_dbi *dbi, json_t *clients, const char *ip)
|
|
{
|
|
uint64_t img_size, cache_size = 0, used_cache = 0, free_cache = 0;
|
|
const char *img_name, *msglog, *img_checksum;
|
|
json_t *client_data, *cache_arr, *img_info;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT ordenadores_particiones.tamano, "
|
|
"ordenadores_particiones.used_size, ordenadores_particiones.free_size "
|
|
"FROM ordenadores_particiones JOIN ordenadores "
|
|
"ON ordenadores.idordenador = ordenadores_particiones.idordenador "
|
|
"WHERE ordenadores.ip = '%s' AND codpar = 202", ip);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
|
|
if (dbi_result_next_row(result)) {
|
|
cache_size = dbi_result_get_longlong(result, "tamano") * 1024;
|
|
used_cache = dbi_result_get_longlong(result, "used_size");
|
|
free_cache = dbi_result_get_longlong(result, "free_size");
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT cache.imagename, cache.size, cache.checksum "
|
|
"FROM ordenadores JOIN cache "
|
|
"ON ordenadores.idordenador = cache.clientid "
|
|
"WHERE ordenadores.ip = '%s'", ip);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
|
|
client_data = json_object();
|
|
if (!client_data) {
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
|
|
cache_arr = json_array();
|
|
if (!cache_arr) {
|
|
json_decref(client_data);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
|
|
while (dbi_result_next_row(result)) {
|
|
img_name = dbi_result_get_string(result, "imagename");
|
|
img_size = dbi_result_get_ulonglong(result, "size");
|
|
img_checksum = dbi_result_get_string(result, "checksum");
|
|
|
|
img_info = json_object();
|
|
if (!img_info) {
|
|
json_decref(client_data);
|
|
json_decref(cache_arr);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(img_info, "name", json_string(img_name));
|
|
json_object_set_new(img_info, "size", json_integer(img_size));
|
|
json_object_set_new(img_info, "checksum", json_string(img_checksum));
|
|
json_array_append_new(cache_arr, img_info);
|
|
}
|
|
|
|
json_object_set_new(client_data, "ip", json_string(ip));
|
|
json_object_set_new(client_data, "cache_size", json_integer(cache_size));
|
|
json_object_set_new(client_data, "used_cache", json_integer(used_cache));
|
|
json_object_set_new(client_data, "free_cache", json_integer(free_cache));
|
|
json_object_set_new(client_data, "images", cache_arr);
|
|
json_array_append_new(clients, client_data);
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_cache_list(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
json_t *value, *root, *clients;
|
|
struct og_dbi *dbi;
|
|
const char *key;
|
|
int err = 0, i;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
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);
|
|
else
|
|
err = -1;
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
clients = json_array();
|
|
if (!clients)
|
|
return -1;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
json_decref(clients);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
if (og_dbi_client_cache_get(dbi, clients, params->ips_array[i]) < 0) {
|
|
json_decref(clients);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
root = json_object();
|
|
if (!root) {
|
|
json_decref(clients);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(root, "clients", clients);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_dbi_client_efi_get(struct og_dbi *dbi, json_t *clients, const char *ip)
|
|
{
|
|
json_t *client_data, *boot_entry, *boot_entry_arr;
|
|
const char *msglog, *entry_name, *entry_description;
|
|
bool entry_active;
|
|
int entry_order;
|
|
dbi_result result;
|
|
|
|
client_data = json_object();
|
|
if (!client_data)
|
|
return -1;
|
|
|
|
json_object_set_new(client_data, "ip", json_string(ip));
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT boot_entries.name, boot_entries.active, "
|
|
"boot_entries.description, boot_entries.entry_order "
|
|
"FROM boot_entries JOIN ordenadores "
|
|
"ON ordenadores.idordenador = boot_entries.client_id "
|
|
"WHERE ordenadores.ip = '%s' "
|
|
"ORDER BY "
|
|
" CASE "
|
|
" WHEN boot_entries.entry_order >= 0 THEN 0 ELSE 1 "
|
|
" END ASC, "
|
|
" boot_entries.entry_order ASC", ip);
|
|
|
|
if (!result) {
|
|
json_decref(client_data);
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
return -1;
|
|
}
|
|
|
|
boot_entry_arr = json_array();
|
|
if (!boot_entry_arr) {
|
|
json_decref(client_data);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
|
|
while (dbi_result_next_row(result)) {
|
|
entry_name = dbi_result_get_string(result, "name");
|
|
entry_active = dbi_result_get_int(result, "active") != 0;
|
|
entry_description = dbi_result_get_string(result, "description");
|
|
entry_order = dbi_result_get_int(result, "entry_order");
|
|
|
|
boot_entry = json_object();
|
|
if (!boot_entry) {
|
|
json_decref(client_data);
|
|
json_decref(boot_entry_arr);
|
|
dbi_result_free(result);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(boot_entry, "name", json_string(entry_name));
|
|
json_object_set_new(boot_entry, "active", json_boolean(entry_active));
|
|
json_object_set_new(boot_entry, "description", json_string(entry_description));
|
|
if (entry_order >= 0)
|
|
json_object_set_new(boot_entry, "order", json_integer(entry_order));
|
|
json_array_append_new(boot_entry_arr, boot_entry);
|
|
}
|
|
json_object_set_new(client_data, "entries", boot_entry_arr);
|
|
json_array_append_new(clients, client_data);
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_efi_list(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
json_t *value, *root, *clients;
|
|
struct og_dbi *dbi;
|
|
const char *key;
|
|
int err = 0, i;
|
|
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
|
|
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);
|
|
else
|
|
err = -1;
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
clients = json_array();
|
|
if (!clients)
|
|
return -1;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
json_decref(clients);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
if (og_dbi_client_efi_get(dbi, clients, params->ips_array[i]) < 0) {
|
|
json_decref(clients);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
root = json_object();
|
|
if (!root) {
|
|
json_decref(clients);
|
|
return -1;
|
|
}
|
|
|
|
json_object_set_new(root, "clients", clients);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_cache_delete(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
json_t *value, *body, *image_arr = NULL;
|
|
const char *key;
|
|
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);
|
|
} else if (!strcmp(key, "images")) {
|
|
if (json_typeof(value) != JSON_ARRAY) {
|
|
err = -1;
|
|
}
|
|
image_arr = value;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
if (!image_arr)
|
|
return -1;
|
|
|
|
body = json_copy(element);
|
|
json_object_del(body, "clients");
|
|
|
|
return og_send_request(OG_METHOD_POST, OG_CMD_CACHE_DELETE, params, body);
|
|
}
|
|
|
|
static int og_cmd_cache_fetch(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
char repository_ip[OG_DB_IP_MAXLEN + 1] = {};
|
|
json_t *value, *body;
|
|
struct og_dbi *dbi;
|
|
|
|
const char *key;
|
|
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);
|
|
} else if (!strcmp(key, "image")) {
|
|
err = og_json_parse_string(value, ¶ms->name);
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "repository_id")) {
|
|
err = og_json_parse_uint64(value, ¶ms->image.repo_id);
|
|
params->flags |= OG_REST_PARAM_REPO;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_NAME |
|
|
OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_REPO))
|
|
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_get_repository_ip(dbi, params->image.repo_id,
|
|
params->ips_array[0], repository_ip);
|
|
og_dbi_close(dbi);
|
|
if (err < 0)
|
|
return err;
|
|
|
|
body = json_copy(element);
|
|
json_object_del(body, "clients");
|
|
json_object_set_new(body, "repository", json_string(repository_ip));
|
|
|
|
return og_send_request(OG_METHOD_POST, OG_CMD_CACHE_FETCH, params, body);
|
|
}
|
|
|
|
static int og_cmd_setup(json_t *element, struct og_msg_params *params)
|
|
{
|
|
json_t *value, *clients;
|
|
const char *key;
|
|
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);
|
|
} else if (!strcmp(key, "type")) {
|
|
err = og_json_parse_string(value, ¶ms->type);
|
|
params->flags |= OG_REST_PARAM_TYPE;
|
|
} else if (!strcmp(key, "disk")) {
|
|
err = og_json_parse_string(value, ¶ms->disk);
|
|
params->flags |= OG_REST_PARAM_DISK;
|
|
} else if (!strcmp(key, "cache")) {
|
|
err = og_json_parse_string(value, ¶ms->cache);
|
|
params->flags |= OG_REST_PARAM_CACHE;
|
|
} else if (!strcmp(key, "cache_size")) {
|
|
err = og_json_parse_string(value, ¶ms->cache_size);
|
|
params->flags |= OG_REST_PARAM_CACHE_SIZE;
|
|
} else if (!strcmp(key, "partition_setup")) {
|
|
err = og_json_parse_partition_setup(value, params);
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_TYPE |
|
|
OG_REST_PARAM_DISK |
|
|
OG_REST_PARAM_CACHE |
|
|
OG_REST_PARAM_CACHE_SIZE |
|
|
OG_REST_PARAM_PART_0 |
|
|
OG_REST_PARAM_PART_1 |
|
|
OG_REST_PARAM_PART_2 |
|
|
OG_REST_PARAM_PART_3))
|
|
return -1;
|
|
|
|
clients = json_copy(element);
|
|
json_object_del(clients, "clients");
|
|
|
|
return og_send_request(OG_METHOD_POST, OG_CMD_SETUP, params, clients);
|
|
}
|
|
|
|
static int og_cmd_scope_get(json_t *element, struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
json_t *root, *array;
|
|
struct og_dbi *dbi;
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
array = json_array();
|
|
if (!array) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
json_object_set_new(root, "scope", array);
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
if (og_dbi_scope_get(dbi, array)) {
|
|
og_dbi_close(dbi);
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define OG_LIVE_JSON_FILE_PATH "/opt/opengnsys/etc/ogliveinfo.json"
|
|
|
|
static int og_cmd_oglive_list(char *buffer_reply)
|
|
{
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
json_error_t json_err;
|
|
json_t *root;
|
|
|
|
root = json_load_file(OG_LIVE_JSON_FILE_PATH, 0, &json_err);
|
|
if (!root) {
|
|
syslog(LOG_ERR, "malformed json line %d: %s\n",
|
|
json_err.line, json_err.text);
|
|
return -1;
|
|
}
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_center_add(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
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, "name")) {
|
|
err = og_json_parse_string(value, ¶ms->name);
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "comment")) {
|
|
err = og_json_parse_string(value, ¶ms->comment);
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_NAME))
|
|
return -1;
|
|
if (!params->comment)
|
|
params->comment = "";
|
|
|
|
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 nombrecentro FROM centros WHERE nombrecentro='%s'",
|
|
params->name);
|
|
|
|
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, "Center with name %s already exists\n",
|
|
params->name);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO centros("
|
|
" nombrecentro,"
|
|
" comentarios,"
|
|
" identidad) VALUES ("
|
|
"'%s', '%s', 1)",
|
|
params->name, params->comment);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to add center to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_center_delete(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
const char *key, *msglog;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
uint32_t image_id;
|
|
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 centros WHERE idcentro=%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;
|
|
}
|
|
|
|
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 -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT idimagen FROM imagenes WHERE idcentro=%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;
|
|
}
|
|
|
|
while (dbi_result_next_row(result)) {
|
|
image_id = dbi_result_get_uint(result, "idimagen");
|
|
|
|
err = og_delete_image(dbi, image_id);
|
|
if (err < 0) {
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return err;
|
|
}
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_repo_list_find_ips(const char *ips_array[], uint32_t ips_array_len,
|
|
uint32_t exclude_repo_id)
|
|
{
|
|
struct og_repo *repo;
|
|
LIST_HEAD(repo_list);
|
|
struct in_addr addr;
|
|
uint32_t i;
|
|
|
|
if (og_repo_list(&repo_list) < 0)
|
|
return -1;
|
|
|
|
for (i = 0; i < ips_array_len; i++) {
|
|
if (!inet_aton(ips_array[i], &addr))
|
|
return -1;
|
|
|
|
list_for_each_entry(repo, &repo_list, list) {
|
|
if (exclude_repo_id && exclude_repo_id == repo->id)
|
|
continue;
|
|
|
|
if (addr.s_addr == repo->addr[i].s_addr) {
|
|
syslog(LOG_ERR, "Cannot add new repository, IP %s is already in used by repository '%s'\n",
|
|
ips_array[i], repo->name);
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
og_repo_free_list(&repo_list);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_repository_update(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
char name[OG_DB_REPO_NAME_MAXLEN];
|
|
const char *key, *msglog;
|
|
unsigned int repo_id;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
int err = 0, i;
|
|
json_t *value;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, &repo_id);
|
|
params->flags |= OG_REST_PARAM_ID;
|
|
} else if (!strcmp(key, "name")) {
|
|
err = og_json_parse_string_copy(value, name,
|
|
sizeof(name));
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "addr")) {
|
|
err = og_json_parse_clients(value, params);
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ID |
|
|
OG_REST_PARAM_NAME |
|
|
OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
if (og_repo_list_find_ips(params->ips_array, params->ips_array_len, repo_id)) {
|
|
syslog(LOG_ERR, "Repository IP already in use, cannot define overlapping\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,
|
|
"DELETE FROM repositorios WHERE alias=%u;",
|
|
repo_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to update repository in database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE repositorios "
|
|
"SET ip='%s' WHERE idrepositorio=%u;",
|
|
params->ips_array[0], repo_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR,
|
|
"failed to add repository to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
for (i = 1; i < params->ips_array_len; i++) {
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO repositorios("
|
|
"nombrerepositorio, ip, idcentro, grupoid, alias) VALUES "
|
|
"('%s', '%s', 1, 0, %u);",
|
|
name, params->ips_array[i], repo_id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR,
|
|
"failed to add repository to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_repository_add(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
char name[OG_DB_REPO_NAME_MAXLEN];
|
|
const char *key, *msglog;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
int err = 0, i;
|
|
json_t *value;
|
|
uint32_t id;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "name")) {
|
|
err = og_json_parse_string_copy(value, name,
|
|
sizeof(name));
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "addr")) {
|
|
err = og_json_parse_clients(value, params);
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
|
|
OG_REST_PARAM_NAME))
|
|
return -1;
|
|
|
|
if (og_repo_list_find_ips(params->ips_array, params->ips_array_len, 0)) {
|
|
syslog(LOG_ERR, "Repository IP already in use, cannot define overlapping\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,
|
|
"INSERT INTO repositorios("
|
|
"nombrerepositorio, ip, idcentro, grupoid, alias) VALUES "
|
|
"('%s', '%s', 1, 0, NULL);",
|
|
name, params->ips_array[0]);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR,
|
|
"failed to add repository to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
id = dbi_conn_sequence_last(dbi->conn, NULL);
|
|
|
|
for (i = 1; i < params->ips_array_len; i++) {
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO repositorios("
|
|
"nombrerepositorio, ip, idcentro, grupoid, alias) VALUES "
|
|
"('%s', '%s', 1, 0, %u);",
|
|
name, params->ips_array[i], id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR,
|
|
"failed to add repository to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_repository_delete(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
const char *key, *msglog;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
uint32_t repo_id;
|
|
json_t *value;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, &repo_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 repositorios "
|
|
"WHERE idrepositorio=%u OR alias=%u",
|
|
repo_id, repo_id);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to delete repository from database "
|
|
"(%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
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 -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_room_update(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
struct og_room room = {};
|
|
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, "name")) {
|
|
err = og_json_parse_string_copy(value, room.name,
|
|
sizeof(room.name));
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "gateway")) {
|
|
err = og_json_parse_string_copy(value, room.gateway,
|
|
sizeof(room.gateway));
|
|
params->flags |= OG_REST_PARAM_GATEWAY;
|
|
} else if (!strcmp(key, "netmask")) {
|
|
err = og_json_parse_string_copy(value, room.netmask,
|
|
sizeof(room.netmask));
|
|
params->flags |= OG_REST_PARAM_NETMASK;
|
|
} else if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, &room.id);
|
|
params->flags |= OG_REST_PARAM_ROOM;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_ROOM |
|
|
OG_REST_PARAM_NAME |
|
|
OG_REST_PARAM_NETMASK |
|
|
OG_REST_PARAM_GATEWAY))
|
|
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 idaula, idcentro FROM aulas WHERE idaula='%u'",
|
|
room.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_next_row(result)) {
|
|
syslog(LOG_ERR, "could not find a room with that id: %u\n",
|
|
room.id);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
room.center = dbi_result_get_uint(result, "idcentro");
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT nombreaula FROM aulas "
|
|
"WHERE nombreaula='%s' AND idcentro=%d AND idaula<>'%u'",
|
|
room.name, room.center, room.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, "Room with name %s already exists in the "
|
|
"center with id %d\n",
|
|
room.name, room.center);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE aulas"
|
|
" SET nombreaula='%s',"
|
|
" netmask='%s',"
|
|
" router='%s'"
|
|
" WHERE idaula='%u';",
|
|
room.name, room.netmask, room.gateway, room.id);
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to update room in database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_room_add(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
struct og_room room = {};
|
|
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, "name")) {
|
|
err = og_json_parse_string_copy(value, room.name,
|
|
sizeof(room.name));
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
} else if (!strcmp(key, "location")) {
|
|
err = og_json_parse_string_copy(value, room.location,
|
|
sizeof(room.location));
|
|
} else if (!strcmp(key, "gateway")) {
|
|
err = og_json_parse_string_copy(value, room.gateway,
|
|
sizeof(room.gateway));
|
|
} else if (!strcmp(key, "netmask")) {
|
|
err = og_json_parse_string_copy(value, room.netmask,
|
|
sizeof(room.netmask));
|
|
params->flags |= OG_REST_PARAM_NETMASK;
|
|
} else if (!strcmp(key, "ntp")) {
|
|
err = og_json_parse_string_copy(value, room.ntp,
|
|
sizeof(room.ntp));
|
|
} else if (!strcmp(key, "dns")) {
|
|
err = og_json_parse_string_copy(value, room.dns,
|
|
sizeof(room.dns));
|
|
} else if (!strcmp(key, "center")) {
|
|
err = og_json_parse_uint(value, &room.center);
|
|
params->flags |= OG_REST_PARAM_CENTER;
|
|
} else if (!strcmp(key, "folder_id")) {
|
|
err = og_json_parse_uint(value, &room.folder_id);
|
|
} else if (!strcmp(key, "remote")) {
|
|
err = og_json_parse_bool(value, &room.remote);
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_NAME |
|
|
OG_REST_PARAM_NETMASK |
|
|
OG_REST_PARAM_CENTER))
|
|
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 nombreaula FROM aulas "
|
|
"WHERE nombreaula='%s' AND idcentro=%d",
|
|
room.name, room.center);
|
|
|
|
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, "Room with name %s already exists in the "
|
|
"center with id %d\n",
|
|
room.name, room.center);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO aulas("
|
|
" idcentro,"
|
|
" nombreaula,"
|
|
" netmask,"
|
|
" grupoid,"
|
|
" ubicacion,"
|
|
" router,"
|
|
" dns,"
|
|
" ntp,"
|
|
" inremotepc) VALUES ("
|
|
"%d, '%s', '%s', %d, '%s', "
|
|
"'%s', '%s', '%s', %d)",
|
|
room.center, room.name, room.netmask,
|
|
room.folder_id, room.location, room.gateway,
|
|
room.dns, room.ntp, room.remote);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to add room to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_post_room_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 aulas WHERE idaula=%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;
|
|
}
|
|
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 -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_servers(char *buffer_reply)
|
|
{
|
|
json_t *root, *servers, *address;
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply,
|
|
};
|
|
char ipaddr[50] = {};
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
int id, ret;
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
|
|
servers = json_array();
|
|
if (!servers) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT identorno, ipserveradm "
|
|
"FROM entornos");
|
|
|
|
while (dbi_result_next_row(result)) {
|
|
address = json_object();
|
|
id = dbi_result_get_int(result, "identorno");
|
|
snprintf(ipaddr, sizeof(ipaddr), "%s",
|
|
dbi_result_get_string(result, "ipserveradm"));
|
|
|
|
json_object_set_new(address, "id", json_integer(id));
|
|
json_object_set_new(address, "address", json_string(ipaddr));
|
|
|
|
json_array_append_new(servers, address);
|
|
}
|
|
|
|
json_object_set_new(root, "servers", servers);
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
ret = json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII);
|
|
json_decref(root);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int og_cmd_post_server(json_t *element,
|
|
struct og_msg_params *params,
|
|
char *buffer_reply)
|
|
{
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply,
|
|
};
|
|
const char *key, *msglog;
|
|
json_t *value, *root;
|
|
int err = 0, id, ret;
|
|
struct in_addr addr;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "address")) {
|
|
err = og_json_parse_string(value, ¶ms->name);
|
|
params->flags |= OG_REST_PARAM_NAME;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_msg_params_validate(params, OG_REST_PARAM_NAME))
|
|
return -1;
|
|
|
|
if (inet_pton(AF_INET, params->name, &addr) <= 0) {
|
|
syslog(LOG_ERR, "invalid server ip address (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
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 identorno FROM entornos WHERE ipserveradm='%s'",
|
|
params->name);
|
|
|
|
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, "Address %s already exists\n",
|
|
params->name);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
dbi_result_free(result);
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"INSERT INTO entornos("
|
|
" ipserveradm,"
|
|
" protoclonacion) VALUES ("
|
|
"'%s', 'UNICAST')",
|
|
params->name);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to add new ogserver address to database (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
root = json_object();
|
|
if (!root) {
|
|
syslog(LOG_ERR, "Cannot allocate JSON object (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
id = dbi_conn_sequence_last(dbi->conn, NULL);
|
|
json_object_set_new(root, "id", json_integer(id));
|
|
ret = json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII);
|
|
|
|
json_decref(root);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int og_cmd_delete_server(json_t *element,
|
|
struct og_msg_params *params)
|
|
{
|
|
const char *key, *msglog;
|
|
struct og_dbi *dbi;
|
|
dbi_result result;
|
|
json_t *value;
|
|
uint32_t id;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "id")) {
|
|
err = og_json_parse_uint(value, &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 entornos WHERE identorno='%u'",
|
|
id);
|
|
|
|
if (!result) {
|
|
dbi_conn_error(dbi->conn, &msglog);
|
|
syslog(LOG_ERR, "failed to delete server (%s:%d) %s\n",
|
|
__func__, __LINE__, msglog);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
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 -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return 0;
|
|
}
|
|
|
|
static int og_dbi_update_oglive(struct og_dbi *dbi, const char *mac,
|
|
const char * oglive)
|
|
{
|
|
const char *msglog;
|
|
dbi_result result;
|
|
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"UPDATE ordenadores SET oglivedir='%s' "
|
|
"WHERE mac='%s'",
|
|
oglive, mac);
|
|
|
|
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_cmd_oglive_set(json_t *element, struct og_msg_params *params)
|
|
{
|
|
const char legacy_default_oglive_str[] = "ogLive";
|
|
const char *oglive_str, *mac, *mode_str;
|
|
const char *msglog;
|
|
struct og_dbi *dbi;
|
|
uint64_t flags = 0;
|
|
dbi_result result;
|
|
const char *key;
|
|
json_t *value;
|
|
int err = 0;
|
|
int i;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "clients")) {
|
|
err = og_json_parse_clients(value, params);
|
|
} else if (!strcmp(key, "name")) {
|
|
err = og_json_parse_string(value, &oglive_str);
|
|
flags |= OG_REST_PARAM_NAME;
|
|
} else {
|
|
err = -1;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (!og_flags_validate(flags, OG_REST_PARAM_NAME) ||
|
|
!og_msg_params_validate(params, OG_REST_PARAM_ADDR))
|
|
return -1;
|
|
|
|
if (!strcmp(oglive_str, "default"))
|
|
oglive_str = legacy_default_oglive_str;
|
|
|
|
dbi = og_dbi_open(&ogconfig.db);
|
|
if (!dbi) {
|
|
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < params->ips_array_len; i++) {
|
|
result = dbi_conn_queryf(dbi->conn,
|
|
"SELECT mac, arranque FROM ordenadores "
|
|
"WHERE ip = '%s'", 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);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
if (!dbi_result_next_row(result)) {
|
|
syslog(LOG_ERR, "could not find client IP: %s (%s:%d)\n",
|
|
params->ips_array[i], __func__, __LINE__);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
mode_str = dbi_result_get_string(result, "arranque");
|
|
mac = dbi_result_get_string(result, "mac");
|
|
|
|
err = og_dbi_update_oglive(dbi, mac, oglive_str);
|
|
if (err < 0) {
|
|
syslog(LOG_ERR, "failed to change db oglive (%s:%d)\n",
|
|
__func__, __LINE__);
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
err = og_set_client_mode(dbi, params->ips_array[i], mac, mode_str);
|
|
if (err < 0) {
|
|
dbi_result_free(result);
|
|
og_dbi_close(dbi);
|
|
return -1;
|
|
}
|
|
|
|
dbi_result_free(result);
|
|
}
|
|
|
|
og_dbi_close(dbi);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_cmd_get_server_stats(char *buffer_reply)
|
|
{
|
|
json_t *root, *time_obj, *memory, *swap;
|
|
struct og_buffer og_buffer = {
|
|
.data = buffer_reply
|
|
};
|
|
struct sysinfo stats;
|
|
time_t now;
|
|
|
|
sysinfo(&stats);
|
|
|
|
root = json_object();
|
|
if (!root)
|
|
return -1;
|
|
time_obj = json_object();
|
|
if (!time_obj) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
memory = json_object();
|
|
if (!memory) {
|
|
json_decref(root);
|
|
json_decref(time_obj);
|
|
return -1;
|
|
}
|
|
swap = json_object();
|
|
if (!swap) {
|
|
json_decref(root);
|
|
json_decref(time_obj);
|
|
json_decref(memory);
|
|
return -1;
|
|
}
|
|
|
|
now = time(NULL);
|
|
json_object_set_new(time_obj, "now", json_integer(now));
|
|
json_object_set_new(time_obj, "boot", json_integer(stats.uptime));
|
|
json_object_set_new(time_obj, "start", json_integer(now - start_time));
|
|
json_object_set_new(root, "time", time_obj);
|
|
|
|
json_object_set_new(memory, "size", json_integer(stats.totalram));
|
|
json_object_set_new(memory, "free", json_integer(stats.freeram));
|
|
json_object_set_new(root, "memory", memory);
|
|
|
|
json_object_set_new(swap, "size", json_integer(stats.totalswap));
|
|
json_object_set_new(swap, "free", json_integer(stats.freeswap));
|
|
json_object_set_new(root, "swap", swap);
|
|
|
|
if (json_dump_callback(root, og_json_dump_clients, &og_buffer, JSON_ENSURE_ASCII)) {
|
|
json_decref(root);
|
|
return -1;
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int og_client_method_not_found(struct og_client *cli)
|
|
{
|
|
/* To meet RFC 7231, this function MUST generate an Allow header field
|
|
* containing the correct methods. For example: "Allow: POST\r\n"
|
|
*/
|
|
char buf[] = "HTTP/1.1 405 Method Not Allowed\r\n"
|
|
"Content-Length: 0\r\n\r\n";
|
|
|
|
send(og_client_socket(cli), buf, strlen(buf), 0);
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int og_client_bad_request(struct og_client *cli)
|
|
{
|
|
char buf[] = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n";
|
|
|
|
send(og_client_socket(cli), buf, strlen(buf), 0);
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int og_client_not_found(struct og_client *cli)
|
|
{
|
|
char buf[] = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
|
|
|
|
send(og_client_socket(cli), buf, strlen(buf), 0);
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int og_client_not_authorized(struct og_client *cli)
|
|
{
|
|
char buf[] = "HTTP/1.1 401 Unauthorized\r\n"
|
|
"WWW-Authenticate: Basic\r\n"
|
|
"Content-Length: 0\r\n\r\n";
|
|
|
|
send(og_client_socket(cli), buf, strlen(buf), 0);
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int og_server_internal_error(struct og_client *cli)
|
|
{
|
|
char buf[] = "HTTP/1.1 500 Internal Server Error\r\n"
|
|
"Content-Length: 0\r\n\r\n";
|
|
|
|
send(og_client_socket(cli), buf, strlen(buf), 0);
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int og_client_ok(struct og_client *cli, char *buf_reply)
|
|
{
|
|
char buf[OG_MSG_RESPONSE_MAXLEN] = {};
|
|
int len;
|
|
|
|
len = snprintf(buf, sizeof(buf),
|
|
"HTTP/1.1 200 OK\r\nContent-Length: %ld\r\n\r\n%s",
|
|
strlen(buf_reply), buf_reply);
|
|
if (len >= (int)sizeof(buf)) {
|
|
syslog(LOG_ERR, "HTTP response to %s:%hu is too large\n",
|
|
inet_ntoa(cli->addr.sin_addr),
|
|
ntohs(cli->addr.sin_port));
|
|
return og_server_internal_error(cli);
|
|
}
|
|
|
|
send(og_client_socket(cli), buf, strlen(buf), 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const char *og_method_str[] = {
|
|
[OG_METHOD_GET] = "GET",
|
|
[OG_METHOD_POST] = "POST",
|
|
[OG_METHOD_DELETE] = "DELETE",
|
|
[OG_METHOD_NO_HTTP] = "NOHTTP",
|
|
};
|
|
|
|
static const char *og_method(enum og_rest_method method)
|
|
{
|
|
if (method > OG_METHOD_NO_HTTP)
|
|
return "UNKNOWN";
|
|
|
|
return og_method_str[method];
|
|
}
|
|
|
|
struct {
|
|
const char *uri;
|
|
} og_uri_handler[] = {
|
|
[OG_URI_UNKNOWN] = { "unknown", },
|
|
[OG_URI_CLIENTS] = { "clients", },
|
|
[OG_URI_CLIENT_REPO] = { "client/repo", },
|
|
[OG_URI_CLIENT_SETUP] = { "client/setup", },
|
|
[OG_URI_CLIENT_SERVER] = { "client/server", },
|
|
[OG_URI_CLIENT_INFO] = { "client/info", },
|
|
[OG_URI_CLIENT_ADD] = { "client/add", },
|
|
[OG_URI_CLIENT_UPDATE] = { "client/update", },
|
|
[OG_URI_CLIENT_DELETE] = { "client/delete", },
|
|
[OG_URI_CLIENT_MOVE] = { "client/move", },
|
|
[OG_URI_WOL] = { "wol", },
|
|
[OG_URI_SHELL_RUN] = { "shell/run", },
|
|
[OG_URI_SHELL_OUTPUT] = { "shell/output", },
|
|
[OG_URI_SHELL_LIST] = { "shell/list", },
|
|
[OG_URI_SESSION] = { "session", },
|
|
[OG_URI_SCOPES] = { "scopes", },
|
|
[OG_URI_POWEROFF] = { "poweroff", },
|
|
[OG_URI_REBOOT] = { "reboot", },
|
|
[OG_URI_BOOT_MODE] = { "mode", },
|
|
[OG_URI_STOP] = { "stop", },
|
|
[OG_URI_REFRESH] = { "refresh", },
|
|
[OG_URI_HARDWARE] = { "hardware", },
|
|
[OG_URI_SOFTWARE] = { "software", },
|
|
[OG_URI_REPO] = { "repositories", },
|
|
[OG_URI_REPO_ADD] = { "repository/add", },
|
|
[OG_URI_REPO_UPDATE] = { "repository/update", },
|
|
[OG_URI_REPO_DELETE] = { "repository/delete", },
|
|
[OG_URI_IMAGES] = { "images", },
|
|
[OG_URI_IMAGE_CREATE] = { "image/create" },
|
|
[OG_URI_IMAGE_UPDATE] = { "image/update" },
|
|
[OG_URI_IMAGE_RESTORE] = { "image/restore", },
|
|
[OG_URI_IMAGE_DELETE] = { "image/delete", },
|
|
[OG_URI_IMAGE_RESTRICT] = { "image/restrict", },
|
|
[OG_URI_CACHE_LIST] = { "cache/list", },
|
|
[OG_URI_CACHE_DELETE] = { "cache/delete", },
|
|
[OG_URI_CACHE_FETCH] = { "cache/fetch", },
|
|
[OG_URI_EFI] = { "efi", },
|
|
[OG_URI_PART_SETUP] = { "setup", },
|
|
[OG_URI_OGLIVE_LIST] = { "oglive/list", },
|
|
[OG_URI_OGLIVE_SET] = { "oglive/set", },
|
|
[OG_URI_CENTER_ADD] = { "center/add", },
|
|
[OG_URI_CENTER_UPDATE] = { "center/update", },
|
|
[OG_URI_CENTER_DELETE] = { "center/delete", },
|
|
[OG_URI_CENTER_INFO] = { "center/info", },
|
|
[OG_URI_ROOM_ADD] = { "room/add", },
|
|
[OG_URI_ROOM_UPDATE] = { "room/update", },
|
|
[OG_URI_ROOM_DELETE] = { "room/delete", },
|
|
[OG_URI_ROOM_INFO] = { "room/info", },
|
|
[OG_URI_SERVER] = { "server", },
|
|
[OG_URI_STATS] = { "stats", },
|
|
[OG_URI_FOLDER_ADD] = { "folder/add", },
|
|
[OG_URI_FOLDER_UPDATE] = { "folder/update", },
|
|
[OG_URI_FOLDER_DELETE] = { "folder/delete", },
|
|
};
|
|
|
|
static const char *og_uri(enum og_rest_uri uri)
|
|
{
|
|
if (uri >= OG_URI_MAX)
|
|
return "unknown";
|
|
|
|
return og_uri_handler[uri].uri;
|
|
}
|
|
|
|
static enum og_rest_uri og_str_to_uri(const char *uri)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < OG_URI_MAX; i++) {
|
|
if (!strncmp(og_uri_handler[i].uri, uri,
|
|
strlen(og_uri_handler[i].uri)))
|
|
return i;
|
|
}
|
|
|
|
return OG_URI_UNKNOWN;
|
|
}
|
|
|
|
static void og_rest_log(const struct og_client *cli, enum og_rest_method method,
|
|
enum og_rest_uri uri, const struct og_msg_params *params)
|
|
{
|
|
char log_buf[(16 * OG_CLIENTS_MAX) + 4096] = {};
|
|
int i, ret;
|
|
|
|
switch (uri) {
|
|
case OG_URI_SCOPES:
|
|
case OG_URI_CLIENTS:
|
|
/* very spammy, do not log these. */
|
|
return;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ret = snprintf(log_buf, sizeof(log_buf), "%s:%hu %s /%s ",
|
|
inet_ntoa(cli->addr.sin_addr), ntohs(cli->addr.sin_port),
|
|
og_method(method), og_uri(uri));
|
|
|
|
if (params->ips_array_len > 0) {
|
|
ret += snprintf(&log_buf[ret], sizeof(log_buf) - ret, "clients=");
|
|
if (ret > sizeof(log_buf))
|
|
return;
|
|
|
|
for (i = 0; i < params->ips_array_len - 1; i++) {
|
|
ret += snprintf(&log_buf[ret], sizeof(log_buf) - ret,
|
|
"%s,", params->ips_array[i]);
|
|
if (ret > sizeof(log_buf))
|
|
return;
|
|
}
|
|
|
|
ret += snprintf(&log_buf[ret], sizeof(log_buf) - ret, "%s", params->ips_array[i]);
|
|
if (ret > sizeof(log_buf))
|
|
return;
|
|
}
|
|
|
|
syslog(LOG_INFO, "%s", log_buf);
|
|
}
|
|
|
|
int og_client_state_process_payload_rest(struct og_client *cli)
|
|
{
|
|
char buf_reply[OG_MSG_RESPONSE_MAXLEN] = {};
|
|
struct og_msg_params params = {};
|
|
enum og_rest_method method;
|
|
const char *cmd, *body;
|
|
json_error_t json_err;
|
|
enum og_rest_uri uri;
|
|
json_t *root = NULL;
|
|
int err = 0;
|
|
|
|
if (!strncmp(cli->buf, "GET", strlen("GET"))) {
|
|
method = OG_METHOD_GET;
|
|
cmd = cli->buf + strlen("GET") + 2;
|
|
} else if (!strncmp(cli->buf, "POST", strlen("POST"))) {
|
|
method = OG_METHOD_POST;
|
|
cmd = cli->buf + strlen("POST") + 2;
|
|
} else if (!strncmp(cli->buf, "DELETE", strlen("DELETE"))) {
|
|
method = OG_METHOD_DELETE;
|
|
cmd = cli->buf + strlen("DELETE") + 2;
|
|
} else
|
|
return og_client_method_not_found(cli);
|
|
|
|
body = strstr(cli->buf, "\r\n\r\n") + 4;
|
|
|
|
if (strcmp(cli->auth_token, ogconfig.rest.api_token)) {
|
|
syslog(LOG_ERR, "wrong Authentication key\n");
|
|
return og_client_not_authorized(cli);
|
|
}
|
|
|
|
if (cli->content_length) {
|
|
root = json_loads(body, 0, &json_err);
|
|
if (!root) {
|
|
syslog(LOG_ERR, "malformed json line %d: %s\n",
|
|
json_err.line, json_err.text);
|
|
return og_client_not_found(cli);
|
|
}
|
|
}
|
|
|
|
uri = og_str_to_uri(cmd);
|
|
|
|
if (!strncmp(cmd, "clients", strlen("clients"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
switch (method) {
|
|
case OG_METHOD_GET:
|
|
err = og_cmd_get_clients(root, ¶ms, buf_reply);
|
|
break;
|
|
default:
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
} else if (!strncmp(cmd, "client/repo", strlen("client/repo"))) {
|
|
switch (method) {
|
|
case OG_METHOD_POST:
|
|
if (!root) {
|
|
syslog(LOG_ERR, "client post repo command with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_client_repo(root, ¶ms, buf_reply);
|
|
break;
|
|
default:
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
} else if (!strncmp(cmd, "client/setup",
|
|
strlen("client/setup"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command client partitions with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_get_client_setup(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "client/info",
|
|
strlen("client/info"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command client info with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_get_client_info(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "client/add", strlen("client/add"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command client info with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_post_client_add(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "client/update", strlen("client/update"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command client info with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_post_client_update(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "client/delete", strlen("client/delete"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command client delete with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_post_client_delete(root, ¶ms);
|
|
} else if (!strncmp(cmd, "client/move", strlen("client/move"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command client move with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_post_client_move(root, ¶ms);
|
|
} else if (!strncmp(cmd, "folder/add", strlen("folder/add"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command folder add with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_post_folder_add(root, ¶ms);
|
|
|
|
} else if (!strncmp(cmd, "folder/update", strlen("folder/update"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command folder update with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_post_folder_update(root, ¶ms);
|
|
|
|
} else if (!strncmp(cmd, "folder/delete", strlen("folder/delete"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command folder delete with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_post_folder_delete(root, ¶ms);
|
|
|
|
} else if (!strncmp(cmd, "wol", strlen("wol"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command wol with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_wol(root, ¶ms);
|
|
} else if (!strncmp(cmd, "shell/run", strlen("shell/run"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command run with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_run_post(root, ¶ms);
|
|
} else if (!strncmp(cmd, "shell/output", strlen("shell/output"))) {
|
|
if (method != OG_METHOD_POST && method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command output with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_run_get(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "shell/list", strlen("shell/list"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_shell_list(buf_reply);
|
|
} else if (!strncmp(cmd, "session", strlen("session"))) {
|
|
if (method != OG_METHOD_POST && method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command session with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (method == OG_METHOD_POST)
|
|
err = og_cmd_session(root, ¶ms);
|
|
else
|
|
err = og_cmd_get_session(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "scopes", strlen("scopes"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (root) {
|
|
syslog(LOG_ERR, "command scopes with payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_scope_get(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "poweroff", strlen("poweroff"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command poweroff with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_poweroff(root, ¶ms);
|
|
} else if (!strncmp(cmd, "reboot", strlen("reboot"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command reboot with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_reboot(root, ¶ms);
|
|
} else if (!strncmp(cmd, "mode", strlen("mode"))) {
|
|
if (method != OG_METHOD_GET && method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (method == OG_METHOD_POST && !root) {
|
|
syslog(LOG_ERR, "command mode with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (method == OG_METHOD_GET)
|
|
err = og_cmd_get_modes(root, ¶ms, buf_reply);
|
|
else if (method == OG_METHOD_POST)
|
|
err = og_cmd_post_modes(root, ¶ms);
|
|
} else if (!strncmp(cmd, "stop", strlen("stop"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command stop with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_stop(root, ¶ms);
|
|
} else if (!strncmp(cmd, "refresh", strlen("refresh"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command refresh with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_refresh(root, ¶ms);
|
|
} else if (!strncmp(cmd, "hardware", strlen("hardware"))) {
|
|
if (method != OG_METHOD_GET && method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command hardware with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (method == OG_METHOD_GET)
|
|
err = og_cmd_get_hardware(root, ¶ms, buf_reply);
|
|
else if (method == OG_METHOD_POST)
|
|
err = og_cmd_hardware(root, ¶ms);
|
|
} else if (!strncmp(cmd, "software", strlen("software"))) {
|
|
if (method != OG_METHOD_POST && method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR, "command software with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (method == OG_METHOD_POST)
|
|
err = og_cmd_software(root, ¶ms);
|
|
else
|
|
err = og_cmd_get_software(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "repositories", strlen("repositories"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (root) {
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_get_repositories(buf_reply);
|
|
} else if (!strncmp(cmd, "repository/add", strlen("repository/add"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command repository add with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_repository_add(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "repository/update", strlen("repository/update"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command repository add with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_repository_update(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "repository/delete",
|
|
strlen("repository/delete"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command repository delete with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_repository_delete(root, ¶ms);
|
|
} else if (!strncmp(cmd, "images", strlen("images"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (root) {
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_images(buf_reply);
|
|
} else if (!strncmp(cmd, "image/create", strlen("image/create"))) {
|
|
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_create_image(root, ¶ms);
|
|
} else if (!strncmp(cmd, "image/update", strlen("image/update"))) {
|
|
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_update_image(root, ¶ms);
|
|
} else if (!strncmp(cmd, "image/restore", strlen("image/restore"))) {
|
|
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_restore_image(root, ¶ms);
|
|
} else if (!strncmp(cmd, "image/delete", strlen("image/delete"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command image delete with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_delete_image(root, ¶ms);
|
|
} else if (!strncmp(cmd, "image/restrict", strlen("image/restrict"))) {
|
|
if (!root) {
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
switch (method) {
|
|
case OG_METHOD_GET:
|
|
err = og_cmd_image_scope_list(root, ¶ms, buf_reply);
|
|
break;
|
|
case OG_METHOD_POST:
|
|
err = og_cmd_image_scope_update(root, ¶ms);
|
|
break;
|
|
default:
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
} else if (!strncmp(cmd, "cache/list", strlen("cache/list"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command cache list with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_cache_list(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "efi", strlen("efi"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command efi with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_efi_list(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "cache/delete", strlen("cache/delete"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command cache list with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_cache_delete(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "cache/fetch", strlen("cache/fetch"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command cache fetch with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_cache_fetch(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "setup", strlen("setup"))) {
|
|
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_setup(root, ¶ms);
|
|
} else if (!strncmp(cmd, "oglive/list",
|
|
strlen("oglive/list"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_oglive_list(buf_reply);
|
|
} else if (!strncmp(cmd, "oglive/set", strlen("oglive/set"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command oglive set with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_oglive_set(root, ¶ms);
|
|
} else if (!strncmp(cmd, "center/add",
|
|
strlen("center/add"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_post_center_add(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "center/delete", strlen("center/delete"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command center delete with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_center_delete(root, ¶ms);
|
|
} else if (!strncmp(cmd, "center/info",
|
|
strlen("center/info"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command client info with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_get_center_info(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "center/update", strlen("center/update"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command center update with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_center_update(root, ¶ms);
|
|
} else if (!strncmp(cmd, "room/add",
|
|
strlen("room/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 with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_room_add(root, ¶ms);
|
|
} else if (!strncmp(cmd, "room/update",
|
|
strlen("room/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_post_room_update(root, ¶ms);
|
|
} else if (!strncmp(cmd, "room/delete", strlen("room/delete"))) {
|
|
if (method != OG_METHOD_POST) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command room delete with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_room_delete(root, ¶ms);
|
|
} else if (!strncmp(cmd, "room/info", strlen("room/info"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
if (!root) {
|
|
syslog(LOG_ERR,
|
|
"command room info with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_get_room_info(root, ¶ms, buf_reply);
|
|
} else if (!strncmp(cmd, "server", strlen("server"))) {
|
|
switch (method) {
|
|
case OG_METHOD_GET:
|
|
err = og_cmd_get_servers(buf_reply);
|
|
break;
|
|
case OG_METHOD_DELETE:
|
|
err = og_cmd_delete_server(root, ¶ms);
|
|
break;
|
|
case OG_METHOD_POST:
|
|
if (!root) {
|
|
syslog(LOG_ERR, "address add command with no payload\n");
|
|
err = og_client_bad_request(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
err = og_cmd_post_server(root, ¶ms, buf_reply);
|
|
break;
|
|
default:
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
} else if (!strncmp(cmd, "stats", strlen("stats"))) {
|
|
if (method != OG_METHOD_GET) {
|
|
err = og_client_method_not_found(cli);
|
|
goto err_process_rest_payload;
|
|
}
|
|
|
|
err = og_cmd_get_server_stats(buf_reply);
|
|
} else {
|
|
syslog(LOG_ERR, "unknown command: %.32s ...\n", cmd);
|
|
err = og_client_not_found(cli);
|
|
}
|
|
|
|
og_rest_log(cli, method, uri, ¶ms);
|
|
|
|
json_decref(root);
|
|
|
|
if (err < 0)
|
|
return og_client_bad_request(cli);
|
|
|
|
return og_client_ok(cli, buf_reply);
|
|
|
|
err_process_rest_payload:
|
|
syslog(LOG_ERR, "%s:%hu %.32s ...\n",
|
|
inet_ntoa(cli->addr.sin_addr),
|
|
ntohs(cli->addr.sin_port), cli->buf);
|
|
json_decref(root);
|
|
|
|
return err;
|
|
}
|