struct cache_node *node;
size_t urlen;
- // XXX load (and save) seqs
- if (json_get_ulong(root, "next", &tbl->seq.next_id))
+ if (json_get_object(root, tbl->name, &root))
return;
- if (json_get_array(root, tbl->name, &array))
+
+ if (json_get_seq(root, "seq", &tbl->seq)) {
+ // XXX this is grouds to reset the cache...
+ pr_op_warn("Unable to load the 'seq' child for the %s table.",
+ tbl->name);
+ return;
+ }
+ if (json_get_array(root, "nodes", &array)) {
+ pr_op_warn("Unable to load the 'nodes' child for the %s table.",
+ tbl->name);
return;
+ }
json_array_foreach(array, index, child) {
node = json2node(child);
if (!json)
return NULL;
- if (json_add_ulong(json, "next", tbl->seq.next_id))
+ if (json_add_seq(json, "seq", &tbl->seq))
goto fail;
nodes = json_array_new();
seq->free_prefix = free_prefix;
}
+void
+cseq_cleanup(struct cache_sequence *seq)
+{
+ if (seq->free_prefix)
+ free(seq->prefix);
+}
+
char *
cseq_next(struct cache_sequence *seq)
{
};
void cseq_init(struct cache_sequence *, char *, bool);
+void cseq_cleanup(struct cache_sequence *);
char *cseq_next(struct cache_sequence *);
/*
#include <limits.h>
#include <time.h>
+#include "alloc.h"
#include "common.h"
#include "log.h"
return 0;
}
+int
+json_get_seq(json_t *parent, char const *name, struct cache_sequence *seq)
+{
+ json_t *child;
+ char const *pfx;
+ int error;
+
+ error = json_get_object(parent, name, &child);
+ if (error)
+ return error;
+
+ error = json_get_str(child, "pfx", &pfx);
+ if (error < 0)
+ return error;
+ if (error > 0)
+ return pr_op_err(
+ "The '%s' JSON object is missing mandatory child 'pfx'.",
+ name
+ );
+ error = json_get_ulong(child, "next", &seq->next_id);
+ if (error < 0)
+ return error;
+
+ seq->prefix = pstrdup(pfx);
+ seq->pathlen = strlen(pfx) + 4;
+ seq->free_prefix = true;
+ 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
return 0;
}
+int
+json_add_seq(json_t *parent, char const *name,
+ struct cache_sequence const *value)
+{
+ json_t *seq;
+
+ seq = json_obj_new();
+ if (seq == NULL)
+ return -EINVAL;
+
+ if (json_add_ulong(seq, "next", value->next_id))
+ goto fail;
+ if (json_add_str(seq, "pfx", value->prefix))
+ goto fail;
+
+ if (json_object_set_new(parent, name, seq))
+ return pr_op_err(
+ "Cannot convert sequence [%s, %lu] to json; unknown cause.",
+ value->prefix, value->next_id
+ );
+
+ return 0;
+
+fail: json_decref(seq);
+ return -EINVAL;
+}
+
#define OOM_PFX " Likely out of memory (but there is no contract)."
json_t *
#include <unistd.h>
#include "asn1/asn1c/INTEGER.h"
+#include "file.h"
/*
* Contract of get functions:
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 **);
+int json_get_seq(json_t *, char const *, struct cache_sequence *);
bool json_valid_members_count(json_t *, size_t);
int json_add_bigint(json_t *, char const *, INTEGER_t *);
int json_add_str(json_t *, char const *, char const *);
int json_add_ts(json_t *, char const *, time_t);
+int json_add_seq(json_t *, char const *, struct cache_sequence const *);
json_t *json_obj_new(void);
json_t *json_array_new(void);
if (state->files)
if (json_object_add(json, "files", files2json(state)))
goto fail;
- if (json_add_ulong(json, "next", state->seq.next_id))
+ if (json_add_seq(json, "seq", &state->seq))
goto fail;
if (!STAILQ_EMPTY(&state->delta_hashes))
if (json_object_add(json, TAGNAME_DELTAS, dh2json(state)))
}
}
+static int
+json2dhs(json_t *json, struct rrdp_state *state)
+{
+ json_t *jdeltas;
+ size_t d, dn;
+ struct rrdp_hash *hash;
+ int error;
+
+ STAILQ_INIT(&state->delta_hashes);
+
+ error = json_get_array(json, TAGNAME_DELTAS, &jdeltas);
+ if (error)
+ return (error > 0) ? 0 : error;
+
+ dn = json_array_size(jdeltas);
+ if (dn == 0)
+ return 0;
+ if (dn > config_get_rrdp_delta_threshold())
+ dn = config_get_rrdp_delta_threshold();
+
+ for (d = 0; d < dn; d++) {
+ error = json2dh(json_array_get(jdeltas, d), &hash);
+ if (error) {
+ clear_delta_hashes(state);
+ return error;
+ }
+ STAILQ_INSERT_TAIL(&state->delta_hashes, hash, hook);
+ }
+
+ return 0;
+}
+
int
rrdp_json2state(json_t *json, struct rrdp_state **result)
{
struct rrdp_state *state;
char const *str;
- json_t *jdeltas;
- size_t d, dn;
- struct rrdp_hash *hash;
int error;
state = pzalloc(sizeof(struct rrdp_state));
- STAILQ_INIT(&state->delta_hashes);
error = json_get_str(json, TAGNAME_SESSION, &str);
if (error < 0)
goto revert_serial;
}
- error = json_get_array(json, TAGNAME_DELTAS, &jdeltas);
- if (error) {
- if (error > 0)
- goto success;
+ error = json_get_seq(json, "seq", &state->seq);
+ if (error)
goto revert_serial;
- }
- dn = json_array_size(jdeltas);
- if (dn == 0)
- goto success;
- if (dn > config_get_rrdp_delta_threshold())
- dn = config_get_rrdp_delta_threshold();
-
- for (d = 0; d < dn; d++) {
- error = json2dh(json_array_get(jdeltas, d), &hash);
- if (error)
- goto revert_deltas;
- STAILQ_INSERT_TAIL(&state->delta_hashes, hash, hook);
- }
+ error = json2dhs(json, state);
+ if (error)
+ goto revert_seq;
-success:
*result = state;
return 0;
-revert_deltas:
- clear_delta_hashes(state);
+revert_seq:
+ cseq_cleanup(&state->seq);
revert_serial:
BN_free(state->session.serial.num);
free(state->session.serial.str);
map_cleanup(&file->map);
free(file);
}
- if (state->seq.free_prefix)
- free(state->seq.prefix);
+ cseq_cleanup(&state->seq);
clear_delta_hashes(state);
free(state);
}