mirror of https://git.48k.eu/ogserver
239 lines
5.4 KiB
C
239 lines
5.4 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 "json.h"
|
|
#include <stdint.h>
|
|
|
|
int og_json_parse_string(const json_t *element, const char **str)
|
|
{
|
|
if (json_typeof(element) != JSON_STRING)
|
|
return -1;
|
|
|
|
*str = json_string_value(element);
|
|
return 0;
|
|
}
|
|
|
|
int og_json_parse_string_copy(const json_t *element, char *str, size_t size)
|
|
{
|
|
const char *reference_str;
|
|
int err = 0;
|
|
|
|
err = og_json_parse_string(element, &reference_str);
|
|
if (err != 0)
|
|
return err;
|
|
|
|
err = snprintf(str, size, "%s", reference_str);
|
|
if (err >= size)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
int og_json_parse_uint64(const json_t *element, uint64_t *integer)
|
|
{
|
|
if (json_typeof(element) != JSON_INTEGER)
|
|
return -1;
|
|
|
|
*integer = json_integer_value(element);
|
|
return 0;
|
|
}
|
|
|
|
int og_json_parse_uint(const json_t *element, uint32_t *integer)
|
|
{
|
|
if (json_typeof(element) != JSON_INTEGER)
|
|
return -1;
|
|
|
|
*integer = json_integer_value(element);
|
|
return 0;
|
|
}
|
|
|
|
int og_json_parse_bool(const json_t *element, bool *value)
|
|
{
|
|
if (json_typeof(element) == JSON_TRUE)
|
|
*value = true;
|
|
else if (json_typeof(element) == JSON_FALSE)
|
|
*value = false;
|
|
else
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int og_json_parse_scope(json_t *element, struct og_scope *scope,
|
|
const uint64_t required_flags)
|
|
{
|
|
uint64_t flags = 0UL;
|
|
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, &scope->id);
|
|
flags |= OG_PARAM_SCOPE_ID;
|
|
} else if (!strcmp(key, "type")) {
|
|
err = og_json_parse_string(value, &scope->type);
|
|
flags |= OG_PARAM_SCOPE_TYPE;
|
|
} else {
|
|
err = -1;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if (flags != required_flags)
|
|
return -1;
|
|
|
|
return err;
|
|
}
|
|
|
|
int og_json_parse_partition(json_t *element, struct og_partition *part,
|
|
uint64_t required_flags)
|
|
{
|
|
uint64_t flags = 0UL;
|
|
const char *key;
|
|
json_t *value;
|
|
int err = 0;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "partition")) {
|
|
err = og_json_parse_string(value, &part->number);
|
|
flags |= OG_PARAM_PART_NUMBER;
|
|
} else if (!strcmp(key, "code")) {
|
|
err = og_json_parse_string(value, &part->code);
|
|
flags |= OG_PARAM_PART_CODE;
|
|
} else if (!strcmp(key, "filesystem")) {
|
|
err = og_json_parse_string(value, &part->filesystem);
|
|
flags |= OG_PARAM_PART_FILESYSTEM;
|
|
} else if (!strcmp(key, "size")) {
|
|
err = og_json_parse_string(value, &part->size);
|
|
flags |= OG_PARAM_PART_SIZE;
|
|
} else if (!strcmp(key, "format")) {
|
|
err = og_json_parse_string(value, &part->format);
|
|
flags |= OG_PARAM_PART_FORMAT;
|
|
} else if (!strcmp(key, "disk")) {
|
|
err = og_json_parse_string(value, &part->disk);
|
|
flags |= OG_PARAM_PART_DISK;
|
|
} else if (!strcmp(key, "disk_type")) {
|
|
err = og_json_parse_string(value, &part->disk_type);
|
|
flags |= OG_PARAM_PART_DISK_TYPE;
|
|
} else if (!strcmp(key, "os")) {
|
|
err = og_json_parse_string(value, &part->os);
|
|
flags |= OG_PARAM_PART_OS;
|
|
} else if (!strcmp(key, "used_size")) {
|
|
err = og_json_parse_string(value, &part->used_size);
|
|
flags |= OG_PARAM_PART_USED_SIZE;
|
|
}
|
|
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
|
|
if ((flags & required_flags) != required_flags)
|
|
return -1;
|
|
|
|
return err;
|
|
}
|
|
|
|
static int og_json_parse_procedure_cmd(json_t *element, int position,
|
|
struct og_procedure *proc)
|
|
{
|
|
struct og_procedure_step *step;
|
|
uint32_t err = 0;
|
|
const char *key;
|
|
json_t *value;
|
|
|
|
step = &proc->steps[proc->num_steps++];
|
|
step->type = OG_STEP_COMMAND;
|
|
step->position = position;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "command"))
|
|
err = og_json_parse_string(value, &step->cmd.type);
|
|
else if (!strcmp(key, "params"))
|
|
step->cmd.json = value;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
static int og_json_parse_procedure_call(json_t *element, int position,
|
|
struct og_procedure *proc)
|
|
{
|
|
struct og_procedure_step *step;
|
|
uint32_t err = 0;
|
|
const char *key;
|
|
json_t *value;
|
|
|
|
step = &proc->steps[proc->num_steps++];
|
|
step->type = OG_STEP_PROCEDURE;
|
|
step->position = position;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "procedure"))
|
|
err = og_json_parse_uint64(value, &step->procedure.id);
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
static int og_json_parse_task_call(json_t *element, int position,
|
|
struct og_procedure *task)
|
|
{
|
|
struct og_procedure_step *step;
|
|
uint32_t err = 0;
|
|
const char *key;
|
|
json_t *value;
|
|
|
|
step = &task->steps[task->num_steps++];
|
|
step->type = OG_STEP_TASK;
|
|
step->position = position;
|
|
|
|
json_object_foreach(element, key, value) {
|
|
if (!strcmp(key, "task"))
|
|
err = og_json_parse_uint64(value, &step->procedure.id);
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int og_json_parse_procedure(json_t *element, struct og_procedure *proc)
|
|
{
|
|
unsigned int i;
|
|
json_t *item;
|
|
int err = 0;
|
|
|
|
if (json_typeof(element) != JSON_ARRAY)
|
|
return -1;
|
|
|
|
for (i = 0; i < json_array_size(element) && i < OG_PROCEDURE_STEPS_MAX; ++i) {
|
|
item = json_array_get(element, i);
|
|
|
|
if (json_object_get(item, "command"))
|
|
err = og_json_parse_procedure_cmd(item, i, proc);
|
|
else if (json_object_get(item, "procedure"))
|
|
err = og_json_parse_procedure_call(item, i, proc);
|
|
else if (json_object_get(item, "task"))
|
|
err = og_json_parse_task_call(item, i, proc);
|
|
else
|
|
err = -1;
|
|
|
|
if (err)
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|