The branch main has been updated by freqlabs:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c4ba4aa547184ab401204096cdad9def4ab37964

commit c4ba4aa547184ab401204096cdad9def4ab37964
Author:     Ryan Moeller <freql...@freebsd.org>
AuthorDate: 2021-03-02 10:29:17 +0000
Commit:     Ryan Moeller <freql...@freebsd.org>
CommitDate: 2021-03-05 09:15:55 +0000

    libifconfig: Overhaul ifconfig_media_* interfaces
    
    Define an ifmedia_t type to use for ifmedia words.
    
    Add ifconfig_media_lookup_* functions to lookup ifmedia words by name.
    
    Get media options as an array of option names rather than formatting it
    as a comma-delimited list into a buffer.
    
    Sprinkle const on static the static description tables for peace of
    mind.
    
    Don't need to zero memory allocated by calloc.
    
    Reviewed by:    kp
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D29029
---
 lib/libifconfig/Makefile            |   2 +-
 lib/libifconfig/Symbol.map          |   9 +-
 lib/libifconfig/libifconfig.h       |  69 +++++++-
 lib/libifconfig/libifconfig_media.c | 339 ++++++++++++++++++++++++------------
 share/examples/libifconfig/status.c |  27 ++-
 5 files changed, 324 insertions(+), 122 deletions(-)

diff --git a/lib/libifconfig/Makefile b/lib/libifconfig/Makefile
index 73dad36c1dc5..c6f006018427 100644
--- a/lib/libifconfig/Makefile
+++ b/lib/libifconfig/Makefile
@@ -7,7 +7,7 @@ INTERNALLIB=    true
 LIBADD=                m
 
 SHLIBDIR?=     /lib
-SHLIB_MAJOR=   1
+SHLIB_MAJOR=   2
 
 VERSION_DEF=   ${LIBCSRCDIR}/Versions.def
 SYMBOL_MAPS=   ${.CURDIR}/Symbol.map
diff --git a/lib/libifconfig/Symbol.map b/lib/libifconfig/Symbol.map
index 235092376b11..2d80fb31652a 100644
--- a/lib/libifconfig/Symbol.map
+++ b/lib/libifconfig/Symbol.map
@@ -26,12 +26,17 @@ FBSD_1.6 {
        ifconfig_lagg_get_lagg_status;
        ifconfig_lagg_get_laggport_status;
        ifconfig_list_cloners;
+       ifconfig_media_get_downreason;
        ifconfig_media_get_mediareq;
-       ifconfig_media_get_options_string;
+       ifconfig_media_get_mode;
+       ifconfig_media_get_options;
        ifconfig_media_get_status;
        ifconfig_media_get_subtype;
        ifconfig_media_get_type;
-       ifconfig_media_get_downreason;
+       ifconfig_media_lookup_mode;
+       ifconfig_media_lookup_options;
+       ifconfig_media_lookup_subtype;
+       ifconfig_media_lookup_type;
        ifconfig_open;
        ifconfig_set_capability;
        ifconfig_set_description;
diff --git a/lib/libifconfig/libifconfig.h b/lib/libifconfig/libifconfig.h
index d8245ea13b23..e1cd6d1821a5 100644
--- a/lib/libifconfig/libifconfig.h
+++ b/lib/libifconfig/libifconfig.h
@@ -202,10 +202,73 @@ int ifconfig_get_ifstatus(ifconfig_handle_t *h, const 
char *name,
  */
 int ifconfig_media_get_mediareq(ifconfig_handle_t *h, const char *name,
     struct ifmediareq **ifmr);
-const char *ifconfig_media_get_type(int ifmw);
-const char *ifconfig_media_get_subtype(int ifmw);
+
 const char *ifconfig_media_get_status(const struct ifmediareq *ifmr);
-void ifconfig_media_get_options_string(int ifmw, char *buf, size_t buflen);
+
+typedef int ifmedia_t;
+
+#define INVALID_IFMEDIA ((ifmedia_t)-1)
+
+/** Retrieve the name of a media type
+ * @param media        The media to be named
+ * @return     A pointer to the media type name, or NULL on failure
+ */
+const char *ifconfig_media_get_type(ifmedia_t media);
+
+/** Retrieve a media type by its name
+ * @param name The name of a media type
+ * @return     The media type value, or INVALID_IFMEDIA on failure
+ */
+ifmedia_t ifconfig_media_lookup_type(const char *name);
+
+/** Retrieve the name of a media subtype
+ * @param media        The media subtype to be named
+ * @return     A pointer to the media subtype name, or NULL on failure
+ */
+const char *ifconfig_media_get_subtype(ifmedia_t media);
+
+/** Retrieve a media subtype by its name
+ * @param media        The top level media type whose subtype we want
+ * @param name The name of a media subtype
+ * @return     The media subtype value, or INVALID_IFMEDIA on failure
+ */
+ifmedia_t ifconfig_media_lookup_subtype(ifmedia_t media, const char *name);
+
+/** Retrieve the name of a media mode
+ * @param media        The media mode to be named
+ * @return     A pointer to the media mode name, or NULL on failure
+ */
+const char *ifconfig_media_get_mode(ifmedia_t media);
+
+/** Retrieve a media mode by its name
+ * @param media        The top level media type whose mode we want
+ * @param name The name of a media mode
+ * @return     The media mode value, or INVALID_IFMEDIA on failure
+ */
+ifmedia_t ifconfig_media_lookup_mode(ifmedia_t media, const char *name);
+
+/** Retrieve an array of media options
+ * @param media        The media for which to obtain the options
+ * @return     Pointer to an array of pointers to option names,
+ *             terminated by a NULL pointer, or simply NULL on failure.
+ *             The caller is responsible for freeing the array but not its
+ *             contents.
+ */
+const char **ifconfig_media_get_options(ifmedia_t media);
+
+/** Retrieve an array of media options by names
+ * @param media        The top level media type whose options we want
+ * @param opts Pointer to an array of string pointers naming options
+ * @param nopts Number of elements in the opts array
+ * @return     Pointer to an array of media options, one for each option named
+ *             in opts.  NULL is returned instead with errno set to ENOMEM if
+ *             allocating the return array fails or EINVAL if media is not
+ *             valid.  A media option in the array will be INVALID_IFMEDIA
+ *             when lookup failed for the option named in that position in
+ *             opts.  The caller is responsible for freeing the array.
+ */
+ifmedia_t *ifconfig_media_lookup_options(ifmedia_t media, const char **opts,
+    size_t nopts);
 
 /** Retrieve the reason the interface is down
  * @param h    An open ifconfig state object
diff --git a/lib/libifconfig/libifconfig_media.c 
b/lib/libifconfig/libifconfig_media.c
index d7ef507604be..e27f5900e3d3 100644
--- a/lib/libifconfig/libifconfig_media.c
+++ b/lib/libifconfig/libifconfig_media.c
@@ -45,6 +45,7 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -53,11 +54,9 @@
 #include "libifconfig.h"
 #include "libifconfig_internal.h"
 
-
-static struct ifmedia_description *get_toptype_desc(int);
-static struct ifmedia_type_to_subtype *get_toptype_ttos(int);
-static struct ifmedia_description *get_subtype_desc(int,
-    struct ifmedia_type_to_subtype *ttos);
+static const struct ifmedia_description *lookup_media_desc(
+    const struct ifmedia_description *, const char *);
+static const struct ifmedia_type_to_subtype *get_toptype_ttos(ifmedia_t);
 
 #define IFM_OPMODE(x)                                                   \
        ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP |             \
@@ -65,74 +64,100 @@ static struct ifmedia_description *get_subtype_desc(int,
        IFM_IEEE80211_MBSS))
 #define IFM_IEEE80211_STA    0
 
-static struct ifmedia_description ifm_type_descriptions[] =
+static const struct ifmedia_description
+    ifm_type_descriptions[] =
     IFM_TYPE_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
+static const struct ifmedia_description
+    ifm_subtype_ethernet_descriptions[] =
     IFM_SUBTYPE_ETHERNET_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_ethernet_aliases[] =
+static const struct ifmedia_description
+    ifm_subtype_ethernet_aliases[] =
     IFM_SUBTYPE_ETHERNET_ALIASES;
 
-static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
+static const struct ifmedia_description
+    ifm_subtype_ethernet_option_descriptions[] =
     IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
+static const struct ifmedia_description
+    ifm_subtype_ieee80211_descriptions[] =
     IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_ieee80211_aliases[] =
+static const struct ifmedia_description
+    ifm_subtype_ieee80211_aliases[] =
     IFM_SUBTYPE_IEEE80211_ALIASES;
 
-static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] =
+static const struct ifmedia_description
+    ifm_subtype_ieee80211_option_descriptions[] =
     IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] =
+static const struct ifmedia_description
+    ifm_subtype_ieee80211_mode_descriptions[] =
     IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] =
+static const struct ifmedia_description
+    ifm_subtype_ieee80211_mode_aliases[] =
     IFM_SUBTYPE_IEEE80211_MODE_ALIASES;
 
-static struct ifmedia_description ifm_subtype_atm_descriptions[] =
+static const struct ifmedia_description
+    ifm_subtype_atm_descriptions[] =
     IFM_SUBTYPE_ATM_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_atm_aliases[] =
+static const struct ifmedia_description
+    ifm_subtype_atm_aliases[] =
     IFM_SUBTYPE_ATM_ALIASES;
 
-static struct ifmedia_description ifm_subtype_atm_option_descriptions[] =
+static const struct ifmedia_description
+    ifm_subtype_atm_option_descriptions[] =
     IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_shared_descriptions[] =
+static const struct ifmedia_description
+    ifm_subtype_shared_descriptions[] =
     IFM_SUBTYPE_SHARED_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_subtype_shared_aliases[] =
+static const struct ifmedia_description
+    ifm_subtype_shared_aliases[] =
     IFM_SUBTYPE_SHARED_ALIASES;
 
-static struct ifmedia_description ifm_shared_option_descriptions[] =
+static const struct ifmedia_description
+    ifm_shared_option_descriptions[] =
     IFM_SHARED_OPTION_DESCRIPTIONS;
 
-static struct ifmedia_description ifm_shared_option_aliases[] =
+static const struct ifmedia_description
+    ifm_shared_option_aliases[] =
     IFM_SHARED_OPTION_ALIASES;
 
+static const struct ifmedia_description *
+lookup_media_desc(const struct ifmedia_description *desc, const char *name)
+{
+
+       for (; desc->ifmt_string != NULL; ++desc)
+               if (strcasecmp(desc->ifmt_string, name) == 0)
+                       return (desc);
+       return (NULL);
+}
+
 struct ifmedia_type_to_subtype {
        struct {
-               struct ifmedia_description *desc;
-               int alias;
+               const struct ifmedia_description *desc;
+               bool alias;
        }
        subtypes[5];
        struct {
-               struct ifmedia_description *desc;
-               int alias;
+               const struct ifmedia_description *desc;
+               bool alias;
        }
        options[4];
        struct {
-               struct ifmedia_description *desc;
-               int alias;
+               const struct ifmedia_description *desc;
+               bool alias;
        }
        modes[3];
 };
 
 /* must be in the same order as IFM_TYPE_DESCRIPTIONS */
-static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] =
+static const struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] =
 {
        {
                {
@@ -192,83 +217,214 @@ static struct ifmedia_type_to_subtype 
ifmedia_types_to_subtypes[] =
        },
 };
 
-static struct ifmedia_description *
-get_toptype_desc(int ifmw)
+static const struct ifmedia_type_to_subtype *
+get_toptype_ttos(ifmedia_t media)
 {
-       struct ifmedia_description *desc;
+       const struct ifmedia_description *desc;
+       const struct ifmedia_type_to_subtype *ttos;
 
-       for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++) {
-               if (IFM_TYPE(ifmw) == desc->ifmt_word) {
-                       break;
-               }
+       for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
+           desc->ifmt_string != NULL; desc++, ttos++) {
+               if (IFM_TYPE(media) == desc->ifmt_word)
+                       return (ttos);
        }
-
-       return (desc);
+       errno = ENOENT;
+       return (NULL);
 }
 
-static struct ifmedia_type_to_subtype *
-get_toptype_ttos(int ifmw)
+const char *
+ifconfig_media_get_type(ifmedia_t media)
 {
-       struct ifmedia_description *desc;
-       struct ifmedia_type_to_subtype *ttos;
+       const struct ifmedia_description *desc;
 
-       for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
-           desc->ifmt_string != NULL; desc++, ttos++) {
-               if (IFM_TYPE(ifmw) == desc->ifmt_word) {
-                       break;
-               }
+       for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; ++desc) {
+               if (IFM_TYPE(media) == desc->ifmt_word)
+                       return (desc->ifmt_string);
        }
+       errno = ENOENT;
+       return (NULL);
+}
+
+ifmedia_t
+ifconfig_media_lookup_type(const char *name)
+{
+       const struct ifmedia_description *desc;
 
-       return (ttos);
+       desc = lookup_media_desc(ifm_type_descriptions, name);
+       return (desc == NULL ? INVALID_IFMEDIA : desc->ifmt_word);
 }
 
-static struct ifmedia_description *
-get_subtype_desc(int ifmw,
-    struct ifmedia_type_to_subtype *ttos)
+const char *
+ifconfig_media_get_subtype(ifmedia_t media)
 {
-       int i;
-       struct ifmedia_description *desc;
+       const struct ifmedia_description *desc;
+       const struct ifmedia_type_to_subtype *ttos;
+
+       ttos = get_toptype_ttos(media);
+       if (ttos == NULL) {
+               errno = EINVAL;
+               return (NULL);
+       }
 
-       for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
-               if (ttos->subtypes[i].alias) {
+       for (size_t i = 0; ttos->subtypes[i].desc != NULL; ++i) {
+               if (ttos->subtypes[i].alias)
                        continue;
-               }
                for (desc = ttos->subtypes[i].desc;
-                   desc->ifmt_string != NULL; desc++) {
-                       if (IFM_SUBTYPE(ifmw) == desc->ifmt_word) {
-                               return (desc);
-                       }
+                   desc->ifmt_string != NULL; ++desc) {
+                       if (IFM_SUBTYPE(media) == desc->ifmt_word)
+                               return (desc->ifmt_string);
                }
        }
-
+       errno = ENOENT;
        return (NULL);
 }
 
-const char *
-ifconfig_media_get_type(int ifmw)
+ifmedia_t
+ifconfig_media_lookup_subtype(ifmedia_t media, const char *name)
 {
-       struct ifmedia_description *desc;
+       const struct ifmedia_description *desc;
+       const struct ifmedia_type_to_subtype *ttos;
 
-       /*int seen_option = 0, i;*/
+       ttos = get_toptype_ttos(media);
+       if (ttos == NULL) {
+               errno = EINVAL;
+               return (INVALID_IFMEDIA);
+       }
 
-       /* Find the top-level interface type. */
-       desc = get_toptype_desc(ifmw);
-       if (desc->ifmt_string == NULL) {
-               return ("<unknown type>");
-       } else {
-               return (desc->ifmt_string);
+       for (size_t i = 0; ttos->subtypes[i].desc != NULL; ++i) {
+               desc = lookup_media_desc(ttos->subtypes[i].desc, name);
+               if (desc != NULL)
+                       return (desc->ifmt_word);
        }
+       errno = ENOENT;
+       return (INVALID_IFMEDIA);
 }
 
 const char *
-ifconfig_media_get_subtype(int ifmw)
+ifconfig_media_get_mode(ifmedia_t media)
 {
-       struct ifmedia_description *desc;
-       struct ifmedia_type_to_subtype *ttos;
+       const struct ifmedia_description *desc;
+       const struct ifmedia_type_to_subtype *ttos;
+
+       ttos = get_toptype_ttos(media);
+       if (ttos == NULL) {
+               errno = EINVAL;
+               return (NULL);
+       }
 
-       ttos = get_toptype_ttos(ifmw);
-       desc = get_subtype_desc(ifmw, ttos);
-       return (desc->ifmt_string);
+       for (size_t i = 0; ttos->modes[i].desc != NULL; ++i) {
+               if (ttos->modes[i].alias)
+                       continue;
+               for (desc = ttos->modes[i].desc;
+                   desc->ifmt_string != NULL; ++desc) {
+                       if (IFM_MODE(media) == desc->ifmt_word)
+                               return (desc->ifmt_string);
+               }
+       }
+       errno = ENOENT;
+       return (NULL);
+}
+
+ifmedia_t
+ifconfig_media_lookup_mode(ifmedia_t media, const char *name)
+{
+       const struct ifmedia_description *desc;
+       const struct ifmedia_type_to_subtype *ttos;
+
+       ttos = get_toptype_ttos(media);
+       if (ttos == NULL) {
+               errno = EINVAL;
+               return (INVALID_IFMEDIA);
+       }
+
+       for (size_t i = 0; ttos->modes[i].desc != NULL; ++i) {
+               desc = lookup_media_desc(ttos->modes[i].desc, name);
+               if (desc != NULL)
+                       return (desc->ifmt_word);
+       }
+       errno = ENOENT;
+       return (INVALID_IFMEDIA);
+}
+
+const char **
+ifconfig_media_get_options(ifmedia_t media)
+{
+       const char **options;
+       const struct ifmedia_description *desc;
+       const struct ifmedia_type_to_subtype *ttos;
+       size_t n;
+
+       ttos = get_toptype_ttos(media);
+       if (ttos == NULL) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
+       n = 0;
+       for (size_t i = 0; ttos->options[i].desc != NULL; ++i) {
+               if (ttos->options[i].alias)
+                       continue;
+               for (desc = ttos->options[i].desc;
+                   desc->ifmt_string != NULL; ++desc) {
+                       if ((media & desc->ifmt_word) != 0)
+                               ++n;
+               }
+       }
+       if (n == 0) {
+               errno = ENOENT;
+               return (NULL);
+       }
+
+       options = calloc(n + 1, sizeof(*options));
+       if (options == NULL)
+               return (NULL);
+
+       options[n] = NULL;
+       n = 0;
+       for (size_t i = 0; ttos->options[i].desc != NULL; ++i) {
+               if (ttos->options[i].alias)
+                       continue;
+               for (desc = ttos->options[i].desc;
+                   desc->ifmt_string != NULL; ++desc) {
+                       if ((media & desc->ifmt_word) != 0) {
+                               options[n] = desc->ifmt_string;
+                               ++n;
+                       }
+               }
+       }
+       return (options);
+}
+
+ifmedia_t *
+ifconfig_media_lookup_options(ifmedia_t media, const char **opts, size_t nopts)
+{
+       ifmedia_t *options;
+       const struct ifmedia_description *desc, *opt;
+       const struct ifmedia_type_to_subtype *ttos;
+
+       assert(opts != NULL);
+       assert(nopts > 0);
+
+       ttos = get_toptype_ttos(media);
+       if (ttos == NULL) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
+       options = calloc(nopts, sizeof(*options));
+       if (options == NULL)
+               return (NULL);
+       (void)memset(options, INVALID_IFMEDIA, nopts * sizeof(ifmedia_t));
+
+       for (size_t i = 0; ttos->options[i].desc != NULL; ++i) {
+               desc = ttos->options[i].desc;
+               for (size_t j = 0; j < nopts; ++j) {
+                       opt = lookup_media_desc(desc, opts[j]);
+                       if (opt != NULL)
+                               options[j] = opt->ifmt_word;
+               }
+       }
+       return (options);
 }
 
 /***************************************************************************
@@ -295,7 +451,6 @@ ifconfig_media_get_mediareq(ifconfig_handle_t *h, const 
char *name,
                h->error.errcode = ENOMEM;
                return (-1);
        }
-       (void)memset(ms, 0, sizeof(*ms));
        (void)strlcpy(ms->ifmr.ifm_name, name, sizeof(ms->ifmr.ifm_name));
 
        /*
@@ -363,36 +518,6 @@ ifconfig_media_get_status(const struct ifmediareq *ifmr)
        }
 }
 
-void
-ifconfig_media_get_options_string(int ifmw, char *buf, size_t buflen)
-{
-       struct ifmedia_type_to_subtype *ttos;
-       struct ifmedia_description *desc;
-       int i, seen_option = 0;
-       size_t len;
-
-       assert(buflen > 0);
-       buf[0] = '\0';
-       ttos = get_toptype_ttos(ifmw);
-       for (i = 0; ttos->options[i].desc != NULL; i++) {
-               if (ttos->options[i].alias) {
-                       continue;
-               }
-               for (desc = ttos->options[i].desc;
-                   desc->ifmt_string != NULL; desc++) {
-                       if (ifmw & desc->ifmt_word) {
-                               if (seen_option++) {
-                                       strlcat(buf, ",", buflen);
-                               }
-                               len = strlcat(buf, desc->ifmt_string, buflen);
-                               assert(len < buflen);
-                               buf += len;
-                               buflen -= len;
-                       }
-               }
-       }
-}
-
 int
 ifconfig_media_get_downreason(ifconfig_handle_t *h, const char *name,
     struct ifdownreason *ifdr)
diff --git a/share/examples/libifconfig/status.c 
b/share/examples/libifconfig/status.c
index 62fd3f35c8de..114cf7e87a68 100644
--- a/share/examples/libifconfig/status.c
+++ b/share/examples/libifconfig/status.c
@@ -406,7 +406,6 @@ print_media(ifconfig_handle_t *lifh, struct ifaddrs *ifa)
         *    tables,  finding an entry with the right media subtype
         */
        struct ifmediareq *ifmr;
-       char opts[80];
 
        if (ifconfig_media_get_mediareq(lifh, ifa->ifa_name, &ifmr) != 0) {
                if (ifconfig_err_errtype(lifh) != OK) {
@@ -419,14 +418,19 @@ print_media(ifconfig_handle_t *lifh, struct ifaddrs *ifa)
        printf("\tmedia: %s %s", ifconfig_media_get_type(ifmr->ifm_current),
            ifconfig_media_get_subtype(ifmr->ifm_current));
        if (ifmr->ifm_active != ifmr->ifm_current) {
+               const char **options;
+
                printf(" (%s", ifconfig_media_get_subtype(ifmr->ifm_active));
-               ifconfig_media_get_options_string(ifmr->ifm_active, opts,
-                   sizeof(opts));
-               if (opts[0] != '\0') {
-                       printf(" <%s>)\n", opts);
+               options = ifconfig_media_get_options(ifmr->ifm_active);
+               if (options != NULL && options[0] != NULL) {
+                       printf(" <%s", options[0]);
+                       for (size_t i = 1; options[i] != NULL; ++i)
+                               printf(",%s", options[i]);
+                       printf(">)\n");
                } else {
                        printf(")\n");
                }
+               free(options);
        } else {
                printf("\n");
        }
@@ -438,15 +442,20 @@ print_media(ifconfig_handle_t *lifh, struct ifaddrs *ifa)
 
        printf("\tsupported media:\n");
        for (i = 0; i < ifmr->ifm_count; i++) {
+               const char **options;
+
                printf("\t\tmedia %s",
                    ifconfig_media_get_subtype(ifmr->ifm_ulist[i]));
-               ifconfig_media_get_options_string(ifmr->ifm_ulist[i], opts,
-                   sizeof(opts));
-               if (opts[0] != '\0') {
-                       printf(" mediaopt %s\n", opts);
+               options = ifconfig_media_get_options(ifmr->ifm_ulist[i]);
+               if (options != NULL && options[0] != NULL) {
+                       printf(" mediaopt %s", options[0]);
+                       for (size_t i = 1; options[i] != NULL; ++i)
+                               printf(",%s", options[i]);
+                       printf("\n");
                } else {
                        printf("\n");
                }
+               free(options);
        }
        free(ifmr);
 }
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to