1 /* $OpenBSD: output-json.c,v 1.17 2021/05/06 17:03:57 job 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\"gbrs\": %zu,\n" 59 "\t\t\"repositories\": %zu,\n" 60 "\t\t\"vrps\": %zu,\n" 61 "\t\t\"uniquevrps\": %zu,\n" 62 "\t\t\"cachedir_del_files\": %zu,\n" 63 "\t\t\"cachedir_del_dirs\": %zu\n" 64 "\t},\n\n", 65 hn, tbuf, (long long)st->elapsed_time.tv_sec, 66 (long long)st->user_time.tv_sec, (long long)st->system_time.tv_sec, 67 st->roas, st->roas_fail, st->roas_invalid, 68 st->certs, st->certs_fail, st->certs_invalid, 69 st->tals, st->talnames, 70 st->mfts, st->mfts_fail, st->mfts_stale, 71 st->crls, 72 st->gbrs, 73 st->repos, 74 st->vrps, st->uniqs, 75 st->del_files, st->del_dirs) < 0) 76 return -1; 77 return 0; 78 } 79 80 int 81 output_json(FILE *out, struct vrp_tree *vrps, struct stats *st) 82 { 83 char buf[64]; 84 struct vrp *v; 85 int first = 1; 86 87 if (outputheader_json(out, st) < 0) 88 return -1; 89 90 if (fprintf(out, "\t\"roas\": [\n") < 0) 91 return -1; 92 93 RB_FOREACH(v, vrp_tree, vrps) { 94 if (first) 95 first = 0; 96 else { 97 if (fprintf(out, ",\n") < 0) 98 return -1; 99 } 100 101 ip_addr_print(&v->addr, v->afi, buf, sizeof(buf)); 102 103 if (fprintf(out, "\t\t{ \"asn\": %u, \"prefix\": \"%s\", " 104 "\"maxLength\": %u, \"ta\": \"%s\", \"expires\": %lld }", 105 v->asid, buf, v->maxlength, v->tal, (long long)v->expires) 106 < 0) 107 return -1; 108 } 109 110 if (fprintf(out, "\n\t]\n}\n") < 0) 111 return -1; 112 return 0; 113 } 114