summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2017-05-12 20:53:05 +0000
committerBryan Cantrill <bryan@joyent.com>2017-05-15 23:42:11 +0000
commitc5bf6dbcaf952d0108897703c878c1c0eb4be27f (patch)
tree824a414cbcbfaa82d814f9e40a949f3ceb739a5f
parentd7b3c0f0f9f6c7bd9fbafc475db0d96a54372712 (diff)
downloadillumos-joyent-c5bf6dbcaf952d0108897703c878c1c0eb4be27f.tar.gz
OS-6057 dladm show-link segfaults if you specify too many fields
Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Ryan Zezeski <ryan.zeseski@joyent.com> Approved by: Ryan Zezeski <ryan.zeseski@joyent.com>
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c38
-rw-r--r--usr/src/cmd/dladm/dladm.c60
-rw-r--r--usr/src/cmd/dlstat/dlstat.c44
-rw-r--r--usr/src/cmd/flowadm/flowadm.c33
-rw-r--r--usr/src/cmd/flowstat/flowstat.c33
-rw-r--r--usr/src/lib/libinetutil/common/mapfile-vers2
-rw-r--r--usr/src/lib/libinetutil/common/ofmt.c94
-rw-r--r--usr/src/lib/libinetutil/common/ofmt.h8
8 files changed, 131 insertions, 181 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c b/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c
index c4b7fd225f..041414fa85 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2017 Nexenta Systems, Inc.
+ * Copyright 2017 Joyent, Inc.
*/
#include <arpa/inet.h>
@@ -63,6 +64,9 @@ static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr;
static cmdfunc_t do_enable_addr, do_disable_addr;
static cmdfunc_t do_up_addr, do_down_addr, do_refresh_addr;
+static void warn(const char *, ...);
+static void die(const char *, ...);
+
typedef struct cmd {
char *c_name;
cmdfunc_t *c_fn;
@@ -334,7 +338,6 @@ static char *progname;
static void die(const char *, ...);
static void die_opterr(int, int, const char *);
static void warn_ipadmerr(ipadm_status_t, const char *, ...);
-static void ipadm_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t);
static void ipadm_check_propstr(const char *, boolean_t, const char *);
static void process_misc_addrargs(int, char **, const char *, int *,
uint32_t *);
@@ -726,7 +729,7 @@ do_show_ifprop(int argc, char **argv, const char *use)
if (state.sps_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, intfprop_fields, ofmtflags, 0, &ofmt);
- ipadm_ofmt_check(oferr, state.sps_parsable, ofmt);
+ ofmt_check(oferr, state.sps_parsable, ofmt, die, warn);
state.sps_ofmt = ofmt;
/* retrieve interface(s) and print the properties */
@@ -905,7 +908,7 @@ do_show_prop(int argc, char **argv, const char *use)
else
ofmtflags |= OFMT_WRAP;
oferr = ofmt_open(fields_str, modprop_fields, ofmtflags, 0, &ofmt);
- ipadm_ofmt_check(oferr, state.sps_parsable, ofmt);
+ ofmt_check(oferr, state.sps_parsable, ofmt, die, warn);
state.sps_ofmt = ofmt;
/* handles all the errors */
@@ -1827,7 +1830,7 @@ do_show_addr(int argc, char *argv[], const char *use)
fields_str = def_fields_str;
oferr = ofmt_open(fields_str, show_addr_fields, ofmtflags, 0, &ofmt);
- ipadm_ofmt_check(oferr, state.sa_parsable, ofmt);
+ ofmt_check(oferr, state.sa_parsable, ofmt, die, warn);
state.sa_ofmt = ofmt;
status = ipadm_addr_info(iph, ifname, &ainfo, 0, LIFC_DEFAULT);
@@ -1962,7 +1965,7 @@ do_show_if(int argc, char *argv[], const char *use)
if (state.si_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, show_if_fields, ofmtflags, 0, &ofmt);
- ipadm_ofmt_check(oferr, state.si_parsable, ofmt);
+ ofmt_check(oferr, state.si_parsable, ofmt, die, warn);
state.si_ofmt = ofmt;
bzero(&sargs, sizeof (sargs));
sargs.si_state = &state;
@@ -2120,7 +2123,7 @@ do_show_addrprop(int argc, char *argv[], const char *use)
if (state.sps_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, addrprop_fields, ofmtflags, 0, &ofmt);
- ipadm_ofmt_check(oferr, state.sps_parsable, ofmt);
+ ofmt_check(oferr, state.sps_parsable, ofmt, die, warn);
state.sps_ofmt = ofmt;
status = ipadm_addr_info(iph, ifname, &ainfop, 0, LIFC_DEFAULT);
@@ -2166,29 +2169,6 @@ do_show_addrprop(int argc, char *argv[], const char *use)
}
}
-static void
-ipadm_ofmt_check(ofmt_status_t oferr, boolean_t parsable,
- ofmt_handle_t ofmt)
-{
- char buf[OFMT_BUFSIZE];
-
- if (oferr == OFMT_SUCCESS)
- return;
- (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
- /*
- * All errors are considered fatal in parsable mode.
- * NOMEM errors are always fatal, regardless of mode.
- * For other errors, we print diagnostics in human-readable
- * mode and processs what we can.
- */
- if (parsable || oferr == OFMT_ENOFIELDS) {
- ofmt_close(ofmt);
- die(buf);
- } else {
- warn(buf);
- }
-}
-
/*
* check if the `pstr' adheres to following syntax
* - prop=<value[,...]> (for set)
diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c
index dce24dd440..40c28ad6ab 100644
--- a/usr/src/cmd/dladm/dladm.c
+++ b/usr/src/cmd/dladm/dladm.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015 Joyent, Inc. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
* Copyright 2016 Nexenta Systems, Inc.
*/
@@ -199,7 +199,6 @@ static ofmt_cb_t print_xaggr_cb, print_aggr_stats_cb;
static ofmt_cb_t print_phys_one_hwgrp_cb, print_wlan_attr_cb;
static ofmt_cb_t print_wifi_status_cb, print_link_attr_cb;
static ofmt_cb_t print_overlay_cb, print_overlay_fma_cb, print_overlay_targ_cb;
-static void dladm_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t);
typedef void cmdfunc_t(int, char **, const char *);
@@ -1864,7 +1863,7 @@ do_show_usage(int argc, char *argv[], const char *use)
&ofmt);
}
- dladm_ofmt_check(oferr, state.us_parsable, ofmt);
+ ofmt_check(oferr, state.us_parsable, ofmt, die, warn);
state.us_ofmt = ofmt;
if (d_arg) {
@@ -3625,7 +3624,7 @@ do_show_link(int argc, char *argv[], const char *use)
ofmtflags |= OFMT_WRAP;
oferr = ofmt_open(fields_str, link_fields, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
if (linkid == DATALINK_ALL_LINKID) {
@@ -3791,7 +3790,7 @@ do_show_aggr(int argc, char *argv[], const char *use)
if (state.gs_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.gs_parsable, ofmt);
+ ofmt_check(oferr, state.gs_parsable, ofmt, die, warn);
state.gs_ofmt = ofmt;
if (s_arg) {
@@ -4261,7 +4260,7 @@ do_show_iptun(int argc, char *argv[], const char *use)
oferr = ofmt_open(fields_str, iptun_fields, ofmtflags,
DLADM_DEFAULT_COL, &ofmt);
- dladm_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
state.ls_flags = flags;
@@ -4626,7 +4625,7 @@ do_show_phys(int argc, char *argv[], const char *use)
if (state.ls_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
if (linkid == DATALINK_ALL_LINKID) {
@@ -4705,7 +4704,7 @@ do_show_vlan(int argc, char *argv[], const char *use)
if (state.ls_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, vlan_fields, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
if (linkid == DATALINK_ALL_LINKID) {
@@ -5360,7 +5359,7 @@ do_show_vnic_common(int argc, char *argv[], const char *use,
if (state.vs_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, pf, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.vs_parsable, ofmt);
+ ofmt_check(oferr, state.vs_parsable, ofmt, die, warn);
state.vs_ofmt = ofmt;
if (s_arg) {
@@ -5745,7 +5744,7 @@ do_show_simnet(int argc, char *argv[], const char *use)
if (state.ls_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, simnet_fields, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
if (linkid == DATALINK_ALL_LINKID) {
@@ -5773,7 +5772,7 @@ link_stats(datalink_id_t linkid, uint_t interval, char *fields_str,
if (state->ls_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, link_s_fields, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state->ls_parsable, ofmt);
+ ofmt_check(oferr, state->ls_parsable, ofmt, die, warn);
state->ls_ofmt = ofmt;
/*
@@ -6084,7 +6083,7 @@ parse_wifi_fields(char *str, ofmt_handle_t *ofmt, uint_t cmdtype,
oferr = ofmt_open(str, template, (parsable ? OFMT_PARSABLE : 0),
0, ofmt);
- dladm_ofmt_check(oferr, parsable, *ofmt);
+ ofmt_check(oferr, parsable, *ofmt, die, warn);
return (0);
}
@@ -6899,7 +6898,7 @@ do_show_linkprop(int argc, char **argv, const char *use)
ofmtflags |= OFMT_WRAP;
oferr = ofmt_open(fields_str, linkprop_fields, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
if (linkid == DATALINK_ALL_LINKID) {
@@ -7685,7 +7684,7 @@ do_show_secobj(int argc, char **argv, const char *use)
if (state.ss_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, secobj_fields, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.ss_parsable, ofmt);
+ ofmt_check(oferr, state.ss_parsable, ofmt, die, warn);
state.ss_ofmt = ofmt;
flags = state.ss_persist ? DLADM_OPT_PERSIST : 0;
@@ -7817,7 +7816,7 @@ do_show_ether(int argc, char **argv, const char *use)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, ether_fields, ofmtflags,
DLADM_DEFAULT_COL, &ofmt);
- dladm_ofmt_check(oferr, state.es_parsable, ofmt);
+ ofmt_check(oferr, state.es_parsable, ofmt, die, warn);
state.es_ofmt = ofmt;
if (state.es_link == NULL) {
@@ -8891,7 +8890,7 @@ do_show_bridge(int argc, char **argv, const char *use)
if (parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, field_arr, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, brstate.state.ls_parsable, ofmt);
+ ofmt_check(oferr, brstate.state.ls_parsable, ofmt, die, warn);
brstate.state.ls_ofmt = ofmt;
for (;;) {
@@ -9262,29 +9261,6 @@ print_default_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
return (B_TRUE);
}
-static void
-dladm_ofmt_check(ofmt_status_t oferr, boolean_t parsable,
- ofmt_handle_t ofmt)
-{
- char buf[OFMT_BUFSIZE];
-
- if (oferr == OFMT_SUCCESS)
- return;
- (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
- /*
- * All errors are considered fatal in parsable mode.
- * NOMEM errors are always fatal, regardless of mode.
- * For other errors, we print diagnostics in human-readable
- * mode and processs what we can.
- */
- if (parsable || oferr == OFMT_ENOFIELDS) {
- ofmt_close(ofmt);
- die(buf);
- } else {
- warn(buf);
- }
-}
-
/*
* Called from the walker dladm_walk_datalink_id() for each IB partition to
* display IB partition specific information.
@@ -9482,7 +9458,7 @@ do_show_part(int argc, char *argv[], const char *use)
if (state.ps_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, part_fields, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.ps_parsable, ofmt);
+ ofmt_check(oferr, state.ps_parsable, ofmt, die, warn);
state.ps_ofmt = ofmt;
/*
@@ -9654,7 +9630,7 @@ do_show_ib(int argc, char *argv[], const char *use)
if (state.is_parsable)
ofmtflags |= OFMT_PARSABLE;
oferr = ofmt_open(fields_str, ib_fields, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, state.is_parsable, ofmt);
+ ofmt_check(oferr, state.is_parsable, ofmt, die, warn);
state.is_ofmt = ofmt;
/*
@@ -10455,7 +10431,7 @@ do_show_overlay(int argc, char *argv[], const char *use)
fields_str = NULL;
oferr = ofmt_open(fields_str, fieldsp, ofmtflags, 0, &ofmt);
- dladm_ofmt_check(oferr, parse, ofmt);
+ ofmt_check(oferr, parse, ofmt, die, warn);
err = 0;
if (argc > optind) {
diff --git a/usr/src/cmd/dlstat/dlstat.c b/usr/src/cmd/dlstat/dlstat.c
index 2615fdbb12..8c1749475b 100644
--- a/usr/src/cmd/dlstat/dlstat.c
+++ b/usr/src/cmd/dlstat/dlstat.c
@@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright 2017 Joyent, Inc.
+ */
+
#include <stdio.h>
#include <ctype.h>
#include <locale.h>
@@ -88,8 +92,6 @@ typedef struct show_history_state_s {
*/
static ofmt_cb_t print_default_cb;
-static void dlstat_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t);
-
typedef void cmdfunc_t(int, char **, const char *);
static cmdfunc_t do_show, do_show_history, do_show_phys, do_show_link;
@@ -782,7 +784,7 @@ do_show_history(int argc, char *argv[], const char *use)
&ofmt);
}
- dlstat_ofmt_check(oferr, state.hs_parsable, ofmt);
+ ofmt_check(oferr, state.hs_parsable, ofmt, die, warn);
state.hs_ofmt = ofmt;
if (d_arg) {
@@ -992,7 +994,7 @@ done:
}
void *
-print_rx_generic_ring_stats(const char *linkname, const char *zonename,
+print_rx_generic_ring_stats(const char *linkname, const char *zonename,
void *statentry, char unit, boolean_t parsable)
{
ring_stat_entry_t *sentry = statentry;
@@ -1288,7 +1290,8 @@ done:
void *
print_tx_lane_stats(const char *linkname, const char *zonename, void *statentry,
- char unit, boolean_t parsable) {
+ char unit, boolean_t parsable)
+{
tx_lane_stat_entry_t *sentry = statentry;
tx_lane_stat_t *link_stats = &sentry->tle_stats;
tx_lane_fields_buf_t *buf = NULL;
@@ -1814,7 +1817,7 @@ do_show(int argc, char *argv[], const char *use)
}
oferr = ofmt_open(fields_str, oftemplate, ofmtflags, 0, &ofmt);
- dlstat_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
show_link_stats(linkid, state, interval);
@@ -1993,7 +1996,7 @@ do_show_phys(int argc, char *argv[], const char *use)
}
oferr = ofmt_open(fields_str, oftemplate, ofmtflags, 0, &ofmt);
- dlstat_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
show_link_stats(linkid, state, interval);
@@ -2203,7 +2206,7 @@ do_show_link(int argc, char *argv[], const char *use)
}
oferr = ofmt_open(fields_str, oftemplate, ofmtflags, 0, &ofmt);
- dlstat_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
@@ -2340,7 +2343,7 @@ do_show_aggr(int argc, char *argv[], const char *use)
}
oferr = ofmt_open(fields_str, oftemplate, ofmtflags, 0, &ofmt);
- dlstat_ofmt_check(oferr, state.ls_parsable, ofmt);
+ ofmt_check(oferr, state.ls_parsable, ofmt, die, warn);
state.ls_ofmt = ofmt;
show_link_stats(linkid, state, interval);
@@ -2446,26 +2449,3 @@ print_default_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize)
(void) strlcpy(buf, value, bufsize);
return (B_TRUE);
}
-
-static void
-dlstat_ofmt_check(ofmt_status_t oferr, boolean_t parsable,
- ofmt_handle_t ofmt)
-{
- char buf[OFMT_BUFSIZE];
-
- if (oferr == OFMT_SUCCESS)
- return;
- (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
- /*
- * All errors are considered fatal in parsable mode.
- * NOMEM errors are always fatal, regardless of mode.
- * For other errors, we print diagnostics in human-readable
- * mode and processs what we can.
- */
- if (parsable || oferr == OFMT_ENOFIELDS) {
- ofmt_close(ofmt);
- die(buf);
- } else {
- warn(buf);
- }
-}
diff --git a/usr/src/cmd/flowadm/flowadm.c b/usr/src/cmd/flowadm/flowadm.c
index 34e597dc78..a1f1c7387e 100644
--- a/usr/src/cmd/flowadm/flowadm.c
+++ b/usr/src/cmd/flowadm/flowadm.c
@@ -21,7 +21,10 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright 2011 Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * Copyright 2017 Joyent, Inc.
*/
#include <stdio.h>
@@ -82,7 +85,6 @@ static void warn_dlerr(dladm_status_t, const char *, ...);
/* callback functions for printing output */
static ofmt_cb_t print_flowprop_cb, print_default_cb;
-static void flowadm_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t);
typedef struct cmd {
char *c_name;
@@ -661,7 +663,7 @@ do_show_flow(int argc, char *argv[])
}
oferr = ofmt_open(fields_str, flow_fields, ofmtflags, 0, &ofmt);
- flowadm_ofmt_check(oferr, state.fs_parsable, ofmt);
+ ofmt_check(oferr, state.fs_parsable, ofmt, die, warn);
state.fs_ofmt = ofmt;
/* Show attributes of one flow */
@@ -1205,7 +1207,7 @@ do_show_flowprop(int argc, char **argv)
state.fs_status = DLADM_STATUS_OK;
oferr = ofmt_open(fields_str, flowprop_fields, ofmtflags, 0, &ofmt);
- flowadm_ofmt_check(oferr, state.fs_parsable, ofmt);
+ ofmt_check(oferr, state.fs_parsable, ofmt, die, warn);
state.fs_ofmt = ofmt;
/* Show properties for one flow */
@@ -1296,26 +1298,3 @@ print_default_cb(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
(void) strlcpy(buf, value, bufsize);
return (B_TRUE);
}
-
-static void
-flowadm_ofmt_check(ofmt_status_t oferr, boolean_t parsable,
- ofmt_handle_t ofmt)
-{
- char buf[OFMT_BUFSIZE];
-
- if (oferr == OFMT_SUCCESS)
- return;
- (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
- /*
- * All errors are considered fatal in parsable mode.
- * NOMEM errors are always fatal, regardless of mode.
- * For other errors, we print diagnostics in human-readable
- * mode and processs what we can.
- */
- if (parsable || oferr == OFMT_ENOFIELDS) {
- ofmt_close(ofmt);
- die(buf);
- } else {
- warn(buf);
- }
-}
diff --git a/usr/src/cmd/flowstat/flowstat.c b/usr/src/cmd/flowstat/flowstat.c
index faabd74a14..ab1797922c 100644
--- a/usr/src/cmd/flowstat/flowstat.c
+++ b/usr/src/cmd/flowstat/flowstat.c
@@ -21,7 +21,10 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright 2011 Joyent, Inc. All rights reserved.
+ */
+
+/*
+ * Copyright 2017 Joyent, Inc.
*/
#include <stdio.h>
@@ -87,7 +90,6 @@ static void warn(const char *, ...);
/* callback functions for printing output */
static ofmt_cb_t print_default_cb, print_flow_stats_cb;
-static void flowstat_ofmt_check(ofmt_status_t, boolean_t, ofmt_handle_t);
#define NULL_OFMT {NULL, 0, 0, NULL}
@@ -719,7 +721,7 @@ main(int argc, char *argv[])
}
oferr = ofmt_open(fields_str, flow_s_fields, ofmtflags, 0, &ofmt);
- flowstat_ofmt_check(oferr, state.fs_parsable, ofmt);
+ ofmt_check(oferr, state.fs_parsable, ofmt, die, warn);
state.fs_ofmt = ofmt;
for (;;) {
@@ -987,7 +989,7 @@ do_show_history(int argc, char *argv[])
0, &ofmt);
}
- flowstat_ofmt_check(oferr, state.us_parsable, ofmt);
+ ofmt_check(oferr, state.us_parsable, ofmt, die, warn);
state.us_ofmt = ofmt;
if (F_arg && d_arg)
@@ -1116,26 +1118,3 @@ print_default_cb(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
(void) strlcpy(buf, value, bufsize);
return (B_TRUE);
}
-
-static void
-flowstat_ofmt_check(ofmt_status_t oferr, boolean_t parsable,
- ofmt_handle_t ofmt)
-{
- char buf[OFMT_BUFSIZE];
-
- if (oferr == OFMT_SUCCESS)
- return;
- (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
- /*
- * All errors are considered fatal in parsable mode.
- * NOMEM errors are always fatal, regardless of mode.
- * For other errors, we print diagnostics in human-readable
- * mode and processs what we can.
- */
- if (parsable || oferr == OFMT_ENOFIELDS) {
- ofmt_close(ofmt);
- die(buf);
- } else {
- warn(buf);
- }
-}
diff --git a/usr/src/lib/libinetutil/common/mapfile-vers b/usr/src/lib/libinetutil/common/mapfile-vers
index f47657c56e..39069ca83d 100644
--- a/usr/src/lib/libinetutil/common/mapfile-vers
+++ b/usr/src/lib/libinetutil/common/mapfile-vers
@@ -20,6 +20,7 @@
#
#
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2017 Joyent, Inc.
#
#
@@ -68,6 +69,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
ofmt_print;
ofmt_update_winsize;
ofmt_strerror;
+ ofmt_check;
mask2plen;
plen2mask;
sockaddrcmp;
diff --git a/usr/src/lib/libinetutil/common/ofmt.c b/usr/src/lib/libinetutil/common/ofmt.c
index 63d744cdc9..9fd1c53eee 100644
--- a/usr/src/lib/libinetutil/common/ofmt.c
+++ b/usr/src/lib/libinetutil/common/ofmt.c
@@ -23,6 +23,11 @@
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
+/*
+ * Copyright 2017 Joyent, Inc.
+ */
+
#include <errno.h>
#include <sys/types.h>
#include <stdlib.h>
@@ -34,6 +39,7 @@
#include <unistd.h>
#include <sys/sysmacros.h>
#include <libintl.h>
+#include <assert.h>
/*
* functions and structures to internally process a comma-separated string
@@ -45,9 +51,8 @@ typedef struct {
uint_t s_nfields; /* the number of fields in s_buf */
uint_t s_currfield; /* the current field being processed */
} split_t;
+
static void splitfree(split_t *);
-static split_t *split_str(const char *, uint_t);
-static split_t *split_fields(const ofmt_field_t *, uint_t, uint_t);
/*
* The state of the output is tracked in a ofmt_state_t structure.
@@ -122,26 +127,30 @@ fail:
}
/*
- * Split `fields' into at most `maxfields' fields. Return a pointer to
- * a split_t containing the split fields, or NULL on failure. Invoked
- * when all fields are implicitly selected at handle creation by
- * passing in a NULL fields_str
+ * Split a template into its maximum number of fields (capped by the maxcols
+ * if it's non-zero). Return a pointer to a split_t containing the split
+ * fields, or NULL on failure. Invoked when all fields are implicitly
+ * selected at handle creation.
*/
static split_t *
-split_fields(const ofmt_field_t *template, uint_t maxfields, uint_t maxcols)
+split_max(const ofmt_field_t *template, uint_t maxcols)
{
+ const ofmt_field_t *ofp;
split_t *sp;
- int i, cols;
+ int i, cols, nfields = 0;
sp = calloc(sizeof (split_t), 1);
if (sp == NULL)
return (NULL);
- sp->s_fields = malloc(sizeof (char *) * maxfields);
+ for (ofp = template; ofp->of_name != NULL; ofp++)
+ nfields++;
+
+ sp->s_fields = malloc(sizeof (char *) * nfields);
if (sp->s_fields == NULL)
goto fail;
cols = 0;
- for (i = 0; i < maxfields; i++) {
+ for (i = 0; i < nfields; i++) {
cols += template[i].of_width;
/*
* If all fields are implied without explicitly passing
@@ -179,11 +188,10 @@ ofmt_open(const char *str, const ofmt_field_t *template, uint_t flags,
uint_t maxcols, ofmt_handle_t *ofmt)
{
split_t *sp;
- uint_t i, j, of_index;
+ uint_t i, of_index;
const ofmt_field_t *ofp;
ofmt_field_t *of;
ofmt_state_t *os;
- int nfields = 0;
ofmt_status_t err = OFMT_SUCCESS;
boolean_t parsable = (flags & OFMT_PARSABLE);
boolean_t wrap = (flags & OFMT_WRAP);
@@ -207,18 +215,29 @@ ofmt_open(const char *str, const ofmt_field_t *template, uint_t flags,
}
if (template == NULL)
return (OFMT_ENOTEMPLATE);
- for (ofp = template; ofp->of_name != NULL; ofp++)
- nfields++;
+
/*
* split str into the columns selected, or construct the
* full set of columns (equivalent to -o all).
*/
if (str != NULL && strcasecmp(str, "all") != 0) {
+ const char *c;
+ int nfields = 1;
+
+ /*
+ * Get an upper bound on the number of fields by counting
+ * the commas.
+ */
+ for (c = str; *c != '\0'; c++) {
+ if (*c == ',')
+ nfields++;
+ }
+
sp = split_str(str, nfields);
} else {
if (parsable || (str != NULL && strcasecmp(str, "all") == 0))
maxcols = 0;
- sp = split_fields(template, nfields, maxcols);
+ sp = split_max(template, maxcols);
}
if (sp == NULL)
goto nomem;
@@ -238,13 +257,12 @@ ofmt_open(const char *str, const ofmt_field_t *template, uint_t flags,
* nfields is the number of fields in template.
*/
for (i = 0; i < sp->s_nfields; i++) {
- for (j = 0; j < nfields; j++) {
- if (strcasecmp(sp->s_fields[i],
- template[j].of_name) == 0) {
+ for (ofp = template; ofp->of_name != NULL; ofp++) {
+ if (strcasecmp(sp->s_fields[i], ofp->of_name) == 0)
break;
- }
}
- if (j == nfields) {
+
+ if (ofp->of_name == NULL) {
int nbad = os->os_nbad++;
err = OFMT_EBADFIELDS;
@@ -259,7 +277,7 @@ ofmt_open(const char *str, const ofmt_field_t *template, uint_t flags,
goto nomem;
continue;
}
- of[of_index].of_name = strdup(template[j].of_name);
+ of[of_index].of_name = strdup(ofp->of_name);
if (of[of_index].of_name == NULL)
goto nomem;
if (multiline) {
@@ -267,9 +285,9 @@ ofmt_open(const char *str, const ofmt_field_t *template, uint_t flags,
os->os_maxnamelen = MAX(n, os->os_maxnamelen);
}
- of[of_index].of_width = template[j].of_width;
- of[of_index].of_id = template[j].of_id;
- of[of_index].of_cb = template[j].of_cb;
+ of[of_index].of_width = ofp->of_width;
+ of[of_index].of_id = ofp->of_id;
+ of[of_index].of_cb = ofp->of_cb;
of_index++;
}
splitfree(sp);
@@ -611,3 +629,31 @@ ofmt_strerror(ofmt_handle_t ofmt, ofmt_status_t err, char *buf, uint_t bufsize)
(void) strlcat(buf, ebuf, bufsize);
return (buf);
}
+
+void
+ofmt_check(ofmt_status_t oferr, boolean_t parsable, ofmt_handle_t ofmt,
+ void (*die)(const char *, ...), void (*warn)(const char *, ...))
+{
+ char buf[OFMT_BUFSIZE];
+
+ assert(die != NULL);
+ assert(warn != NULL);
+
+ if (oferr == OFMT_SUCCESS)
+ return;
+
+ (void) ofmt_strerror(ofmt, oferr, buf, sizeof (buf));
+
+ /*
+ * All errors are considered fatal in parsable mode. OFMT_ENOMEM and
+ * OFMT_ENOFIELDS errors are always fatal, regardless of mode. For
+ * other errors, we print diagnostics in human-readable mode and
+ * processs what we can.
+ */
+ if (parsable || oferr == OFMT_ENOFIELDS || oferr == OFMT_ENOMEM) {
+ ofmt_close(ofmt);
+ die(buf);
+ } else {
+ warn(buf);
+ }
+}
diff --git a/usr/src/lib/libinetutil/common/ofmt.h b/usr/src/lib/libinetutil/common/ofmt.h
index e69d43e20a..f2cf1ac682 100644
--- a/usr/src/lib/libinetutil/common/ofmt.h
+++ b/usr/src/lib/libinetutil/common/ofmt.h
@@ -24,6 +24,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright 2017 Joyent, Inc.
+ */
+
#ifndef _OFMT_H
#define _OFMT_H
@@ -203,6 +207,10 @@ extern void ofmt_update_winsize(ofmt_handle_t);
*/
extern char *ofmt_strerror(ofmt_handle_t, ofmt_status_t, char *, uint_t);
+extern void ofmt_check(ofmt_status_t oferr, boolean_t parsable,
+ ofmt_handle_t ofmt,
+ void (*die)(const char *, ...), void (*warn)(const char *, ...));
+
#ifdef __cplusplus
}
#endif