Commit 0498d9b4 authored by Dan Williams's avatar Dan Williams
Browse files

2006-01-23 Dan Williams <dcbw@redhat.com>

	* src/NetworkManagerAP.[ch]
		- (nm_ap_new_from_ap): copy original essid too
		- (nm_ap_unref): free original essid
		- (nm_ap_get_orig_essid): new function
		- (nm_ap_set_essid): Convert essid to UTF-8 for display and dbus,
			but keep original essid around too

	* src/nm-device-802-11-wireless.c
		- (supplicant_send_network_config): send wpa_supplicant the
			_original_ essid, and not as a string, but in hex.  Should
			allow us to connect to more APs that use wierd character
			encodings for their essids

	* utils/nm-utils.[ch]
		- (nm_utils_essid_to_utf8): make a best-effort to convert the essid
			to UTF-8.  If it's not already valid UTF-8, we check LANG and
			use the current locale as a hint for what encoding the essid
			might be in.  Obviously not 100% accurate, but the idea here is
			that if a user's locale is ex. ja_JP, they are more likely than
			not to be in Japan, where access points will likely be in some
			Japanese encoding.


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1385 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
parent c316f359
2006-01-23 Dan Williams <dcbw@redhat.com>
* src/NetworkManagerAP.[ch]
- (nm_ap_new_from_ap): copy original essid too
- (nm_ap_unref): free original essid
- (nm_ap_get_orig_essid): new function
- (nm_ap_set_essid): Convert essid to UTF-8 for display and dbus,
but keep original essid around too
* src/nm-device-802-11-wireless.c
- (supplicant_send_network_config): send wpa_supplicant the
_original_ essid, and not as a string, but in hex. Should
allow us to connect to more APs that use wierd character
encodings for their essids
* utils/nm-utils.[ch]
- (nm_utils_essid_to_utf8): make a best-effort to convert the essid
to UTF-8. If it's not already valid UTF-8, we check LANG and
use the current locale as a hint for what encoding the essid
might be in. Obviously not 100% accurate, but the idea here is
that if a user's locale is ex. ja_JP, they are more likely than
not to be in Japan, where access points will likely be in some
Japanese encoding.
2006-01-23 Dan Williams <dcbw@redhat.com>
* libnm-util/cipher-private.h
......
......@@ -35,6 +35,7 @@ struct NMAccessPoint
/* Scanned or cached values */
char * essid;
char * orig_essid;
struct ether_addr address;
int mode; /* from IW_MODE_* in wireless.h */
gint8 strength;
......@@ -108,7 +109,10 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *src_ap)
}
if (src_ap->essid && (strlen (src_ap->essid) > 0))
{
new_ap->essid = g_strdup (src_ap->essid);
new_ap->orig_essid = g_strdup (src_ap->orig_essid);
}
memcpy (&new_ap->address, &src_ap->address, sizeof (struct ether_addr));
new_ap->mode = src_ap->mode;
new_ap->strength = src_ap->strength;
......@@ -142,6 +146,7 @@ void nm_ap_unref (NMAccessPoint *ap)
if (ap->refcount == 0)
{
g_free (ap->essid);
g_free (ap->orig_essid);
g_slist_foreach (ap->user_addresses, (GFunc)g_free, NULL);
g_slist_free (ap->user_addresses);
......@@ -179,12 +184,18 @@ void nm_ap_set_timestamp (NMAccessPoint *ap, const GTimeVal *timestamp)
*/
const char * nm_ap_get_essid (const NMAccessPoint *ap)
{
g_assert (ap);
g_return_val_if_fail (ap != NULL, NULL);
return ap->essid;
}
const char * nm_ap_get_orig_essid (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, NULL);
return ap->orig_essid;
}
void nm_ap_set_essid (NMAccessPoint *ap, const char * essid)
{
g_return_if_fail (ap != NULL);
......@@ -192,11 +203,16 @@ void nm_ap_set_essid (NMAccessPoint *ap, const char * essid)
if (ap->essid)
{
g_free (ap->essid);
g_free (ap->orig_essid);
ap->essid = NULL;
ap->orig_essid = NULL;
}
if (essid)
ap->essid = g_strdup (essid);
{
ap->orig_essid = g_strdup (essid);
ap->essid = nm_utils_essid_to_utf8 (essid);
}
}
......
......@@ -42,6 +42,7 @@ void nm_ap_set_timestamp (NMAccessPoint *ap, const GTimeVal *timestamp);
const char * nm_ap_get_essid (const NMAccessPoint *ap);
void nm_ap_set_essid (NMAccessPoint *ap, const char *essid);
/* Get essid in original over-the-air form */
const char * nm_ap_get_orig_essid (const NMAccessPoint *ap);
guint32 nm_ap_get_capabilities (NMAccessPoint *ap);
......
......@@ -41,6 +41,7 @@
#include "nm-activation-request.h"
#include "nm-dbus-nmi.h"
#include "wpa_ctrl.h"
#include "cipher.h"
/* #define IW_QUAL_DEBUG */
......@@ -2486,6 +2487,7 @@ supplicant_send_network_config (NMDevice80211Wireless *self,
const char * essid;
struct wpa_ctrl * ctrl;
gboolean user_created;
char * hex_essid;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (req != NULL, FALSE);
......@@ -2518,9 +2520,10 @@ supplicant_send_network_config (NMDevice80211Wireless *self,
if (nm_device_activation_should_cancel (NM_DEVICE (self)))
goto out;
essid = nm_ap_get_essid (ap);
essid = nm_ap_get_orig_essid (ap);
hex_essid = cipher_bin2hexstr (essid, strlen (essid), -1);
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
"SET_NETWORK %i ssid \"%s\"", nwid, essid))
"SET_NETWORK %i ssid %s", nwid, hex_essid))
goto out;
/* Ad-Hoc ? */
......
......@@ -20,6 +20,7 @@
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
......@@ -130,3 +131,220 @@ gchar *nm_dbus_unescape_object_path (const gchar *object_path)
return utf8_string;
}
struct EncodingTriplet
{
const char *encoding1;
const char *encoding2;
const char *encoding3;
};
struct IsoLangToEncodings
{
const char * lang;
struct EncodingTriplet encodings;
};
/* 5-letter language codes */
static const struct IsoLangToEncodings isoLangEntries5[] =
{
/* Simplified Chinese */
{ "zh_cn", {"euc-cn", "gb2312", "gb18030"} }, /* PRC */
{ "zh_sg", {"euc-cn", "gb2312", "gb18030"} }, /* Singapore */
/* Traditional Chinese */
{ "zh_tw", {"big5", "euc-tw", NULL} }, /* Taiwan */
{ "zh_hk", {"big5", "euc-tw", "big5-hkcs"} },/* Hong Kong */
{ "zh_mo", {"big5", "euc-tw", NULL} }, /* Macau */
/* Table end */
{ NULL, {NULL, NULL, NULL} }
};
/* 2-letter language codes; we don't care about the other 3 in this table */
static const struct IsoLangToEncodings isoLangEntries2[] =
{
/* Japanese */
{ "ja", {"euc-jp", "shift_jis", "iso-2022-jp"} },
/* Korean */
{ "ko", {"euc-kr", "iso-2022-kr", "johab"} },
/* Thai */
{ "th", {"iso-8859-11","windows-874", NULL} },
/* Central European */
{ "hu", {"iso-8859-2", "windows-1250", NULL} }, /* Hungarian */
{ "cs", {"iso-8859-2", "windows-1250", NULL} }, /* Czech */
{ "hr", {"iso-8859-2", "windows-1250", NULL} }, /* Croatian */
{ "pl", {"iso-8859-2", "windows-1250", NULL} }, /* Polish */
{ "ro", {"iso-8859-2", "windows-1250", NULL} }, /* Romanian */
{ "sk", {"iso-8859-2", "windows-1250", NULL} }, /* Slovakian */
{ "sl", {"iso-8859-2", "windows-1250", NULL} }, /* Slovenian */
{ "sh", {"iso-8859-2", "windows-1250", NULL} }, /* Serbo-Croatian */
/* Cyrillic */
{ "ru", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Russian */
{ "be", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Belorussian */
{ "bg", {"windows-1251","koi8-r", "iso-8859-5"} }, /* Bulgarian */
{ "mk", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Macedonian */
{ "sr", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Serbian */
{ "uk", {"koi8-u", "koi8-r", "windows-1251"} }, /* Ukranian */
/* Arabic */
{ "ar", {"iso-8859-6", "windows-1256", NULL} },
/* Balitc */
{ "et", {"iso-8859-4", "windows-1257", NULL} }, /* Estonian */
{ "lt", {"iso-8859-4", "windows-1257", NULL} }, /* Lithuanian */
{ "lv", {"iso-8859-4", "windows-1257", NULL} }, /* Latvian */
/* Greek */
{ "el", {"iso-8859-7", "windows-1253", NULL} },
/* Hebrew */
{ "he", {"iso-8859-8", "windows-1255", NULL} },
{ "iw", {"iso-8859-8", "windows-1255", NULL} },
/* Turkish */
{ "tr", {"iso-8859-9", "windows-1254", NULL} },
/* Table end */
{ NULL, {NULL, NULL, NULL} }
};
static GHashTable * langToEncodings5 = NULL;
static GHashTable * langToEncodings2 = NULL;
static void
init_lang_to_encodings_hash (void)
{
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
g_static_mutex_lock (&mutex);
if (G_UNLIKELY (!langToEncodings5 || !langToEncodings2))
{
const struct IsoLangToEncodings * enc = &isoLangEntries5[0];
/* Five-letter codes */
langToEncodings5 = g_hash_table_new (g_str_hash, g_str_equal);
while (enc->lang)
{
g_hash_table_insert (langToEncodings5, (gpointer) enc->lang,
(gpointer) &enc->encodings);
enc++;
}
/* Two-letter codes */
enc = &isoLangEntries2[0];
langToEncodings2 = g_hash_table_new (g_str_hash, g_str_equal);
while (enc->lang)
{
g_hash_table_insert (langToEncodings2, (gpointer) enc->lang,
(gpointer) &enc->encodings);
enc++;
}
}
g_static_mutex_unlock (&mutex);
}
static gboolean
get_encodings_for_lang (const char *lang,
char **encoding1,
char **encoding2,
char **encoding3)
{
struct EncodingTriplet * encodings;
gboolean success = FALSE;
char * tmp_lang;
g_return_val_if_fail (lang != NULL, FALSE);
g_return_val_if_fail (encoding1 != NULL, FALSE);
g_return_val_if_fail (encoding2 != NULL, FALSE);
g_return_val_if_fail (encoding3 != NULL, FALSE);
*encoding1 = "iso-8859-1";
*encoding2 = "windows-1251";
*encoding3 = NULL;
init_lang_to_encodings_hash ();
tmp_lang = g_strdup (lang);
if ((encodings = g_hash_table_lookup (langToEncodings5, tmp_lang)))
{
*encoding1 = (char *) encodings->encoding1;
*encoding2 = (char *) encodings->encoding2;
*encoding3 = (char *) encodings->encoding3;
success = TRUE;
}
/* Truncate tmp_lang to length of 2 */
if (strlen (tmp_lang) > 2)
tmp_lang[2] = '\0';
if (!success && (encodings = g_hash_table_lookup (langToEncodings2, tmp_lang)))
{
*encoding1 = (char *) encodings->encoding1;
*encoding2 = (char *) encodings->encoding2;
*encoding3 = (char *) encodings->encoding3;
success = TRUE;
}
g_free (tmp_lang);
return success;
}
char *
nm_utils_essid_to_utf8 (const char *orig_essid)
{
char *new_essid = NULL;
g_return_val_if_fail (orig_essid != NULL, NULL);
if (g_utf8_validate (orig_essid, -1, NULL))
new_essid = g_strdup (orig_essid);
else
{
char * lang;
char *e1 = NULL, *e2 = NULL, *e3 = NULL;
/* Even if the local encoding is UTF-8, LANG may give
* us a clue as to what encoding ESSIDs are more likely to be in.
*/
g_get_charset ((const char **)(&e1));
if ((lang = getenv ("LANG")))
{
char * dot;
lang = g_ascii_strdown (lang, -1);
if ((dot = strchr (lang, '.')))
*dot = '\0';
get_encodings_for_lang (lang, &e1, &e2, &e3);
g_free (lang);
}
new_essid = g_convert (orig_essid, -1, "UTF-8", e1, NULL, NULL, NULL);
if (!new_essid && e2)
{
new_essid = g_convert (orig_essid, -1, "UTF-8", e2,
NULL, NULL, NULL);
}
if (!new_essid && e3)
{
new_essid = g_convert (orig_essid, -1, "UTF-8", e3,
NULL, NULL, NULL);
}
if (!new_essid)
{
new_essid = g_convert_with_fallback (orig_essid, -1, "UTF-8", e1,
"?", NULL, NULL, NULL);
}
}
return new_essid;
}
......@@ -128,4 +128,6 @@ G_STMT_START \
gchar *nm_dbus_escape_object_path (const gchar *utf8_string);
gchar *nm_dbus_unescape_object_path (const gchar *object_path);
char *nm_utils_essid_to_utf8 (const char *orig_essid);
#endif /* NM_UTILS_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment