> Date: Sat, 22 Feb 2020 12:44:12 +0100
> From: Stefan Sperling <s...@stsp.name>
> 
> This is another attempt at improving usability with non-ASCII network IDs.
> 
> Previous attempts have been rejected in part because entering UTF-8 strings
> is difficult to do for Americans and, to a lesser extent, Canadians.
> 
> It occurred to me that the real issue might have been that previous attempts
> were erasing the hex string representation in favour of UTF-8, instead of
> amending the hex string with a human-readable representation of that string.
> 
> With the diff below ifconfig shows both representations, provided the UTF-8
> locale is active and the string can be successfully decoded, and fits NWID
> length restrictions, and contains printable Unicode only.
> 
> We still need to enter a hex ID to use a network, but at least it becomes
> much easier to tell which one to use.
> 
> Before:
> 
> $ ifconfig iwm0 scan
> iwm0: flags=808843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,AUTOCONF4> mtu 1500
> [...]
>               nwid 0x6162616374c3a97269c3a96d69717565 chan 4 bssid 
> xx:xx:xx:xx:xx:xx 68% HT-MCS7 privacy,short_preamble,short_slottime,wpa2 
>               nwid 0x00000000000000000000000000000000000000000000 chan 6 
> bssid xx:xx:xx:xx:xx:xx 25% HT-MCS15 privacy,short_slottime,wpa2 
> 
> 
> After:
> 
> $ ifconfig iwm0 scan iwm0: 
> flags=808843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,AUTOCONF4> mtu 1500
> [...]
>               nwid 0x6162616374c3a97269c3a96d69717565 ("abactériémique") chan 
> 4 bssid xx:xx:xx:xx:xx:xx 68% HT-MCS7 
> privacy,short_preamble,short_slottime,wpa2 
>               nwid 0x00000000000000000000000000000000000000000000 chan 6 
> bssid xx:xx:xx:xx:xx:xx 25% HT-MCS15 privacy,short_slottime,wpa2 
> 
> 
> I'm making the man page point out that 'ifconfig nwid' accepts only
> *printable ASCII* strings or hex. Based on that it should be clear what
> the user needs to do with information shown in the scan result list.
> 
> This feature also works with 'ifconfig joinlist'. While here fix a bug
> where non-ASCII IDs on this list were improperly truncated to 32 columns
> when displayed. The hexstring can be up to 66 colomns in length so capping
> joinlist SSIDs to IEEE80211_NWID_LEN - 1 columns is wrong.
> A human-readable representation needs additional space to be displayed.
> 
> Since print_string() and len_string() are only used with NWIDs nowadays I
> am renaming them to print_nwid() and width_nwid() (the latter function is
> being used to compute a display width, not a string length in bytes).
> 
> Is this acceptable or are there objections to the idea?

IMHO it is a bad idea to make the output of ifconfig locale-dependent.

> diff c20bd74017ceeadb2db0f78a352ed1f1e2b77c2b /usr/src
> blob - 3fb0780ba7cf1333894f5c3485a95e71885fbd6d
> file + sbin/ifconfig/ifconfig.8
> --- sbin/ifconfig/ifconfig.8
> +++ sbin/ifconfig/ifconfig.8
> @@ -972,8 +972,9 @@ list if they are found during a scan.
>  .Pp
>  The
>  .Ar id
> -can either be any text string up to 32 characters in length,
> -or a series of hexadecimal digits up to 64 digits.
> +can either be a printable ASCII string up to 32 characters in length,
> +or a series of hexadecimal digits up to 64 digits preceded by
> +.Dq 0x .
>  If
>  .Ar id
>  is the empty string
> @@ -1077,6 +1078,12 @@ Remove specified flag.
>  .It Cm nwid Ar id
>  Connect to the network with NWID/ESSID
>  .Ar id .
> +The
> +.Ar id
> +can either be a printable ASCII string up to 32 characters in length,
> +or a series of hexadecimal digits up to 64 digits preceded by
> +.Dq 0x .
> +.Pp
>  Unlike
>  .Cm join ,
>  the
> blob - e1dc9dbb07bf109c3ec7f5fd4d851a7dbb5692f1
> file + sbin/ifconfig/ifconfig.c
> --- sbin/ifconfig/ifconfig.c
> +++ sbin/ifconfig/ifconfig.c
> @@ -110,6 +110,12 @@
>  #ifndef SMALL
>  #include <dev/usb/mbim.h>
>  #include <dev/usb/if_umb.h>
> +
> +/* UTF-8 support */
> +#include <langinfo.h>
> +#include <locale.h>
> +#include <wctype.h>
> +#include <wchar.h>
>  #endif /* SMALL */
>  
>  #include "ifconfig.h"
> @@ -156,6 +162,7 @@ struct    ifaliasreq      addreq;
>  
>  int  wconfig = 0;
>  int  wcwconfig = 0;
> +int  is_utf8_locale = 0;
>  #endif /* SMALL */
>  
>  char ifname[IFNAMSIZ];
> @@ -654,8 +661,9 @@ const char *get_linkstate(int, int);
>  void status(int, struct sockaddr_dl *, int);
>  __dead void  usage(void);
>  const char *get_string(const char *, const char *, u_int8_t *, int *);
> -int  len_string(const u_int8_t *, int);
> -int  print_string(const u_int8_t *, int);
> +int  utf8_nwid(const u_int8_t *, int);
> +int  width_nwid(const u_int8_t *, int);
> +int  print_nwid(const u_int8_t *, int);
>  char *sec2str(time_t);
>  
>  const char *get_media_type_string(uint64_t);
> @@ -731,6 +739,10 @@ main(int argc, char *argv[])
>       int found_rulefile = 0;
>       int i;
>  
> +#ifndef SMALL
> +     setlocale(LC_CTYPE, "");
> +     is_utf8_locale = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0);
> +#endif
>       /* If no args at all, print all interfaces.  */
>       if (argc < 2) {
>               /* no filesystem visibility */
> @@ -1678,9 +1690,44 @@ get_string(const char *val, const char *sep, u_int8_t 
>       return val;
>  }
>  
> +/*
> + * Attempt to create a human-readable representation of an NWID in UTF-8.
> + * Return the width of the representation (amount of terminal columns used)
> + * and optionally print to stdout.
> + */
>  int
> -len_string(const u_int8_t *buf, int len)
> +utf8_nwid(const u_int8_t *buf, int print_nwid)
>  {
> +#ifndef SMALL
> +     wchar_t wcid[IEEE80211_NWID_LEN + 1];
> +     size_t nwc;
> +     int width, i;
> +
> +     if (!is_utf8_locale)
> +             return 0;
> +
> +     nwc = mbstowcs(wcid, buf, IEEE80211_NWID_LEN);
> +     if (nwc == (size_t)-1 || nwc > IEEE80211_NWID_LEN)
> +             return 0;
> +     wcid[nwc] = L'\0';
> +     for (i = 0; i < nwc; i++) {
> +             if (!iswprint(wcid[i]))
> +                     return 0;
> +     }
> +     width = wcswidth(wcid, IEEE80211_NWID_LEN);
> +     if (width == 0 || width == -1)
> +             return 0;
> +     if (print_nwid)
> +             printf(" (\"%ls\")", wcid);
> +     return width + 5;
> +#else
> +     return 0;       
> +#endif
> +}
> +
> +int
> +width_nwid(const u_int8_t *buf, int len)
> +{
>       int i = 0, hasspc = 0;
>  
>       if (len < 2 || buf[0] != '0' || tolower(buf[1]) != 'x') {
> @@ -1698,11 +1745,11 @@ len_string(const u_int8_t *buf, int len)
>               else
>                       return len;
>       } else
> -             return (len * 2) + 2;
> +             return (len * 2) + 2 + utf8_nwid(buf, 0);
>  }
>  
>  int
> -print_string(const u_int8_t *buf, int len)
> +print_nwid(const u_int8_t *buf, int len)
>  {
>       int i = 0, hasspc = 0;
>  
> @@ -1727,7 +1774,7 @@ print_string(const u_int8_t *buf, int len)
>               printf("0x");
>               for (i = 0; i < len; i++)
>                       printf("%02x", buf[i]);
> -             return (len * 2) + 2;
> +             return (len * 2) + 2 + utf8_nwid(buf, 1);
>       }
>  }
>  
> @@ -2440,7 +2487,7 @@ ieee80211_status(void)
>                       fputs(" join ", stdout);
>               else
>                       fputs(" nwid ", stdout);
> -             print_string(nwid.i_nwid, len);
> +             print_nwid(nwid.i_nwid, len);
>       }
>  
>       if (ichan == 0 && channel.i_channel != 0 &&
> @@ -2571,18 +2618,16 @@ join_status(void)
>  
>       maxlen = 0;
>       for (i = 0; i < ja.ja_nodes; i++) {
> -             len = len_string(jn[i].i_nwid, jn[i].i_len);
> +             len = width_nwid(jn[i].i_nwid, jn[i].i_len);
>               if (len > maxlen)
>                       maxlen = len;
>       }
> -     if (maxlen > IEEE80211_NWID_LEN)
> -             maxlen = IEEE80211_NWID_LEN - 1;
>  
>       for (i = 0; i < ja.ja_nodes; i++) {
>               printf("\t      ");
>               if (jn[i].i_len > IEEE80211_NWID_LEN)
>                       jn[i].i_len = IEEE80211_NWID_LEN;
> -             len = print_string(jn[i].i_nwid, jn[i].i_len);
> +             len = print_nwid(jn[i].i_nwid, jn[i].i_len);
>               printf("%-*s", maxlen - len, " ");
>               if (jn[i].i_flags) {
>                       const char *sep;
> @@ -2717,7 +2762,7 @@ ieee80211_printnode(struct ieee80211_nodereq *nr)
>               if (len > IEEE80211_NWID_LEN)
>                       len = IEEE80211_NWID_LEN;
>               printf("nwid ");
> -             print_string(nr->nr_nwid, len);
> +             print_nwid(nr->nr_nwid, len);
>               putchar(' ');
>  
>               printf("chan %u ", nr->nr_channel);
> 
> 

Reply via email to