Index: sbin/ifconfig/ifconfig.c =================================================================== --- sbin/ifconfig/ifconfig.c +++ sbin/ifconfig/ifconfig.c @@ -70,6 +70,7 @@ #ifdef JAIL #include #endif +#include #include #include #include @@ -424,6 +425,8 @@ f_inet = f_inet6 = f_ether = f_addr = NULL; matchgroup = nogroup = NULL; + setlocale(LC_CTYPE, ""); + lifh = ifconfig_open(); if (lifh == NULL) err(EXIT_FAILURE, "ifconfig_open"); Index: sbin/ifconfig/ifieee80211.c =================================================================== --- sbin/ifconfig/ifieee80211.c +++ sbin/ifconfig/ifieee80211.c @@ -91,8 +91,8 @@ #include #include #include /* NB: for offsetof */ -#include #include +#include #include "ifconfig.h" @@ -3439,45 +3439,58 @@ } /* - * Copy the ssid string contents into buf, truncating to fit. If the - * ssid is entirely printable then just copy intact. Otherwise convert - * to hexadecimal. If the result is truncated then replace the last - * three characters with "...". + * Copy the SSID string contents into the buffer, truncating to fit. + * If the SSID is entirely printable then just copy intact, otherwise + * convert to hexadecimal (in this case, if the result is truncated + * then replace the last three characters with "..."). */ static int -copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, size_t essid_len) +copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, + size_t essid_len, int *vis_essid_len) { - const u_int8_t *p; + const u_int8_t *cur, *end; size_t maxlen; - u_int i; + wchar_t wc; + int i, adv, vw; if (essid_len > bufsize) maxlen = bufsize; else maxlen = essid_len; - /* determine printable or not */ - for (i = 0, p = essid; i < maxlen; i++, p++) { - if (*p < ' ' || *p > 0x7e) - break; - } - if (i != maxlen) { /* not printable, print as hex */ - if (bufsize < 3) - return 0; - strlcpy(buf, "0x", bufsize); + /* + * Determine if SSID is printable or not, and calculate its + * visible width to be able to align CJK characters against + * alphabetic ones correctly, if needed. + */ + cur = essid; + end = essid + maxlen; + for (vw = 0; end - cur > 0; cur += adv) { + adv = mbtowc(&wc, cur, end - cur); + if (adv < 1) + goto nonprintable; + i = wcwidth(wc); + if (i < 1) + goto nonprintable; + vw += i; + } + memcpy(buf, essid, maxlen); + if (vis_essid_len != NULL) + *vis_essid_len = vw; + return (maxlen); + nonprintable: + if (bufsize < 3) + return 0; + strcpy(buf, "0x"); + bufsize -= 2; + for (i = 0; i < maxlen && bufsize >= 2; i++) { + sprintf(&buf[2 + 2 * i], "%02x", essid[i]); bufsize -= 2; - p = essid; - for (i = 0; i < maxlen && bufsize >= 2; i++) { - sprintf(&buf[2+2*i], "%02x", p[i]); - bufsize -= 2; - } - if (i != essid_len) - memcpy(&buf[2+2*i-3], "...", 3); - } else { /* printable, truncate as needed */ - memcpy(buf, essid, maxlen); - if (maxlen != essid_len) - memcpy(&buf[maxlen-3], "...", 3); } - return maxlen; + if (i != essid_len) + memcpy(&buf[2 + 2 * i - 3], "...", 3); + if (vis_essid_len != NULL) + *vis_essid_len = maxlen; + return (maxlen); } static void @@ -3485,7 +3498,8 @@ { char ssid[2*IEEE80211_NWID_LEN+1]; - printf("%s<%.*s>", tag, copy_essid(ssid, maxlen, ie+2, ie[1]), ssid); + printf("%s<%.*s>", tag, copy_essid(ssid, maxlen, ie+2, ie[1], + NULL), ssid); } static void @@ -3744,6 +3758,7 @@ do { const struct ieee80211req_scan_result *sr; const uint8_t *vp, *idp; + int length, visible_length; sr = (const struct ieee80211req_scan_result *) cp; vp = cp + sr->isr_ie_off; @@ -3754,9 +3769,11 @@ idp = vp; idlen = sr->isr_ssid_len; } + length = copy_essid(ssid, IEEE80211_NWID_LEN, idp, idlen, + &visible_length); printf("%-*.*s %s %3d %3dM %4d:%-4d %4d %-4.4s" - , IEEE80211_NWID_LEN - , copy_essid(ssid, IEEE80211_NWID_LEN, idp, idlen) + , IEEE80211_NWID_LEN + length - visible_length + , length , ssid , ether_ntoa((const struct ether_addr *) sr->isr_bssid) , ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags) @@ -5681,7 +5698,6 @@ i = 0; hasspc = 0; - setlocale(LC_CTYPE, ""); utf8 = strncmp("UTF-8", nl_langinfo(CODESET), 5) == 0; for (; i < len; i++) {