fort_SOURCES += extension.h extension.c
fort_SOURCES += file.h file.c
fort_SOURCES += init.h init.c
-fort_SOURCES += json_parser.c json_parser.h
+fort_SOURCES += json_util.c json_util.h
fort_SOURCES += line_file.h line_file.c
fort_SOURCES += log.h log.c
fort_SOURCES += nid.h nid.c
#include "common.h"
#include "config.h"
#include "file.h"
+#include "json_util.h"
#include "log.h"
#include "rrdp.h"
#include "thread_var.h"
* FIXME test max recursion
*/
+#define TAGNAME_BN "basename"
+#define TAGNAME_DIRECT "direct-download"
+#define TAGNAME_ERROR "latest-result"
+#define TAGNAME_TSATTEMPT "attempt-timestamp"
+#define TAGNAME_SUCCESS "successful-download"
+#define TAGNAME_TSSUCCESS "success-timestamp"
+#define TAGNAME_FILE "is-file"
+#define TAGNAME_CHILDREN "children"
+
/*
* Have we ever attempted to download this directly?
* Otherwise we actually downloaded a descendant.
time_t startup_time; /* When we started the last validation */
};
-
static struct cache_node *
add_child(struct cache_node *parent, char const *basename)
{
return 0;
}
-static int
-json_tt_value(struct json_t const *json, time_t *result)
-{
- char const *str;
- struct tm tm;
- time_t tmp;
-
- if (json == NULL)
- return -1;
- str = json_string_value(json);
- if (str == NULL)
- return -1;
- str = strptime(str, "%FT%T%z", &tm);
- if (str == NULL || *str != 0)
- return -1;
- tmp = mktime(&tm);
- if (tmp == ((time_t) -1))
- return -1;
-
- *result = tmp;
- return 0;
-}
-
static struct cache_node *
json2node(json_t *json, struct cache_node *parent)
{
struct cache_node *node, *child;
char const *string;
+ bool boolean;
json_t *jchild;
size_t c;
+ int error;
if (json == NULL)
return NULL;
node = pzalloc(sizeof(struct cache_node));
- string = json_string_value(json_object_get(json, "basename"));
- if (string == NULL) {
- pr_op_warn("Tag 'basename' of a metadata.json's download node cannot be parsed as a string; skipping.");
+ error = json_get_str(json, TAGNAME_BN, &string);
+ if (error) {
+ if (error > 0)
+ pr_op_err("Node is missing the '" TAGNAME_BN "' tag.");
goto cancel;
}
node->basename = pstrdup(string);
- jchild = json_object_get(json, "flags");
- if (!json_is_integer(jchild)) {
- pr_op_warn("Tag 'flags' of metadata.json's download node '%s' cannot be parsed as an integer; skipping.",
- node->basename);
+ if (json_get_bool(json, TAGNAME_DIRECT, &boolean) < 0)
goto cancel;
- }
- node->flags = json_integer_value(jchild);
+ if (boolean) {
+ node->flags |= CNF_DIRECT;
+ if (json_get_int(json, TAGNAME_ERROR, &node->error) < 0)
+ goto cancel;
- if (json_tt_value(json_object_get(json, "ts_success"), &node->ts_success)) {
- pr_op_warn("Tag 'success' of metadata.json's download node '%s' cannot be parsed as a date; skipping.",
- node->basename);
- goto cancel;
- }
+ if (json_get_ts(json, TAGNAME_TSATTEMPT, &node->ts_attempt) < 0)
+ goto cancel;
- if (json_tt_value(json_object_get(json, "ts_attempt"), &node->ts_attempt)) {
- pr_op_warn("Tag 'attempt' of metadata.json's download node '%s' cannot be parsed as a date; skipping.",
- node->basename);
- goto cancel;
+ if (json_get_bool(json, TAGNAME_SUCCESS, &boolean) < 0)
+ goto cancel;
+ if (boolean) {
+ node->flags |= CNF_SUCCESS;
+ if (json_get_ts(json, TAGNAME_TSSUCCESS, &node->ts_success) < 0)
+ goto cancel;
+ }
}
- jchild = json_object_get(json, "error");
- if (!json_is_integer(jchild)) {
- pr_op_warn("Tag 'error' of metadata.json's download node '%s' cannot be parsed as an integer; skipping.",
- node->basename);
+ if (json_get_bool(json, TAGNAME_FILE, &boolean) < 0)
goto cancel;
- }
- node->error = json_integer_value(jchild);
+ if (boolean)
+ node->flags |= CNF_FILE;
- jchild = json_object_get(json, "children");
- if (jchild != NULL && !json_is_array(jchild)) {
- pr_op_warn("Tag 'children' of metadata.json's download node '%s' cannot be parsed as an array; skipping.",
- node->basename);
+ if (json_get_array(json, "children", &jchild) < 0)
goto cancel;
- }
-
for (c = 0; c < json_array_size(jchild); c++) {
child = json2node(json_array_get(jchild, c), node);
- if (child == NULL)
- goto cancel;
- HASH_ADD_KEYPTR(hh, node->children, child->basename,
- strlen(child->basename), child);
+ if (child != NULL)
+ HASH_ADD_KEYPTR(hh, node->children, child->basename,
+ strlen(child->basename), child);
}
node->parent = parent;
json_decref(root);
}
-static int
-tt2json(time_t tt, json_t **result)
-{
- char str[32];
- struct tm tmbuffer, *tm;
-
- memset(&tmbuffer, 0, sizeof(tmbuffer));
- tm = localtime_r(&tt, &tmbuffer);
- if (tm == NULL)
- return errno;
- if (strftime(str, sizeof(str) - 1, "%FT%T%z", tm) == 0)
- return ENOSPC;
-
- *result = json_string(str);
- return 0;
-}
-
static json_t *
node2json(struct cache_node *node)
{
- json_t *json, *date, *children, *jchild;
+ json_t *json, *children, *jchild;
struct cache_node *child, *tmp;
- int error;
+ int cnf;
json = json_object();
if (json == NULL) {
return NULL;
}
- if (json_object_set_new(json, "basename", json_string(node->basename))) {
- pr_op_err("Cannot convert string '%s' to json; unknown cause.",
- node->basename);
+ if (json_add_str(json, TAGNAME_BN, node->basename))
goto cancel;
- }
- if (json_object_set_new(json, "flags", json_integer(node->flags))) {
- pr_op_err("Cannot convert int '%d' to json; unknown cause.",
- node->flags);
- goto cancel;
- }
-
- error = tt2json(node->ts_success, &date);
- if (error) {
- pr_op_err("Cannot convert %s's success timestamp to json: %s",
- node->basename, strerror(error));
- goto cancel;
- }
- if (json_object_set_new(json, "ts_success", date)) {
- pr_op_err("Cannot convert %s's success timestamp to json; unknown cause.",
- node->basename);
- goto cancel;
- }
-
- error = tt2json(node->ts_attempt, &date);
- if (error) {
- pr_op_err("Cannot convert %s's attempt timestamp to json: %s",
- node->basename, strerror(error));
- goto cancel;
- }
- if (json_object_set_new(json, "ts_attempt", date)) {
- pr_op_err("Cannot convert %s's attempt timestamp to json; unknown cause.",
- node->basename);
- goto cancel;
+ cnf = node->flags & CNF_DIRECT;
+ if (cnf) {
+ if (json_add_bool(json, TAGNAME_DIRECT, cnf))
+ goto cancel;
+ if (json_add_int(json, TAGNAME_ERROR, node->error))
+ goto cancel;
+ if (json_add_date(json, TAGNAME_TSATTEMPT, node->ts_attempt))
+ goto cancel;
+ cnf = node->flags & CNF_SUCCESS;
+ if (cnf) {
+ if (json_add_bool(json, TAGNAME_SUCCESS, cnf))
+ goto cancel;
+ if (json_add_date(json, TAGNAME_TSSUCCESS, node->ts_success))
+ goto cancel;
+ }
}
-
- if (json_object_set_new(json, "error", json_integer(node->error))) {
- pr_op_err("Cannot convert int '%d' to json; unknown cause.",
- node->error);
+ cnf = node->flags & CNF_FILE;
+ if (cnf && json_add_bool(json, TAGNAME_FILE, cnf))
goto cancel;
- }
if (node->children != NULL) {
children = json_array();
return NULL;
}
- if (json_object_set_new(json, "children", children)) {
+ if (json_object_set_new(json, TAGNAME_CHILDREN, children)) {
pr_op_err("Cannot push children array into json node; unknown cause.");
goto cancel;
}
#include <assert.h>
#include "common.h"
-#include "json_parser.h"
+#include "json_util.h"
#include "log.h"
#include "data_structure/common.h"
int error;
id = __INID_MAX;
- error = json_get_string(json, "name", &name);
- if (error)
+ error = json_get_str(json, "name", &name);
+ if (error < 0)
return error;
+ if (error > 0)
+ return pr_op_err("Incidence is missing the 'name' tag.");
error = name2id(name, &id);
if (error)
return error;
- error = json_get_string(json, "action", &action_str);
- if (error)
+ error = json_get_str(json, "action", &action_str);
+ if (error < 0)
return error;
+ if (error > 0)
+ return pr_op_err("Incidence '%s' is missing the 'action' tag.",
+ name);
if (strcmp("ignore", action_str) == 0)
action = INAC_IGNORE;
+++ /dev/null
-#include "json_parser.h"
-
-#include <errno.h>
-#include "log.h"
-
-/*
- * Try to get member @name from @parent as a char const *. On success, set
- * @result with the members value.
- *
- * Returns 0 on success, -ENOENT if the @name doesn't exists, -EINVAL if the
- * member isn't a JSON integer.
- */
-int
-json_get_string(json_t *parent, char const *name, char const **result)
-{
- json_t *child;
-
- child = json_object_get(parent, name);
- if (child == NULL) {
- *result = NULL;
- return -ENOENT;
- }
-
- if (!json_is_string(child)) {
- *result = NULL;
- return pr_op_err("The '%s' element is not a JSON string.", name);
- }
-
- *result = json_string_value(child);
- return 0;
-}
-
-/*
- * Try to get member @name from @parent as a json_int_t. On success, set
- * @result with the members value.
- *
- * Returns 0 on success, -ENOENT if the @name doesn't exists, -EINVAL if the
- * member isn't a JSON integer.
- */
-int
-json_get_int(json_t *parent, char const *name, json_int_t *result)
-{
- json_t *child;
-
- child = json_object_get(parent, name);
- if (child == NULL)
- return -ENOENT;
-
- if (!json_is_integer(child))
- return pr_op_err("The '%s' element is not a JSON integer.", name);
-
- *result = json_integer_value(child);
- return 0;
-}
-
-json_t *
-json_get_array(json_t *parent, char const *name)
-{
- json_t *child;
-
- child = json_object_get(parent, name);
- if (child == NULL)
- return NULL;
-
- if (!json_is_array(child)) {
- pr_op_err("The '%s' element is not a JSON array.", name);
- return NULL;
- }
-
- return child;
-}
-
-json_t *
-json_get_object(json_t *parent, char const *name)
-{
- json_t *child;
-
- child = json_object_get(parent, name);
- if (child == NULL)
- return NULL;
-
- if (!json_is_object(child)) {
- pr_op_err("The '%s' element is not a JSON object.", name);
- return NULL;
- }
-
- return child;
-}
-
-/*
- * Any unknown members should be treated as errors, RFC8416 3.1:
- * "JSON members that are not defined here MUST NOT be used in SLURM
- * files. An RP MUST consider any deviations from the specifications to
- * be errors."
- */
-bool
-json_valid_members_count(json_t *object, size_t expected_size)
-{
- return json_object_size(object) == expected_size;
-}
+++ /dev/null
-#ifndef SRC_JSON_PARSER_H_
-#define SRC_JSON_PARSER_H_
-
-#include <jansson.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-int json_get_string(json_t *, char const *, char const **);
-int json_get_int(json_t *, char const *, json_int_t *);
-json_t *json_get_array(json_t *, char const *);
-json_t *json_get_object(json_t *, char const *);
-
-bool json_valid_members_count(json_t *, size_t);
-
-#endif /* SRC_JSON_PARSER_H_ */
--- /dev/null
+#include "json_util.h"
+
+#include <errno.h>
+#include <limits.h>
+#include "log.h"
+
+int
+json_get_str(json_t *parent, char const *name, char const **result)
+{
+ json_t *child;
+
+ *result = NULL;
+
+ child = json_object_get(parent, name);
+ if (child == NULL)
+ return ENOENT;
+
+ if (!json_is_string(child))
+ return pr_op_err("Tag '%s' is not a JSON string.", name);
+
+ *result = json_string_value(child);
+ return 0;
+}
+
+int
+json_get_bool(json_t *parent, char const *name, bool *result)
+{
+ json_t *child;
+
+ *result = false;
+
+ child = json_object_get(parent, name);
+ if (child == NULL)
+ return ENOENT;
+
+ if (!json_is_boolean(child))
+ return pr_op_err("Tag '%s' is not a JSON boolean.", name);
+
+ *result = json_boolean_value(child);
+ return 0;
+}
+
+static int
+json_get_int_t(json_t *parent, char const *name, json_int_t *result)
+{
+ json_t *child;
+
+ *result = 0;
+
+ child = json_object_get(parent, name);
+ if (child == NULL)
+ return ENOENT;
+
+ if (!json_is_integer(child))
+ return pr_op_err("Tag '%s' is not a JSON integer.", name);
+
+ *result = json_integer_value(child);
+ return 0;
+}
+
+int
+json_get_int(json_t *parent, char const *name, int *result)
+{
+ json_int_t json_int;
+ int error;
+
+ *result = 0;
+
+ error = json_get_int_t(parent, name, &json_int);
+ if (error)
+ return error;
+ if (json_int < INT_MIN || INT_MAX < json_int)
+ return pr_op_err("Tag '%s' (%" JSON_INTEGER_FORMAT
+ ") is out of range [%d, %d].",
+ name, json_int, INT_MIN, INT_MAX);
+
+ *result = json_int;
+ return 0;
+}
+
+int
+json_get_u32(json_t *parent, char const *name, uint32_t *result)
+{
+ json_int_t json_int;
+ int error;
+
+ *result = 0;
+
+ error = json_get_int_t(parent, name, &json_int);
+ if (error)
+ return error;
+ if (json_int < 0 || UINT32_MAX < json_int)
+ return pr_op_err("Tag '%s' (%" JSON_INTEGER_FORMAT
+ ") is out of range [0, %u].",
+ name, json_int, UINT32_MAX);
+
+ *result = json_int;
+ return 0;
+}
+
+int
+json_get_ts(json_t *parent, char const *name, time_t *result)
+{
+ char const *str, *consumed;
+ struct tm tm;
+ time_t time;
+ int error;
+
+ *result = 0;
+
+ error = json_get_str(parent, name, &str);
+ if (error)
+ return error;
+
+ consumed = strptime(str, "%FT%T%z", &tm);
+ if (consumed == NULL || (*consumed) != 0)
+ return pr_op_err("String '%s' does not appear to be a timestamp.",
+ str);
+ time = mktime(&tm);
+ if (time == ((time_t) -1)) {
+ error = errno;
+ return pr_op_err("String '%s' does not appear to be a timestamp: %s",
+ str, strerror(error));
+ }
+
+ *result = time;
+ return 0;
+}
+
+int
+json_get_array(json_t *parent, char const *name, json_t **array)
+{
+ json_t *child;
+
+ *array = NULL;
+
+ child = json_object_get(parent, name);
+ if (child == NULL)
+ return ENOENT;
+
+ if (!json_is_array(child))
+ return pr_op_err("Tag '%s' is not a JSON array.", name);
+
+ *array = child;
+ return 0;
+}
+
+int
+json_get_object(json_t *parent, char const *name, json_t **obj)
+{
+ json_t *child;
+
+ *obj = NULL;
+
+ child = json_object_get(parent, name);
+ if (child == NULL)
+ return ENOENT;
+
+ if (!json_is_object(child))
+ return pr_op_err("Tag '%s' is not a JSON object.", name);
+
+ *obj = child;
+ return 0;
+}
+
+/*
+ * Any unknown members should be treated as errors, RFC8416 3.1:
+ * "JSON members that are not defined here MUST NOT be used in SLURM
+ * files. An RP MUST consider any deviations from the specifications to
+ * be errors."
+ */
+bool
+json_valid_members_count(json_t *object, size_t expected_size)
+{
+ return json_object_size(object) == expected_size;
+}
+
+int
+json_add_bool(json_t *parent, char const *name, bool value)
+{
+ if (json_object_set_new(parent, name, json_boolean(value)))
+ return pr_op_err(
+ "Cannot convert %s '%u' to json; unknown cause.",
+ name, value
+ );
+
+ return 0;
+}
+
+int
+json_add_int(json_t *parent, char const *name, int value)
+{
+ if (json_object_set_new(parent, name, json_integer(value)))
+ return pr_op_err(
+ "Cannot convert %s '%d' to json; unknown cause.",
+ name, value
+ );
+
+ return 0;
+}
+
+int
+json_add_str(json_t *parent, char const *name, char const *value)
+{
+ if (json_object_set_new(parent, name, json_string(value)))
+ return pr_op_err(
+ "Cannot convert %s '%s' to json; unknown cause.",
+ name, value
+ );
+
+ return 0;
+}
+
+static int
+tt2json(time_t tt, json_t **result)
+{
+ char str[32];
+ struct tm tmbuffer, *tm;
+
+ memset(&tmbuffer, 0, sizeof(tmbuffer));
+ tm = localtime_r(&tt, &tmbuffer);
+ if (tm == NULL)
+ return errno;
+ if (strftime(str, sizeof(str) - 1, "%FT%T%z", tm) == 0)
+ return ENOSPC;
+
+ *result = json_string(str);
+ return 0;
+}
+
+int
+json_add_date(json_t *parent, char const *name, time_t value)
+{
+ json_t *date = NULL;
+ int error;
+
+ error = tt2json(value, &date);
+ if (error) {
+ pr_op_err("Cannot convert timestamp '%s' to json: %s",
+ name, strerror(error));
+ return error;
+ }
+
+ if (json_object_set_new(parent, name, date))
+ return pr_op_err(
+ "Cannot convert timestamp '%s' to json; unknown cause.",
+ name
+ );
+
+ return 0;
+}
--- /dev/null
+#ifndef SRC_JSON_UTIL_H_
+#define SRC_JSON_UTIL_H_
+
+#include <jansson.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+
+/*
+ * Contract of get functions:
+ *
+ * result = 0: Tag parsed successfully, out param populated.
+ * result > 0: Tag was nonexistent, outbound param reset (0 or NULL), not logged
+ * result < 0: Tag was fatally invalid, outbound param reset, logged
+ */
+
+int json_get_bool(json_t *, char const *, bool *);
+int json_get_int(json_t *, char const *, int *);
+int json_get_u32(json_t *, char const *, uint32_t *);
+int json_get_ts(json_t *, char const *, time_t *);
+int json_get_str(json_t *, char const *, char const **);
+int json_get_array(json_t *, char const *, json_t **);
+int json_get_object(json_t *, char const *, json_t **);
+
+bool json_valid_members_count(json_t *, size_t);
+
+int json_add_bool(json_t *, char const *, bool);
+int json_add_int(json_t *, char const *, int);
+int json_add_str(json_t *, char const *, char const *);
+int json_add_date(json_t *, char const *, time_t);
+
+#endif /* SRC_JSON_UTIL_H_ */
if (type == 0) {
pr_val_err(PRE_RSYNC "%s", cur);
} else {
- pr_val_info(PRE_RSYNC "%s", cur);
+ pr_val_debug(PRE_RSYNC "%s", cur);
}
cur = tmp + 1;
}
#include "crypto/base64.h"
#include "algorithm.h"
#include "alloc.h"
+#include "json_util.h"
#include "log.h"
-#include "json_parser.h"
#include "types/address.h"
#include "types/router_key.h"
#include "slurm/db_slurm.h"
#define ROUTER_PUBLIC_KEY "routerPublicKey"
#define COMMENT "comment"
-#define CHECK_REQUIRED(element, name) \
- if (element == NULL) \
- return pr_op_err("SLURM member '%s' is required", name);
+#define COMPLAIN_REQUIRED(name) pr_op_err("SLURM member '" name "' is required")
static int handle_json(json_t *, struct db_slurm *);
set_asn(json_t *object, bool is_assertion, uint32_t *result, uint8_t *flag,
size_t *members_loaded)
{
- json_int_t int_tmp;
int error;
- int_tmp = 0;
- error = json_get_int(object, ASN, &int_tmp);
- if (error == -ENOENT) {
- if (is_assertion)
- return pr_op_err("ASN is required");
- else
- return 0; /* Optional for filters */
- } else if (error)
+ error = json_get_u32(object, ASN, result);
+ if (error < 0)
return error;
+ if (error > 0)
+ /* Optional for filters */
+ return is_assertion ? pr_op_err("ASN is required") : 0;
- /* An underflow or overflow will be considered here */
- if (int_tmp < 0 || UINT32_MAX < int_tmp)
- return pr_op_err("ASN (%lld) is out of range [0 - %u].", int_tmp,
- UINT32_MAX);
*flag = *flag | SLURM_COM_FLAG_ASN;
- *result = (uint32_t) int_tmp;
(*members_loaded)++;
return 0;
}
static int
set_comment(json_t *object, uint8_t *flag, size_t *members_loaded)
{
- char const *tmp;
+ char const *comment;
int error;
- error = json_get_string(object, COMMENT, &tmp);
- if (error && error == -ENOENT)
- return 0; /* Optional member */
- else if (error)
+ error = json_get_str(object, COMMENT, &comment);
+ if (error < 0)
return error;
+ if (comment == NULL)
+ return 0;
*flag = *flag | SLURM_COM_FLAG_COMMENT;
(*members_loaded)++;
int error;
/* First part: Prefix in string format */
- error = json_get_string(object, PREFIX, &str_prefix);
- if (error && error == -ENOENT) {
- if (is_assertion)
- return pr_op_err("SLURM assertion prefix is required");
- else
- return 0; /* Optional for filters */
- } else if (error)
+ error = json_get_str(object, PREFIX, &str_prefix);
+ if (error < 0)
return error;
+ if (str_prefix == NULL) {
+ return is_assertion
+ ? pr_op_err("SLURM assertion prefix is required")
+ : 0; /* Optional for filters */
+ }
clone = pstrdup(str_prefix);
set_max_prefix_length(json_t *object, bool is_assertion, uint8_t addr_fam,
uint8_t *result, uint8_t *flag, size_t *members_loaded)
{
- json_int_t int_tmp;
+ uint32_t u32;
+ unsigned int max;
int error;
- int_tmp = 0;
- error = json_get_int(object, MAX_PREFIX_LENGTH, &int_tmp);
- if (error == -ENOENT)
- return 0; /* Optional for assertions, unsupported by filters */
-
- if (error && is_assertion)
+ error = json_get_u32(object, MAX_PREFIX_LENGTH, &u32);
+ if (error < 0)
return error;
- /* Unsupported by filters */
+ /* Filters */
if (!is_assertion)
- return pr_op_err("Prefix filter can't have a max prefix length");
+ return (error == 0)
+ ? pr_op_err("Prefix filter can't have a max prefix length")
+ : 0;
- /* An underflow or overflow will be considered here */
- if (int_tmp <= 0 || (addr_fam == AF_INET ? 32 : 128) < int_tmp)
- return pr_op_err("Max prefix length (%lld) is out of range [1 - %d].",
- int_tmp, (addr_fam == AF_INET) ? 32 : 128);
+ /* Assertions */
+ if (error > 0)
+ return 0;
+
+ max = (addr_fam == AF_INET) ? 32 : 128;
+ if (max < u32)
+ return pr_op_err("Max prefix length (%u) is out of range [0, %u].",
+ u32, max);
*flag = *flag | SLURM_PFX_FLAG_MAX_LENGTH;
- *result = (uint8_t) int_tmp;
+ *result = (uint8_t) u32;
(*members_loaded)++;
return 0;
size_t ski_len;
int error;
- error = json_get_string(object, SKI, &str_encoded);
- if (error && error == -ENOENT) {
- if (is_assertion)
- return pr_op_err("SLURM assertion %s is required", SKI);
- else
- return 0; /* Optional for filters */
- } else if (error)
+ error = json_get_str(object, SKI, &str_encoded);
+ if (error < 0)
return error;
+ if (str_encoded == NULL)
+ return is_assertion
+ ? pr_op_err("SLURM assertion %s is required", SKI)
+ : 0; /* Optional for filters */
error = validate_base64url_encoded(str_encoded);
if (error)
size_t spk_len;
int error;
- error = json_get_string(object, ROUTER_PUBLIC_KEY, &str_encoded);
- if (error == -ENOENT && !is_assertion)
- return 0; /* OK for filters */
-
- /* Required by assertions */
- if (error && is_assertion) {
- if (error == -ENOENT)
- return pr_op_err("SLURM assertion %s is required",
- ROUTER_PUBLIC_KEY);
+ error = json_get_str(object, ROUTER_PUBLIC_KEY, &str_encoded);
+ if (error < 0)
return error;
- }
- /* Unsupported by filters */
+ /* Filters */
if (!is_assertion)
- return pr_op_err("BGPsec filter can't have a router public key");
+ return (error == 0)
+ ? pr_op_err("BGPsec filter can't have a router public key")
+ : 0;
+
+ /* Assertions */
+ if (str_encoded == NULL)
+ return pr_op_err("SLURM assertion %s is required",
+ ROUTER_PUBLIC_KEY);
error = validate_base64url_encoded(str_encoded);
if (error)
static int
load_version(json_t *root)
{
- json_int_t version;
+ uint32_t version;
int error;
- version = -1;
- error = json_get_int(root, SLURM_VERSION, &version);
- if (error)
- return (error == -ENOENT) ?
- pr_op_err("SLURM member '"SLURM_VERSION"' is required.") :
- error;
+ error = json_get_u32(root, SLURM_VERSION, &version);
+ if (error < 0)
+ return error;
+ if (error > 0)
+ return COMPLAIN_REQUIRED(SLURM_VERSION);
/* Validate data */
if (version != 1)
- return pr_op_err("'%s' must be 1", SLURM_VERSION);
+ return pr_op_err("'" SLURM_VERSION "' must be 1");
return 0;
}
size_t expected_members;
int error;
- filters = json_get_object(root, VALIDATION_OUTPUT_FILTERS);
- CHECK_REQUIRED(filters, VALIDATION_OUTPUT_FILTERS)
+ error = json_get_object(root, VALIDATION_OUTPUT_FILTERS, &filters);
+ if (error < 0)
+ return error;
+ if (error > 0)
+ return COMPLAIN_REQUIRED(VALIDATION_OUTPUT_FILTERS);
- prefix = json_get_array(filters, PREFIX_FILTERS);
- CHECK_REQUIRED(prefix, PREFIX_FILTERS)
+ error = json_get_array(filters, PREFIX_FILTERS, &prefix);
+ if (error < 0)
+ return error;
+ if (error > 0)
+ return COMPLAIN_REQUIRED(PREFIX_FILTERS);
- bgpsec = json_get_array(filters, BGPSEC_FILTERS);
- CHECK_REQUIRED(bgpsec, BGPSEC_FILTERS)
+ error = json_get_array(filters, BGPSEC_FILTERS, &bgpsec);
+ if (error < 0)
+ return error;
+ if (error > 0)
+ return COMPLAIN_REQUIRED(BGPSEC_FILTERS);
expected_members = 2;
if (!json_valid_members_count(filters, expected_members))
size_t expected_members;
int error;
- assertions = json_get_object(root, LOCALLY_ADDED_ASSERTIONS);
- CHECK_REQUIRED(assertions, LOCALLY_ADDED_ASSERTIONS)
+ error = json_get_object(root, LOCALLY_ADDED_ASSERTIONS, &assertions);
+ if (error < 0)
+ return error;
+ if (error > 0)
+ return COMPLAIN_REQUIRED(LOCALLY_ADDED_ASSERTIONS);
- prefix = json_get_array(assertions, PREFIX_ASSERTIONS);
- CHECK_REQUIRED(prefix, PREFIX_ASSERTIONS)
+ error = json_get_array(assertions, PREFIX_ASSERTIONS, &prefix);
+ if (error < 0)
+ return error;
+ if (error > 0)
+ return COMPLAIN_REQUIRED(PREFIX_ASSERTIONS);
- bgpsec = json_get_array(assertions, BGPSEC_ASSERTIONS);
- CHECK_REQUIRED(bgpsec, BGPSEC_ASSERTIONS)
+ error = json_get_array(assertions, BGPSEC_ASSERTIONS, &bgpsec);
+ if (error < 0)
+ return error;
+ if (error > 0)
+ return COMPLAIN_REQUIRED(BGPSEC_ASSERTIONS);
expected_members = 2;
if (!json_valid_members_count(assertions, expected_members))
#include "alloc.c"
#include "common.c"
#include "file.c"
+#include "json_util.c"
#include "mock.c"
#include "data_structure/path_builder.c"
#include "types/uri.c"
cache->rsync = TNODE("rsync", 0, NOW + 0, NOW + 1, 0,
TNODE("a.b.c", 0, NOW + 2, NOW + 3, 0,
TNODE("d", SUCCESS, NOW + 4, NOW + 5, 0),
- TNODE("e", SUCCESS, NOW + 6, NOW + 7, 0)),
+ TNODE("e", CNF_DIRECT, NOW + 6, NOW + 7, 1)),
TNODE("x.y.z", 0, NOW + 8, NOW + 9, 0,
TNODE("w", SUCCESS, NOW + 0, NOW + 1, 0)));
cache->https = TNODE("https", 0, NOW + 2, NOW + 3, 0,
TNODE("a", 0, NOW + 4, NOW + 5, 0,
- TNODE("b", HTTP_SUCCESS, NOW + 6, NOW + 7, 0),
+ TNODE("b", HTTP_SUCCESS, NOW + 6, NOW + 7, 1),
TNODE("c", HTTP_SUCCESS, NOW + 8, NOW + 9, 0)));
json = build_metadata_json(cache);
/* printf("%s\n", str); */
json_decref(json);
+ /* TODO (test) Time zones are hardcoded to CST */
ck_assert_str_eq(
- "[{\"basename\":\"rsync\",\"flags\":0,\"ts_success\":\"2023-09-05T16:23:30-0600\",\"ts_attempt\":\"2023-09-05T16:23:31-0600\",\"error\":0,\"children\":["
- "{\"basename\":\"a.b.c\",\"flags\":0,\"ts_success\":\"2023-09-05T16:23:32-0600\",\"ts_attempt\":\"2023-09-05T16:23:33-0600\",\"error\":0,\"children\":["
- "{\"basename\":\"d\",\"flags\":3,\"ts_success\":\"2023-09-05T16:23:34-0600\",\"ts_attempt\":\"2023-09-05T16:23:35-0600\",\"error\":0},"
- "{\"basename\":\"e\",\"flags\":3,\"ts_success\":\"2023-09-05T16:23:36-0600\",\"ts_attempt\":\"2023-09-05T16:23:37-0600\",\"error\":0}]},"
- "{\"basename\":\"x.y.z\",\"flags\":0,\"ts_success\":\"2023-09-05T16:23:38-0600\",\"ts_attempt\":\"2023-09-05T16:23:39-0600\",\"error\":0,\"children\":["
- "{\"basename\":\"w\",\"flags\":3,\"ts_success\":\"2023-09-05T16:23:30-0600\",\"ts_attempt\":\"2023-09-05T16:23:31-0600\",\"error\":0}]}]},"
- "{\"basename\":\"https\",\"flags\":0,\"ts_success\":\"2023-09-05T16:23:32-0600\",\"ts_attempt\":\"2023-09-05T16:23:33-0600\",\"error\":0,\"children\":["
- "{\"basename\":\"a\",\"flags\":0,\"ts_success\":\"2023-09-05T16:23:34-0600\",\"ts_attempt\":\"2023-09-05T16:23:35-0600\",\"error\":0,\"children\":["
- "{\"basename\":\"b\",\"flags\":11,\"ts_success\":\"2023-09-05T16:23:36-0600\",\"ts_attempt\":\"2023-09-05T16:23:37-0600\",\"error\":0},"
- "{\"basename\":\"c\",\"flags\":11,\"ts_success\":\"2023-09-05T16:23:38-0600\",\"ts_attempt\":\"2023-09-05T16:23:39-0600\",\"error\":0}]}]}]",
+ "[{\"basename\":\"rsync\",\"children\":["
+ "{\"basename\":\"a.b.c\",\"children\":["
+ "{\"basename\":\"d\",\"direct-download\":true,\"latest-result\":0,\"attempt-timestamp\":\"2023-09-05T16:23:35-0600\",\"successful-download\":true,\"success-timestamp\":\"2023-09-05T16:23:34-0600\"},"
+ "{\"basename\":\"e\",\"direct-download\":true,\"latest-result\":1,\"attempt-timestamp\":\"2023-09-05T16:23:37-0600\"}]},"
+ "{\"basename\":\"x.y.z\",\"children\":["
+ "{\"basename\":\"w\",\"direct-download\":true,\"latest-result\":0,\"attempt-timestamp\":\"2023-09-05T16:23:31-0600\",\"successful-download\":true,\"success-timestamp\":\"2023-09-05T16:23:30-0600\"}]}]},"
+ "{\"basename\":\"https\",\"children\":["
+ "{\"basename\":\"a\",\"children\":["
+ "{\"basename\":\"b\",\"direct-download\":true,\"latest-result\":1,\"attempt-timestamp\":\"2023-09-05T16:23:37-0600\",\"successful-download\":true,\"success-timestamp\":\"2023-09-05T16:23:36-0600\",\"is-file\":true},"
+ "{\"basename\":\"c\",\"direct-download\":true,\"latest-result\":0,\"attempt-timestamp\":\"2023-09-05T16:23:39-0600\",\"successful-download\":true,\"success-timestamp\":\"2023-09-05T16:23:38-0600\",\"is-file\":true}]}]}]",
str);
free(str);
cache_reset(cache);
load_metadata_json(cache);
+ ck_assert_ptr_nonnull(cache->rsync);
+ ck_assert_ptr_nonnull(cache->https);
+
validate_trees(cache->rsync,
- TNODE("rsync", 0, NOW + 0, NOW + 1, 0,
- TNODE("a.b.c", 0, NOW + 2, NOW + 3, 0,
+ TNODE("rsync", 0, 0, 0, 0,
+ TNODE("a.b.c", 0, 0, 0, 0,
TNODE("d", SUCCESS, NOW + 4, NOW + 5, 0),
- TNODE("e", SUCCESS, NOW + 6, NOW + 7, 0)),
- TNODE("x.y.z", 0, NOW + 8, NOW + 9, 0,
+ TNODE("e", CNF_DIRECT, NOW + 6, NOW + 7, 1)),
+ TNODE("x.y.z", 0, 0, 0, 0,
TNODE("w", SUCCESS, NOW + 0, NOW + 1, 0))),
NULL);
validate_trees(cache->https,
- TNODE("https", 0, NOW + 2, NOW + 3, 0,
- TNODE("a", 0, NOW + 4, NOW + 5, 0,
- TNODE("b", HTTP_SUCCESS, NOW + 6, NOW + 7, 0),
+ TNODE("https", 0, 0, 0, 0,
+ TNODE("a", 0, 0, 0, 0,
+ TNODE("b", HTTP_SUCCESS, NOW + 6, NOW + 7, 1),
TNODE("c", HTTP_SUCCESS, NOW + 8, NOW + 9, 0))),
NULL);
#include "alloc.c"
#include "common.c"
#include "file.c"
-#include "json_parser.c"
+#include "json_util.c"
#include "mock.c"
#include "output_printer.c"
#include "types/delta.c"