}
static int addresses_build_json(Set *addresses, JsonVariant **ret) {
- JsonVariant **elements;
+ JsonVariant **elements = NULL;
Address *address;
size_t n = 0;
int r;
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (set_isempty(addresses)) {
*ret = NULL;
return 0;
SET_FOREACH(address, addresses) {
r = address_build_json(address, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Addresses", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Addresses", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int neighbor_build_json(Neighbor *n, JsonVariant **ret) {
}
static int neighbors_build_json(Set *neighbors, JsonVariant **ret) {
- JsonVariant **elements;
+ JsonVariant **elements = NULL;
Neighbor *neighbor;
size_t n = 0;
int r;
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (set_isempty(neighbors)) {
*ret = NULL;
return 0;
SET_FOREACH(neighbor, neighbors) {
r = neighbor_build_json(neighbor, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Neighbors", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Neighbors", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int nexthop_group_build_json(NextHop *nexthop, JsonVariant **ret) {
- JsonVariant **elements;
+ JsonVariant **elements = NULL;
struct nexthop_grp *g;
size_t n = 0;
int r;
assert(nexthop);
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (hashmap_isempty(nexthop->group)) {
*ret = NULL;
return 0;
JSON_BUILD_PAIR_UNSIGNED("ID", g->id),
JSON_BUILD_PAIR_UNSIGNED("Weight", g->weight+1)));
if (r < 0)
- goto failure;
+ return r;
n++;
}
- r = json_variant_new_array(ret, elements, n);
-
-failure:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_variant_new_array(ret, elements, n);
}
static int nexthop_build_json(NextHop *n, JsonVariant **ret) {
}
static int nexthops_build_json(Set *nexthops, JsonVariant **ret) {
- JsonVariant **elements;
+ JsonVariant **elements = NULL;
NextHop *nexthop;
size_t n = 0;
int r;
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (set_isempty(nexthops)) {
*ret = NULL;
return 0;
SET_FOREACH(nexthop, nexthops) {
r = nexthop_build_json(nexthop, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NextHops", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NextHops", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int route_build_json(Route *route, JsonVariant **ret) {
}
static int routes_build_json(Set *routes, JsonVariant **ret) {
- JsonVariant **elements;
+ JsonVariant **elements = NULL;
Route *route;
size_t n = 0;
int r;
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (set_isempty(routes)) {
*ret = NULL;
return 0;
SET_FOREACH(route, routes) {
r = route_build_json(route, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Routes", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Routes", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int routing_policy_rule_build_json(RoutingPolicyRule *rule, JsonVariant **ret) {
}
static int routing_policy_rules_build_json(Set *rules, JsonVariant **ret) {
- JsonVariant **elements;
+ JsonVariant **elements = NULL;
RoutingPolicyRule *rule;
size_t n = 0;
int r;
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (set_isempty(rules)) {
*ret = NULL;
return 0;
SET_FOREACH(rule, rules) {
r = routing_policy_rule_build_json(rule, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("RoutingPolicyRules", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("RoutingPolicyRules", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int network_build_json(Network *network, JsonVariant **ret) {
assert(link);
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (!link->network) {
*ret = NULL;
return 0;
if (link->n_dns != UINT_MAX) {
for (unsigned i = 0; i < link->n_dns; i++) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = dns_build_json_one(link, link->dns[i], NETWORK_CONFIG_SOURCE_RUNTIME, NULL, elements + n);
if (r < 0)
- goto finalize;
+ return r;
if (r > 0)
n++;
}
} else {
for (unsigned i = 0; i < link->network->n_dns; i++) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = dns_build_json_one(link, link->network->dns[i], NETWORK_CONFIG_SOURCE_STATIC, NULL, elements + n);
if (r < 0)
- goto finalize;
+ return r;
if (r > 0)
n++;
}
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
if (r < 0)
- goto finalize;
+ return r;
n_dns = sd_dhcp_lease_get_dns(link->dhcp_lease, &dns);
for (int i = 0; i < n_dns; i++) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = dns_build_json_one(link,
&(struct in_addr_full) { .family = AF_INET, .address.in = dns[i], },
&s,
elements + n);
if (r < 0)
- goto finalize;
+ return r;
if (r > 0)
n++;
}
r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6);
if (r < 0)
- goto finalize;
+ return r;
n_dns = sd_dhcp6_lease_get_dns(link->dhcp6_lease, &dns);
for (int i = 0; i < n_dns; i++) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = dns_build_json_one(link,
&(struct in_addr_full) { .family = AF_INET6, .address.in6 = dns[i], },
&s,
elements + n);
if (r < 0)
- goto finalize;
+ return r;
if (r > 0)
n++;
}
NDiscRDNSS *a;
SET_FOREACH(a, link->ndisc_rdnss) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = dns_build_json_one(link,
&(struct in_addr_full) { .family = AF_INET6, .address.in6 = a->address, },
&(union in_addr_union) { .in6 = a->router },
elements + n);
if (r < 0)
- goto finalize;
+ return r;
if (r > 0)
n++;
}
if (n == 0) {
*ret = NULL;
- r = 0;
- goto finalize;
+ return 0;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNS", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNS", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int server_build_json_one_addr(int family, const union in_addr_union *a, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) {
assert(link);
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (!link->network) {
*ret = NULL;
return 0;
}
STRV_FOREACH(p, link->ntp ?: link->network->ntp) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = server_build_json_one_string(*p, NETWORK_CONFIG_SOURCE_RUNTIME, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
if (r < 0)
- goto finalize;
+ return r;
n_ntp = sd_dhcp_lease_get_ntp(link->dhcp_lease, &ntp);
for (int i = 0; i < n_ntp; i++) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = server_build_json_one_addr(AF_INET,
&(union in_addr_union) { .in = ntp[i], },
&s,
elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6);
if (r < 0)
- goto finalize;
+ return r;
n_ntp = sd_dhcp6_lease_get_ntp_addrs(link->dhcp6_lease, &ntp_addr);
for (int i = 0; i < n_ntp; i++) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = server_build_json_one_addr(AF_INET6,
&(union in_addr_union) { .in6 = ntp_addr[i], },
&s,
elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
n_ntp = sd_dhcp6_lease_get_ntp_fqdn(link->dhcp6_lease, &ntp_fqdn);
for (int i = 0; i < n_ntp; i++) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = server_build_json_one_fqdn(AF_INET6,
ntp_fqdn[i],
&s,
elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
return 0;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NTP", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NTP", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int sip_build_json(Link *link, JsonVariant **ret) {
const struct in_addr *sip;
- JsonVariant **elements;
+ JsonVariant **elements = NULL;
union in_addr_union s;
size_t n = 0;
int n_sip, r;
assert(link);
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (!link->network || !link->network->dhcp_use_sip || !link->dhcp_lease) {
*ret = NULL;
return 0;
&s,
elements + n);
if (r < 0)
- goto finalize;
+ return r;
if (r > 0)
n++;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("SIP", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("SIP", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int captive_portal_build_json(Link *link, JsonVariant **ret) {
assert(link);
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (!link->network) {
*ret = NULL;
return 0;
use_domains = is_route ? DHCP_USE_DOMAINS_ROUTE : DHCP_USE_DOMAINS_YES;
ORDERED_SET_FOREACH(domain, link_domains ?: network_domains) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = domain_build_json(AF_UNSPEC, domain,
link_domains ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC,
NULL, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
link->network->dhcp_use_domains == use_domains) {
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
if (r < 0)
- goto finalize;
+ return r;
if (sd_dhcp_lease_get_domainname(link->dhcp_lease, &domain) >= 0) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = domain_build_json(AF_INET, domain, NETWORK_CONFIG_SOURCE_DHCP4, &s, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
if (sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains) >= 0) {
STRV_FOREACH(p, domains) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = domain_build_json(AF_INET, *p, NETWORK_CONFIG_SOURCE_DHCP4, &s, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
link->network->dhcp6_use_domains == use_domains) {
r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6);
if (r < 0)
- goto finalize;
+ return r;
if (sd_dhcp6_lease_get_domains(link->dhcp6_lease, &domains) >= 0) {
STRV_FOREACH(p, domains) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = domain_build_json(AF_INET6, *p, NETWORK_CONFIG_SOURCE_DHCP6, &s, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
NDiscDNSSL *a;
SET_FOREACH(a, link->ndisc_dnssl) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = domain_build_json(AF_INET6, NDISC_DNSSL_DOMAIN(a), NETWORK_CONFIG_SOURCE_NDISC,
&(union in_addr_union) { .in6 = a->router },
elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
return 0;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR(is_route ? "RouteDomains" : "SearchDomains",
- JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR(is_route ? "RouteDomains" : "SearchDomains",
+ JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int nta_build_json(const char *nta, NetworkConfigSource s, JsonVariant **ret) {
assert(link);
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (!link->network) {
*ret = NULL;
return 0;
}
SET_FOREACH(nta, link->dnssec_negative_trust_anchors ?: link->network->dnssec_negative_trust_anchors) {
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = nta_build_json(nta,
link->dnssec_negative_trust_anchors ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC,
elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
return 0;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSECNegativeTrustAnchors",
- JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSECNegativeTrustAnchors",
+ JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int dns_misc_build_json(Link *link, JsonVariant **ret) {
assert(link);
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
if (!link->network) {
*ret = NULL;
return 0;
if (resolve_support >= 0) {
source = link->llmnr >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC;
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = json_build(elements + n, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR_STRING("LLMNR", resolve_support_to_string(resolve_support)),
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source))));
if (r < 0)
- goto finalize;
+ return r;
n++;
}
if (resolve_support >= 0) {
source = link->mdns >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC;
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = json_build(elements + n, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR_STRING("MDNS", resolve_support_to_string(resolve_support)),
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source))));
if (r < 0)
- goto finalize;
+ return r;
n++;
}
if (t >= 0) {
source = link->dns_default_route >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC;
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = json_build(elements + n, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR_BOOLEAN("DNSDefaultRoute", t),
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source))));
if (r < 0)
- goto finalize;
+ return r;
n++;
}
if (mode >= 0) {
source = link->dns_over_tls_mode >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC;
- if (!GREEDY_REALLOC(elements, n + 1)) {
- r = -ENOMEM;
- goto finalize;
- }
+ if (!GREEDY_REALLOC(elements, n + 1))
+ return -ENOMEM;
r = json_build(elements + n, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR_STRING("DNSOverTLS", dns_over_tls_mode_to_string(mode)),
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source))));
if (r < 0)
- goto finalize;
+ return r;
n++;
}
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSettings",
- JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSettings",
+ JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
static int dhcp_server_offered_leases_build_json(Link *link, JsonVariant **ret) {
}
static int links_build_json(Manager *manager, JsonVariant **ret) {
- JsonVariant **elements;
+ JsonVariant **elements = NULL;
Link *link;
size_t n = 0;
int r;
assert(manager);
assert(ret);
+ CLEANUP_ARRAY(elements, n, json_variant_unref_many);
+
elements = new(JsonVariant*, hashmap_size(manager->links_by_index));
if (!elements)
return -ENOMEM;
HASHMAP_FOREACH(link, manager->links_by_index) {
r = link_build_json(link, elements + n);
if (r < 0)
- goto finalize;
+ return r;
n++;
}
typesafe_qsort(elements, n, link_json_compare);
- r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Interfaces", JSON_BUILD_VARIANT_ARRAY(elements, n))));
-
-finalize:
- json_variant_unref_many(elements, n);
- free(elements);
- return r;
+ return json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Interfaces", JSON_BUILD_VARIANT_ARRAY(elements, n))));
}
int manager_build_json(Manager *manager, JsonVariant **ret) {
JsonVariant* values[];
};
+static struct json_data* json_data_free(struct json_data *d) {
+ if (!d)
+ return NULL;
+
+ json_variant_unref(d->name);
+
+ FOREACH_ARRAY(v, d->values, d->n_values)
+ json_variant_unref(*v);
+
+ return mfree(d);
+}
+
+DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(json_data_hash_ops_free,
+ char, string_hash_func, string_compare_func,
+ struct json_data, json_data_free);
+
static int update_json_data(
Hashmap *h,
OutputFlags flags,
size_t size) {
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
- struct json_data *d;
+ struct json_data *d = NULL;
int r;
assert(name);
char usecbuf[CONST_MAX(DECIMAL_STR_MAX(usec_t), DECIMAL_STR_MAX(uint64_t))];
_cleanup_(json_variant_unrefp) JsonVariant *object = NULL;
+ _cleanup_hashmap_free_ Hashmap *h = NULL;
sd_id128_t journal_boot_id, seqnum_id;
_cleanup_free_ char *cursor = NULL;
usec_t realtime, monotonic;
JsonVariant **array = NULL;
struct json_data *d;
- Hashmap *h = NULL;
uint64_t seqnum;
size_t n = 0;
int r;
if (r < 0)
return log_error_errno(r, "Failed to get seqnum: %m");
- h = hashmap_new(&string_hash_ops);
+ h = hashmap_new(&json_data_hash_ops_free);
if (!h)
return log_oom();
r = update_json_data(h, flags, "__CURSOR", cursor, SIZE_MAX);
if (r < 0)
- goto finish;
+ return r;
xsprintf(usecbuf, USEC_FMT, realtime);
r = update_json_data(h, flags, "__REALTIME_TIMESTAMP", usecbuf, SIZE_MAX);
if (r < 0)
- goto finish;
+ return r;
xsprintf(usecbuf, USEC_FMT, monotonic);
r = update_json_data(h, flags, "__MONOTONIC_TIMESTAMP", usecbuf, SIZE_MAX);
if (r < 0)
- goto finish;
+ return r;
r = update_json_data(h, flags, "_BOOT_ID", SD_ID128_TO_STRING(journal_boot_id), SIZE_MAX);
if (r < 0)
- goto finish;
+ return r;
xsprintf(usecbuf, USEC_FMT, seqnum);
r = update_json_data(h, flags, "__SEQNUM", usecbuf, SIZE_MAX);
if (r < 0)
- goto finish;
+ return r;
r = update_json_data(h, flags, "__SEQNUM_ID", SD_ID128_TO_STRING(seqnum_id), SIZE_MAX);
if (r < 0)
- goto finish;
+ return r;
for (;;) {
const void *data;
r = sd_journal_enumerate_data(j, &data, &size);
if (IN_SET(r, -EBADMSG, -EADDRNOTAVAIL)) {
log_debug_errno(r, "Skipping message we can't read: %m");
- r = 0;
- goto finish;
- }
- if (r < 0) {
- log_error_errno(r, "Failed to read journal: %m");
- goto finish;
+ return 0;
}
+ if (r < 0)
+ return log_error_errno(r, "Failed to read journal: %m");
if (r == 0)
break;
r = update_json_data_split(h, flags, output_fields, data, size);
if (r < 0)
- goto finish;
+ return r;
}
array = new(JsonVariant*, hashmap_size(h)*2);
- if (!array) {
- r = log_oom();
- goto finish;
- }
+ if (!array)
+ return log_oom();
+
+ CLEANUP_ARRAY(array, n, json_variant_unref_many);
HASHMAP_FOREACH(d, h) {
assert(d->n_values > 0);
_cleanup_(json_variant_unrefp) JsonVariant *q = NULL;
r = json_variant_new_array(&q, d->values, d->n_values);
- if (r < 0) {
- log_error_errno(r, "Failed to create JSON array: %m");
- goto finish;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to create JSON array: %m");
array[n++] = TAKE_PTR(q);
}
}
r = json_variant_new_object(&object, array, n);
- if (r < 0) {
- log_error_errno(r, "Failed to allocate JSON object: %m");
- goto finish;
- }
-
- json_variant_dump(object,
- output_mode_to_json_format_flags(mode) |
- (FLAGS_SET(flags, OUTPUT_COLOR) ? JSON_FORMAT_COLOR : 0),
- f, NULL);
-
- r = 0;
-
-finish:
- while ((d = hashmap_steal_first(h))) {
- json_variant_unref(d->name);
- json_variant_unref_many(d->values, d->n_values);
- free(d);
- }
-
- hashmap_free(h);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate JSON object: %m");
- json_variant_unref_many(array, n);
- free(array);
- return r;
+ return json_variant_dump(object,
+ output_mode_to_json_format_flags(mode) |
+ (FLAGS_SET(flags, OUTPUT_COLOR) ? JSON_FORMAT_COLOR : 0),
+ f, NULL);
}
static int output_cat_field(