From a09a319138073774985f6c6e2b7c5117a3a98bf4 Mon Sep 17 00:00:00 2001 From: claudio Date: Mon, 5 Jun 2023 14:19:13 +0000 Subject: [PATCH] Add an extra argument compact to json_do_object() to instruct the parser to dump this object on a single line. While one can select on an object to object basis for arrays the compact setting is inherited from the surrounding object. Requested by job@, OK job@ tb@ --- usr.sbin/rpki-client/json.c | 52 ++++++++++++++++++++------- usr.sbin/rpki-client/json.h | 4 +-- usr.sbin/rpki-client/output-json.c | 12 +++---- usr.sbin/rpki-client/output-ometric.c | 3 +- usr.sbin/rpki-client/print.c | 24 ++++++------- 5 files changed, 61 insertions(+), 34 deletions(-) diff --git a/usr.sbin/rpki-client/json.c b/usr.sbin/rpki-client/json.c index 5d860729ef2..970439babbf 100644 --- a/usr.sbin/rpki-client/json.c +++ b/usr.sbin/rpki-client/json.c @@ -1,4 +1,4 @@ -/* $OpenBSD: json.c,v 1.2 2023/05/03 07:56:05 claudio Exp $ */ +/* $OpenBSD: json.c,v 1.3 2023/06/05 14:19:13 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker @@ -38,6 +38,7 @@ enum json_type { static struct json_stack { const char *name; unsigned int count; + int compact; enum json_type type; } stack[JSON_MAX_STACK]; @@ -49,9 +50,18 @@ static FILE *jsonfh; static void do_comma_indent(void) { - if (stack[level].count++ > 0) + char sp = '\n'; + + if (stack[level].compact) + sp = ' '; + + if (stack[level].count++ > 0) { if (!eb) - eb = fprintf(jsonfh, ",\n") < 0; + eb = fprintf(jsonfh, ",%c", sp) < 0; + } + + if (stack[level].compact) + return; if (!eb) eb = fprintf(jsonfh, "\t%.*s", level, indent) < 0; } @@ -107,6 +117,7 @@ void json_do_array(const char *name) { int i, l; + char sp = '\n'; if ((l = do_find(ARRAY, name)) > 0) { /* array already in use, close element and move on */ @@ -118,10 +129,12 @@ json_do_array(const char *name) if (stack[level].type == ARRAY) json_do_end(); + if (stack[level].compact) + sp = ' '; do_comma_indent(); do_name(name); if (!eb) - eb = fprintf(jsonfh, "[\n") < 0; + eb = fprintf(jsonfh, "[%c", sp) < 0; if (++level >= JSON_MAX_STACK) errx(1, "json stack too deep"); @@ -129,12 +142,15 @@ json_do_array(const char *name) stack[level].name = name; stack[level].type = ARRAY; stack[level].count = 0; + /* inherit compact setting from above level */ + stack[level].compact = stack[level - 1].compact; } void -json_do_object(const char *name) +json_do_object(const char *name, int compact) { int i, l; + char sp = '\n'; if ((l = do_find(OBJECT, name)) > 0) { /* roll back to that object and close it */ @@ -142,10 +158,12 @@ json_do_object(const char *name) json_do_end(); } + if (compact) + sp = ' '; do_comma_indent(); do_name(name); if (!eb) - eb = fprintf(jsonfh, "{\n") < 0; + eb = fprintf(jsonfh, "{%c", sp) < 0; if (++level >= JSON_MAX_STACK) errx(1, "json stack too deep"); @@ -153,23 +171,33 @@ json_do_object(const char *name) stack[level].name = name; stack[level].type = OBJECT; stack[level].count = 0; + stack[level].compact = compact; } void json_do_end(void) { - if (stack[level].type == ARRAY) { - if (!eb) - eb = fprintf(jsonfh, "\n%.*s]", level, indent) < 0; - } else if (stack[level].type == OBJECT) { + char c; + + if (stack[level].type == ARRAY) + c = ']'; + else if (stack[level].type == OBJECT) + c = '}'; + else + errx(1, "json bad stack state"); + + if (!stack[level].compact) { if (!eb) - eb = fprintf(jsonfh, "\n%.*s}", level, indent) < 0; + eb = fprintf(jsonfh, "\n%.*s%c", level, indent, c) < 0; } else { - errx(1, "json bad stack state"); + if (!eb) + eb = fprintf(jsonfh, " %c", c) < 0; } + stack[level].name = NULL; stack[level].type = NONE; stack[level].count = 0; + stack[level].compact = 0; if (level-- <= 0) errx(1, "json stack underflow"); diff --git a/usr.sbin/rpki-client/json.h b/usr.sbin/rpki-client/json.h index 5eb8babef4c..011d38f8aed 100644 --- a/usr.sbin/rpki-client/json.h +++ b/usr.sbin/rpki-client/json.h @@ -1,4 +1,4 @@ -/* $OpenBSD: json.h,v 1.2 2023/05/03 07:56:05 claudio Exp $ */ +/* $OpenBSD: json.h,v 1.3 2023/06/05 14:19:13 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker @@ -22,7 +22,7 @@ void json_do_start(FILE *); int json_do_finish(void); void json_do_array(const char *); -void json_do_object(const char *); +void json_do_object(const char *, int); void json_do_end(void); void json_do_printf(const char *, const char *, ...) __attribute__((__format__ (printf, 2, 3))); diff --git a/usr.sbin/rpki-client/output-json.c b/usr.sbin/rpki-client/output-json.c index f68872e5998..dce33e631c5 100644 --- a/usr.sbin/rpki-client/output-json.c +++ b/usr.sbin/rpki-client/output-json.c @@ -1,4 +1,4 @@ -/* $OpenBSD: output-json.c,v 1.38 2023/05/26 14:57:38 claudio Exp $ */ +/* $OpenBSD: output-json.c,v 1.39 2023/06/05 14:19:13 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker * @@ -37,7 +37,7 @@ outputheader_json(struct stats *st) gethostname(hn, sizeof hn); - json_do_object("metadata"); + json_do_object("metadata", 0); json_do_string("buildmachine", hn); json_do_string("buildtime", tbuf); @@ -87,7 +87,7 @@ print_vap(struct vap *v, enum afi afi) size_t i; int found = 0; - json_do_object("aspa"); + json_do_object("aspa", 1); json_do_int("customer_asid", v->custasid); json_do_int("expires", v->expires); @@ -108,7 +108,7 @@ output_aspa(struct vap_tree *vaps) { struct vap *v; - json_do_object("provider_authorizations"); + json_do_object("provider_authorizations", 0); json_do_array("ipv4"); RB_FOREACH(v, vap_tree, vaps) { @@ -138,7 +138,7 @@ output_json(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks, RB_FOREACH(v, vrp_tree, vrps) { ip_addr_print(&v->addr, v->afi, buf, sizeof(buf)); - json_do_object("roa"); + json_do_object("roa", 1); json_do_int("asn", v->asid); json_do_string("prefix", buf); json_do_int("maxLength", v->maxlength); @@ -150,7 +150,7 @@ output_json(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks, json_do_array("bgpsec_keys"); RB_FOREACH(b, brk_tree, brks) { - json_do_object("brks"); + json_do_object("brks", 0); json_do_int("asn", b->asid); json_do_string("ski", b->ski); json_do_string("pubkey", b->pubkey); diff --git a/usr.sbin/rpki-client/output-ometric.c b/usr.sbin/rpki-client/output-ometric.c index 9ddd8960dd4..53ab900d768 100644 --- a/usr.sbin/rpki-client/output-ometric.c +++ b/usr.sbin/rpki-client/output-ometric.c @@ -1,4 +1,4 @@ -/* $OpenBSD: output-ometric.c,v 1.3 2023/04/26 16:32:41 claudio Exp $ */ +/* $OpenBSD: output-ometric.c,v 1.4 2023/06/05 14:19:13 claudio Exp $ */ /* * Copyright (c) 2022 Claudio Jeker * @@ -216,7 +216,6 @@ output_ometric(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks, repo_stats_collect(repo_stats, NULL); set_common_stats(&st->repo_tal_stats, rpki_obj, NULL); - ometric_set_int(rpki_repo, st->repos, NULL); ometric_set_int_with_labels(rpki_repo, st->rsync_repos, OKV("type", "state"), OKV("rsync", "synced"), NULL); ometric_set_int_with_labels(rpki_repo, st->rsync_fails, diff --git a/usr.sbin/rpki-client/print.c b/usr.sbin/rpki-client/print.c index fbd0e022af9..1b58bf20ab5 100644 --- a/usr.sbin/rpki-client/print.c +++ b/usr.sbin/rpki-client/print.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print.c,v 1.39 2023/05/30 12:02:22 claudio Exp $ */ +/* $OpenBSD: print.c,v 1.40 2023/06/05 14:19:13 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -161,7 +161,7 @@ as_resources_print(struct cert_as *as, size_t asz) for (i = 0; i < asz; i++) { if (outformats & FORMAT_JSON) - json_do_object("resource"); + json_do_object("resource", 1); switch (as[i].type) { case CERT_AS_ID: if (outformats & FORMAT_JSON) { @@ -183,7 +183,7 @@ as_resources_print(struct cert_as *as, size_t asz) break; case CERT_AS_RANGE: if (outformats & FORMAT_JSON) { - json_do_object("asrange"); + json_do_object("asrange", 1); json_do_uint("min", as[i].range.min); json_do_uint("max", as[i].range.max); json_do_end(); @@ -212,7 +212,7 @@ ip_resources_print(struct cert_ip *ips, size_t ipsz, size_t asz) for (i = 0; i < ipsz; i++) { if (outformats & FORMAT_JSON) - json_do_object("resource"); + json_do_object("resource", 1); switch (ips[i].type) { case CERT_IP_INHERIT: if (outformats & FORMAT_JSON) { @@ -240,7 +240,7 @@ ip_resources_print(struct cert_ip *ips, size_t ipsz, size_t asz) inet_ntop(sockt, ips[i].min, buf1, sizeof(buf1)); inet_ntop(sockt, ips[i].max, buf2, sizeof(buf2)); if (outformats & FORMAT_JSON) { - json_do_object("ip_range"); + json_do_object("ip_range", 1); json_do_string("min", buf1); json_do_string("max", buf2); json_do_end(); @@ -376,7 +376,7 @@ crl_print(const struct crl *p) x509_get_time(X509_REVOKED_get0_revocationDate(rev), &t); if (serial != NULL) { if (outformats & FORMAT_JSON) { - json_do_object("cert"); + json_do_object("cert", 1); json_do_string("serial", serial); json_do_string("date", time2str(t)); json_do_end(); @@ -436,7 +436,7 @@ mft_print(const X509 *x, const struct mft *p) errx(1, "base64_encode failure"); if (outformats & FORMAT_JSON) { - json_do_object("filehash"); + json_do_object("filehash", 1); json_do_string("filename", p->files[i].file); json_do_string("hash", hash); json_do_end(); @@ -495,7 +495,7 @@ roa_print(const X509 *x, const struct roa *p) p->ips[i].afi, buf, sizeof(buf)); if (outformats & FORMAT_JSON) { - json_do_object("vrp"); + json_do_object("vrp", 1); json_do_string("prefix", buf); json_do_uint("asid", p->asid); json_do_uint("maxlen", p->ips[i].maxlength); @@ -591,7 +591,7 @@ rsc_print(const X509 *x, const struct rsc *p) errx(1, "base64_encode failure"); if (outformats & FORMAT_JSON) { - json_do_object("filehash"); + json_do_object("filehash", 1); if (p->files[i].filename) json_do_string("filename", p->files[i].filename); @@ -616,7 +616,7 @@ static void aspa_provider(uint32_t as, enum afi afi) { if (outformats & FORMAT_JSON) { - json_do_object("aspa"); + json_do_object("aspa", 1); json_do_uint("asid", as); if (afi == AFI_IPV4) json_do_string("afi_limit", "ipv4"); @@ -713,7 +713,7 @@ takey_print(char *name, const struct takey *t) errx(1, "base64_encode failed in %s", __func__); if (outformats & FORMAT_JSON) { - json_do_object("takey"); + json_do_object("takey", 0); json_do_string("name", name); json_do_array("comments"); for (i = 0; i < t->commentsz; i++) @@ -824,7 +824,7 @@ geofeed_print(const X509 *x, const struct geofeed *p) ip_addr_print(&p->geoips[i].ip->ip, p->geoips[i].ip->afi, buf, sizeof(buf)); if (outformats & FORMAT_JSON) { - json_do_object("geoip"); + json_do_object("geoip", 1); json_do_string("prefix", buf); json_do_string("location", p->geoips[i].loc); json_do_end(); -- 2.20.1