svn commit: r310530 - head/usr.sbin/jls

Jamie Gritton jamie at FreeBSD.org
Sat Dec 24 23:51:28 UTC 2016


Author: jamie
Date: Sat Dec 24 23:51:27 2016
New Revision: 310530
URL: https://svnweb.freebsd.org/changeset/base/310530

Log:
  Improve IP address list representation in libxo output.
  
  Extract decision-making about special-case printing of certain
  jail parameters into a function.
  
  Refactor emitting of IPv4 and IPv6 address lists into a function.
  
  Resulting user-facing changes:
  
  XO_VERSION is bumped to 2.
  
  In verbose mode (-v), IPv4 and IPv6-Addresses are now properly emitted
  as separate lists.
  This only affects the output in encoding styles, i.e. xml and json.
  
  {                                    {
    "__version": "1",                    "__version": "2",
    "jail-information": {                "jail-information": {
      "jail": [                            "jail": [
        {                                    {
          "jid": 166,                          "jid": 166,
          "hostname": "foo.com",               "hostname": "foo.com",
          "path": "/var/jail/foo",             "path": "/var/jail/foo",
          "name": "foo",                       "name": "foo",
          "state": "ACTIVE",                   "state": "ACTIVE",
          "cpusetid": 2,                       "cpusetid": 2,
          "ipv4_addrs": [                      "ipv4_addrs": [
            "10.1.1.1",                          "10.1.1.1",
            "10.1.1.2",                          "10.1.1.2",
            "10.1.1.3",              |           "10.1.1.3"
                                     >         ],
                                     >         "ipv6_addrs": [
            "fe80::1000:1",                      "fe80::1000:1",
            "fe80::1000:2"                       "fe80::1000:2"
          ]                                    ]
        }                                    }
      ]                                    ]
    }                                    }
  }                                    }
  
  In -n mode, ip4.addr and ip6.addr are formatted in the encoding styles'
  native list types, e.g. instead of comma-separated lists, JSON arrays
  are printed.
  
  jls -n all --libxo json
   ...
   "ip4.addr": [
      "10.1.1.1",
      "10.1.1.2",
      "10.1.1.3"
    ],
    "ip4.saddrsel": true,
    "ip6.addr": [
      "fe80::1000:1",
      "fe80::1000:2"
    ],
    ...
  
  jls -n all --libxo xml
    ...
    <ip4.addr>10.1.1.1</ip4.addr>
    <ip4.addr>10.1.1.2</ip4.addr>
    <ip4.addr>10.1.1.3</ip4.addr>
    <ip4.saddrsel>true</ip4.saddrsel>
    <ip6.addr>fe80::1000:1</ip6.addr>
    <ip6.addr>fe80::1000:2</ip6.addr>
    ...
  
  PR:		215008
  Submitted by:	Christian Schwarz <me at cschwarz.com>
  Differential Revision:	https://reviews.freebsd.org/D8766

Modified:
  head/usr.sbin/jls/jls.c

Modified: head/usr.sbin/jls/jls.c
==============================================================================
--- head/usr.sbin/jls/jls.c	Sat Dec 24 23:43:14 2016	(r310529)
+++ head/usr.sbin/jls/jls.c	Sat Dec 24 23:51:27 2016	(r310530)
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
 #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,10 @@ static int sort_param(const void *a, con
 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_list(int af_family, const char *list_name,
+		struct jailparam *param);
 
 int
 main(int argc, char **argv)
@@ -379,8 +382,7 @@ print_jail(int pflags, int jflags)
 {
 	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 +403,13 @@ print_jail(int pflags, int jflags)
 		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);
-				}
+			emit_ip_addr_list(AF_INET, "ipv4_addrs", params + n);
 			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);
+			emit_ip_addr_list(AF_INET6, "ipv6_addrs", params + n);
 			n++;
 		}
 #endif
@@ -499,14 +485,8 @@ print_jail(int pflags, int jflags)
 				}
 				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 +533,70 @@ quoted_print(int pflags, char *name, cha
 	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")) {
+		emit_ip_addr_list(AF_INET, param->jp_name, param);
+	} else if (ip_as_list && !strcmp(param->jp_name, "ip6.addr")) {
+		emit_ip_addr_list(AF_INET6, param->jp_name, param);
+	} else {
+		return 0;
+	}
+
+	return 1;
+}
+
+static void
+emit_ip_addr_list(int af_family, const char *list_name, struct jailparam *param)
+{
+	char ipbuf[INET6_ADDRSTRLEN];
+	size_t addr_len;
+	const char *emit_str;
+	int ai, count;
+
+	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;
+
+	xo_open_list(list_name);
+	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);
+		}
+	}
+	xo_close_list(list_name);
+}


More information about the svn-src-head mailing list