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 <m...@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);
+}
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to