1 /* $OpenBSD: output-json.c,v 1.13 2020/09/12 15:46:48 claudio Exp $ */ 2 /* 3 * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <stdlib.h> 19 #include <unistd.h> 20 #include <time.h> 21 #include <netdb.h> 22 23 #include "extern.h" 24 25 static int 26 outputheader_json(FILE *out, struct stats *st) 27 { 28 char hn[NI_MAXHOST], tbuf[26]; 29 struct tm *tp; 30 time_t t; 31 32 time(&t); 33 setenv("TZ", "UTC", 1); 34 tp = localtime(&t); 35 strftime(tbuf, sizeof tbuf, "%FT%TZ", tp); 36 37 gethostname(hn, sizeof hn); 38 39 if (fprintf(out, 40 "{\n\t\"metadata\": {\n" 41 "\t\t\"buildmachine\": \"%s\",\n" 42 "\t\t\"buildtime\": \"%s\",\n" 43 "\t\t\"elapsedtime\": \"%lld\",\n" 44 "\t\t\"usertime\": \"%lld\",\n" 45 "\t\t\"systemtime\": \"%lld\",\n" 46 "\t\t\"roas\": %zu,\n" 47 "\t\t\"failedroas\": %zu,\n" 48 "\t\t\"invalidroas\": %zu,\n" 49 "\t\t\"certificates\": %zu,\n" 50 "\t\t\"failcertificates\": %zu,\n" 51 "\t\t\"invalidcertificates\": %zu,\n" 52 "\t\t\"tals\": %zu,\n" 53 "\t\t\"talfiles\": \"%s\",\n" 54 "\t\t\"manifests\": %zu,\n" 55 "\t\t\"failedmanifests\": %zu,\n" 56 "\t\t\"stalemanifests\": %zu,\n" 57 "\t\t\"crls\": %zu,\n" 58 "\t\t\"repositories\": %zu,\n" 59 "\t\t\"vrps\": %zu,\n" 60 "\t\t\"uniquevrps\": %zu\n" 61 "\t},\n\n", 62 hn, tbuf, (long long)st->elapsed_time.tv_sec, 63 (long long)st->user_time.tv_sec, (long long)st->system_time.tv_sec, 64 st->roas, st->roas_fail, st->roas_invalid, 65 st->certs, st->certs_fail, st->certs_invalid, 66 st->tals, st->talnames, 67 st->mfts, st->mfts_fail, st->mfts_stale, 68 st->crls, 69 st->repos, 70 st->vrps, st->uniqs) < 0) 71 return -1; 72 return 0; 73 } 74 75 int 76 output_json(FILE *out, struct vrp_tree *vrps, struct stats *st) 77 { 78 char buf[64]; 79 struct vrp *v; 80 int first = 1; 81 82 if (outputheader_json(out, st) < 0) 83 return -1; 84 85 if (fprintf(out, "\t\"roas\": [\n") < 0) 86 return -1; 87 88 RB_FOREACH(v, vrp_tree, vrps) { 89 if (first) 90 first = 0; 91 else { 92 if (fprintf(out, ",\n") < 0) 93 return -1; 94 } 95 96 ip_addr_print(&v->addr, v->afi, buf, sizeof(buf)); 97 98 if (fprintf(out, "\t\t{ \"asn\": \"AS%u\", \"prefix\": \"%s\", " 99 "\"maxLength\": %u, \"ta\": \"%s\" }", 100 v->asid, buf, v->maxlength, v->tal) < 0) 101 return -1; 102 } 103 104 if (fprintf(out, "\n\t]\n}\n") < 0) 105 return -1; 106 return 0; 107 } 108