Index: usr.sbin/jls/jls.8 =================================================================== --- usr.sbin/jls/jls.8 +++ usr.sbin/jls/jls.8 @@ -104,7 +104,11 @@ containing the following parameters: jail identifier (jid), hostname (host.hostname), path (path), jail name (name), jail state (dying), cpuset ID (cpuset), -IP address(es) (ip4.addr and ip6.addr). +IP address(es) (ip4.addr and ip6.addr, one address per line). +.Pp +For encoding-styled +.Sy --libxo +output, IPv4 and IPv6 addresses emitted as separate lists. .It Fl j Ar jail The jid or name of the .Ar jail Index: usr.sbin/jls/jls.c =================================================================== --- usr.sbin/jls/jls.c +++ usr.sbin/jls/jls.c @@ -51,7 +51,7 @@ #define JP_USER 0x01000000 #define JP_OPT 0x02000000 -#define JLS_XO_VERSION "1" +#define JLS_XO_VERSION "2" #define PRINT_DEFAULT 0x01 #define PRINT_HEADER 0x02 @@ -77,7 +77,9 @@ static char *noname(const char *name); static char *nononame(const char *name); static int print_jail(int pflags, int jflags); +static int special_print(int pflags, struct jailparam *param); static void quoted_print(int pflags, char *name, char *value); +static void emit_ip_addr(int af_family, struct jailparam *param); int main(int argc, char **argv) @@ -379,8 +381,7 @@ { char *nname, *xo_nname; char **param_values; - int i, ai, jid, count, n, spc; - char ipbuf[INET6_ADDRSTRLEN]; + int i, jid, n, spc; jid = jailparam_get(params, nparams, jflags); if (jid < 0) @@ -401,29 +402,17 @@ n = 6; #ifdef INET if (ip4_ok && !strcmp(params[n].jp_name, "ip4.addr")) { - count = params[n].jp_valuelen / sizeof(struct in_addr); - for (ai = 0; ai < count; ai++) - if (inet_ntop(AF_INET, - &((struct in_addr *)params[n].jp_value)[ai], - ipbuf, sizeof(ipbuf)) == NULL) - xo_err(1, "inet_ntop"); - else { - xo_emit("{P: }{l:ipv4_addrs}{P:\n}", ipbuf); - } + xo_open_list("ipv4_addrs"); + emit_ip_addr(AF_INET, params + n); + xo_close_list("ipv4_addrs"); n++; } #endif #ifdef INET6 if (ip6_ok && !strcmp(params[n].jp_name, "ip6.addr")) { - count = params[n].jp_valuelen / sizeof(struct in6_addr); - for (ai = 0; ai < count; ai++) - if (inet_ntop(AF_INET6, - &((struct in6_addr *) - params[n].jp_value)[ai], - ipbuf, sizeof(ipbuf)) == NULL) - xo_err(1, "inet_ntop"); - else - xo_emit("{P: }{l:ipv6_addrs}{P:\n}", ipbuf); + xo_open_list("ipv6_addrs"); + emit_ip_addr(AF_INET6, params + n); + xo_close_list("ipv6_addrs"); n++; } #endif @@ -450,6 +439,7 @@ if (!(params[i].jp_flags & JP_USER)) continue; param_values[i] = jailparam_export(params + i); + param_values[i] = jailparam_export(params + i); if (param_values[i] == NULL) xo_errx(1, "%s", jail_errmsg); } @@ -499,14 +489,10 @@ } xo_emit("{d:%s}=", params[i].jp_name); } - if (params[i].jp_valuelen == 0) { - if (pflags & PRINT_QUOTED) - xo_emit("{P:\"\"}"); - else if (!(pflags & PRINT_NAMEVAL)) - xo_emit("{P:-}"); - } else { + + if (!special_print(pflags, params + i)) quoted_print(pflags, params[i].jp_name, param_values[i]); - } + } xo_emit("{P:\n}"); for (i = 0; i < nparams; i++) @@ -553,3 +539,72 @@ if (qc && pflags & PRINT_QUOTED) xo_emit("{P:/%c}", qc); } + +static int +special_print(int pflags, struct jailparam *param) { + + int ip_as_list; + + switch (xo_get_style(NULL)) { + case XO_STYLE_JSON: + case XO_STYLE_XML: + ip_as_list = 1; + break; + default: + ip_as_list = 0; + } + + if (!ip_as_list && param->jp_valuelen == 0) { + if (pflags & PRINT_QUOTED) + xo_emit("{P:\"\"}"); + else if (!(pflags & PRINT_NAMEVAL)) + xo_emit("{P:-}"); + } else if (ip_as_list && !strcmp(param->jp_name, "ip4.addr")) { + xo_open_list("ip4.addr"); + emit_ip_addr(AF_INET, param); + xo_close_list("ip4.addr"); + } else if (ip_as_list && !strcmp(param->jp_name, "ip6.addr")) { + xo_open_list("ip6.addr"); + emit_ip_addr(AF_INET6, param); + xo_close_list("ip6.addr"); + } else { + return 0; + } + + return 1; +} + +static void +emit_ip_addr(int af_family, struct jailparam *param) { + char ipbuf[INET6_ADDRSTRLEN]; + size_t addr_len; + const char *emit_str; + int count, ai; + + switch (af_family) { + case AF_INET: + addr_len = sizeof(struct in_addr); + emit_str = "{P: }{ql:ipv4_addr}{P:\n}"; + break; + case AF_INET6: + addr_len = sizeof(struct in6_addr); + emit_str = "{P: }{ql:ipv6_addr}{P:\n}"; + break; + default: + xo_err(1, "unsupported af_family"); + return; + } + + count = param->jp_valuelen / addr_len; + + for (ai = 0; ai < count; ai++) { + if (inet_ntop(af_family, + ((uint8_t*)param->jp_value) + addr_len*ai, + ipbuf, sizeof(ipbuf)) == NULL) { + xo_err(1, "inet_ntop"); + } else { + xo_emit(emit_str, ipbuf); + } + } + +}