Index: libpurple/protocols/nateon/nateon.c
===================================================================
--- libpurple/protocols/nateon/nateon.c	(revision 57)
+++ libpurple/protocols/nateon/nateon.c	(working copy)
@@ -21,7 +21,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-//#define PHOTO_SUPPORT 1
+#define PHOTO_SUPPORT 1
 
 #include <glib.h>
 
@@ -44,36 +44,36 @@
 #include "sync.h"
 //#include "slplink.h"
 
-//#if PHOTO_SUPPORT
-//#include "imgstore.h"
-//#endif
-//
+#if PHOTO_SUPPORT
+#include "imgstore.h"
+#endif
+
 //typedef struct
 //{
 //	PurpleConnection *gc;
 //	const char *passport;
 //
 //} NateonMobileData;
-//
-//typedef struct
-//{
-//	PurpleConnection *gc;
-//	char *name;
-//
-//} NateonGetInfoData;
-//
-//typedef struct
-//{
-//	NateonGetInfoData *info_data;
-//	char *stripped;
-//	char *url_buffer;
-//	GString *s;
-//	char *photo_url_text;
-//	char *tooltip_text;
-//	const char *title;
-//
-//} NateonGetInfoStepTwoData;
 
+typedef struct
+{
+	PurpleConnection *gc;
+	char *name;
+	char *id;
+
+} NateonGetInfoData;
+
+typedef struct
+{
+	NateonGetInfoData *info_data;
+	char *stripped;
+	char *url_buffer;
+	PurpleNotifyUserInfo *user_info;
+	char *photo_url_text;
+	char *photo_frame_url_text;
+
+} NateonGetInfoStepTwoData;
+
 static const char *nateon_normalize(const PurpleAccount *account, const char *str)
 {
 	static char buf[BUF_LEN];
@@ -1334,594 +1338,314 @@
 //		nateon_cmdproc_send(cmdproc, "RMG", "%d", group_id);
 //	}
 //}
-//
-//static char *
-//nateon_tooltip_info_text(NateonGetInfoData *info_data)
-//{
-//	GString *s;
-//	PurpleBuddy *b;
-//
-//	s = g_string_sized_new(80); /* wild guess */
-//
-//	b = purple_find_buddy(purple_connection_get_account(info_data->gc),
-//						info_data->name);
-//
-//	if (b)
-//	{
-//		PurplePresence *presence;
-//		GString *str = g_string_new("");
-//		char *tmp;
-//
-//		presence = purple_buddy_get_presence(b);
-//
-//		if (b->alias && b->alias[0])
-//		{
-//			char *aliastext = g_markup_escape_text(b->alias, -1);
-//			g_string_append_printf(s, _("<b>Alias:</b> %s<br>"), aliastext);
-//			g_free(aliastext);
-//		}
-//
-//		if (b->server_alias)
-//		{
-//			char *nicktext = g_markup_escape_text(b->server_alias, -1);
-//			g_string_append_printf(s, _("<b>%s:</b> "), _("Nickname"));
-//			g_string_append_printf(s, "<font sml=\"nateon\">%s</font><br>",
-//					nicktext);
-//			g_free(nicktext);
-//		}
-//
-//		nateon_tooltip_text(b, str, TRUE);
-//		tmp = purple_strreplace((*str->str == '\n' ? str->str + 1 : str->str),
-//							  "\n", "<br>");
-//		g_string_free(str, TRUE);
-//		g_string_append_printf(s, "%s<br>", tmp);
-//		g_free(tmp);
-//	}
-//
-//	return g_string_free(s, FALSE);
-//}
-//
-//#if PHOTO_SUPPORT
-//
-//static char *
-//nateon_get_photo_url(const char *url_text)
-//{
-//	char *p, *q;
-//
-//	if ((p = strstr(url_text, " contactparams:photopreauthurl=\"")) != NULL)
-//	{
-//		p += strlen(" contactparams:photopreauthurl=\"");
-//	}
-//
-//	if (p && (strncmp(p, "http://", 8) == 0) && ((q = strchr(p, '"')) != NULL))
-//			return g_strndup(p, q - p);
-//
-//	return NULL;
-//}
-//
-//static void nateon_got_photo(void *data, const char *url_text, size_t len);
-//
-//#endif
-//
-//#if 0
-//static char *nateon_info_date_reformat(const char *field, size_t len)
-//{
-//	char *tmp = g_strndup(field, len);
-//	time_t t = purple_str_to_time(tmp, FALSE, NULL, NULL, NULL);
-//
-//	g_free(tmp);
-//	return g_strdup(purple_date_format_short(localtime(&t)));
-//}
-//#endif
-//
-//#define NATEON_GOT_INFO_GET_FIELD(a, b) \
-//	found = purple_markup_extract_info_field(stripped, stripped_len, s, \
-//			"\n" a "\t", 0, "\n", 0, "Undisclosed", b, 0, NULL, NULL); \
-//	if (found) \
-//		sect_info = TRUE;
-//
-//static void
-//nateon_got_info(void *data, const char *url_text, size_t len)
-//{
-//	NateonGetInfoData *info_data = (NateonGetInfoData *)data;
-//	char *stripped, *p, *q;
-//	char buf[1024];
-//	char *tooltip_text;
-//	char *user_url = NULL;
-//	gboolean found;
-//	gboolean has_info = FALSE;
-//	gboolean sect_info = FALSE;
-//	const char* title = NULL;
-//	char *url_buffer;
-//	char *personal = NULL;
-//	char *business = NULL;
-//	GString *s, *s2;
-//	int stripped_len;
-//#if PHOTO_SUPPORT
-//	char *photo_url_text = NULL;
-//	NateonGetInfoStepTwoData *info2_data = NULL;
-//#endif
-//
-//	purple_debug_info("nateon", "In nateon_got_info\n");
-//
-//	/* Make sure the connection is still valid */
-//	if (g_list_find(purple_connections_get_all(), info_data->gc) == NULL)
-//	{
-//		purple_debug_warning("nateon", "invalid connection. ignoring buddy info.\n");
-//		g_free(info_data->name);
-//		g_free(info_data);
-//		return;
-//	}
-//
-//	tooltip_text = nateon_tooltip_info_text(info_data);
-//	title = _("NATEON Profile");
-//
-//	if (url_text == NULL || strcmp(url_text, "") == 0)
-//	{
-//		g_snprintf(buf, 1024, "<html><body>%s<b>%s</b></body></html>",
-//				tooltip_text, _("Error retrieving profile"));
-//
-//		purple_notify_userinfo(info_data->gc, info_data->name, buf, NULL, NULL);
-//
-//		g_free(tooltip_text);
-//		return;
-//	}
-//
-//	url_buffer = g_strdup(url_text);
-//
-//	/* If they have a homepage link, NATEON masks it such that we need to
-//	 * fetch the url out before purple_markup_strip_html() nukes it */
-//	/* I don't think this works with the new spaces profiles - Stu 3/2/06 */
-//	if ((p = strstr(url_text,
-//			"Take a look at my </font><A class=viewDesc title=\"")) != NULL)
-//	{
-//		p += 50;
-//
-//		if ((q = strchr(p, '"')) != NULL)
-//			user_url = g_strndup(p, q - p);
-//	}
-//
-//	/*
-//	 * purple_markup_strip_html() doesn't strip out character entities like &nbsp;
-//	 * and &#183;
-//	 */
-//	while ((p = strstr(url_buffer, "&nbsp;")) != NULL)
-//	{
-//		*p = ' '; /* Turn &nbsp;'s into ordinary blanks */
-//		p += 1;
-//		memmove(p, p + 5, strlen(p + 5));
-//		url_buffer[strlen(url_buffer) - 5] = '\0';
-//	}
-//
-//	while ((p = strstr(url_buffer, "&#183;")) != NULL)
-//	{
-//		memmove(p, p + 6, strlen(p + 6));
-//		url_buffer[strlen(url_buffer) - 6] = '\0';
-//	}
-//
-//	/* Nuke the nasty \r's that just get in the way */
-//	purple_str_strip_char(url_buffer, '\r');
-//
-//	/* NATEON always puts in &#39; for apostrophes...replace them */
-//	while ((p = strstr(url_buffer, "&#39;")) != NULL)
-//	{
-//		*p = '\'';
-//		memmove(p + 1, p + 5, strlen(p + 5));
-//		url_buffer[strlen(url_buffer) - 4] = '\0';
-//	}
-//
-//	/* Nuke the html, it's easier than trying to parse the horrid stuff */
-//	stripped = purple_markup_strip_html(url_buffer);
-//	stripped_len = strlen(stripped);
-//
-//	purple_debug_misc("nateon", "stripped = %p\n", stripped);
-//	purple_debug_misc("nateon", "url_buffer = %p\n", url_buffer);
-//
-//	/* Gonna re-use the memory we've already got for url_buffer */
-//	/* No we're not. */
-//	s = g_string_sized_new(strlen(url_buffer));
-//	s2 = g_string_sized_new(strlen(url_buffer));
-//
-//	/* Extract their Name and put it in */
-//	NATEON_GOT_INFO_GET_FIELD("Name", _("Name"))
-//
-//	/* General */
-//	NATEON_GOT_INFO_GET_FIELD("Nickname", _("Nickname"));
-//	NATEON_GOT_INFO_GET_FIELD("Age", _("Age"));
-//	NATEON_GOT_INFO_GET_FIELD("Gender", _("Gender"));
-//	NATEON_GOT_INFO_GET_FIELD("Occupation", _("Occupation"));
-//	NATEON_GOT_INFO_GET_FIELD("Location", _("Location"));
-//
-//	/* Extract their Interests and put it in */
-//	found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//			"\nInterests\t", 0, " (/default.aspx?page=searchresults", 0,
-//			"Undisclosed", _("Hobbies and Interests") /* _("Interests") */,
-//			0, NULL, NULL);
-//
-//	if (found)
-//		sect_info = TRUE;
-//
-//	NATEON_GOT_INFO_GET_FIELD("More about me", _("A Little About Me"));
-//
-//	if (sect_info)
-//	{
-//		/* trim off the trailing "<br>\n" */
-//		g_string_truncate(s, strlen(s->str) - 5);
-//		g_string_append_printf(s2, _("%s<b>General</b><br>%s"),
-//							   (*tooltip_text) ? "<hr>" : "", s->str);
-//		s = g_string_truncate(s, 0);
-//		has_info = TRUE;
-//		sect_info = FALSE;
-//	}
-//
-//
-//	/* Social */
-//	NATEON_GOT_INFO_GET_FIELD("Marital status", _("Marital Status"));
-//	NATEON_GOT_INFO_GET_FIELD("Interested in", _("Interests"));
-//	NATEON_GOT_INFO_GET_FIELD("Pets", _("Pets"));
-//	NATEON_GOT_INFO_GET_FIELD("Hometown", _("Hometown"));
-//	NATEON_GOT_INFO_GET_FIELD("Places lived", _("Places Lived"));
-//	NATEON_GOT_INFO_GET_FIELD("Fashion", _("Fashion"));
-//	NATEON_GOT_INFO_GET_FIELD("Humor", _("Humor"));
-//	NATEON_GOT_INFO_GET_FIELD("Music", _("Music"));
-//	NATEON_GOT_INFO_GET_FIELD("Favorite quote", _("Favorite Quote"));
-//
-//	if (sect_info)
-//	{
-//		g_string_append_printf(s2, _("%s<b>Social</b><br>%s"), has_info ? "<br><hr>" : "", s->str);
-//		s = g_string_truncate(s, 0);
-//		has_info = TRUE;
-//		sect_info = FALSE;
-//	}
-//
-//	/* Contact Info */
-//	/* Personal */
-//	NATEON_GOT_INFO_GET_FIELD("Name", _("Name"));
-//	NATEON_GOT_INFO_GET_FIELD("Significant other", _("Significant Other"));
-//	NATEON_GOT_INFO_GET_FIELD("Home phone", _("Home Phone"));
-//	NATEON_GOT_INFO_GET_FIELD("Home phone 2", _("Home Phone 2"));
-//	NATEON_GOT_INFO_GET_FIELD("Home address", _("Home Address"));
-//	NATEON_GOT_INFO_GET_FIELD("Personal Mobile", _("Personal Mobile"));
-//	NATEON_GOT_INFO_GET_FIELD("Home fax", _("Home Fax"));
-//	NATEON_GOT_INFO_GET_FIELD("Personal e-mail", _("Personal E-Mail"));
-//	NATEON_GOT_INFO_GET_FIELD("Personal IM", _("Personal IM"));
-//	NATEON_GOT_INFO_GET_FIELD("Birthday", _("Birthday"));
-//	NATEON_GOT_INFO_GET_FIELD("Anniversary", _("Anniversary"));
-//	NATEON_GOT_INFO_GET_FIELD("Notes", _("Notes"));
-//
-//	if (sect_info)
-//	{
-//		personal = g_strdup_printf(_("<br><b>Personal</b><br>%s"), s->str);
-//		s = g_string_truncate(s, 0);
-//		sect_info = FALSE;
-//	}
-//
-//	/* Business */
-//	NATEON_GOT_INFO_GET_FIELD("Name", _("Name"));
-//	NATEON_GOT_INFO_GET_FIELD("Job title", _("Job Title"));
-//	NATEON_GOT_INFO_GET_FIELD("Company", _("Company"));
-//	NATEON_GOT_INFO_GET_FIELD("Department", _("Department"));
-//	NATEON_GOT_INFO_GET_FIELD("Profession", _("Profession"));
-//	NATEON_GOT_INFO_GET_FIELD("Work phone 1", _("Work Phone"));
-//	NATEON_GOT_INFO_GET_FIELD("Work phone 2", _("Work Phone 2"));
-//	NATEON_GOT_INFO_GET_FIELD("Work address", _("Work Address"));
-//	NATEON_GOT_INFO_GET_FIELD("Work mobile", _("Work Mobile"));
-//	NATEON_GOT_INFO_GET_FIELD("Work pager", _("Work Pager"));
-//	NATEON_GOT_INFO_GET_FIELD("Work fax", _("Work Fax"));
-//	NATEON_GOT_INFO_GET_FIELD("Work e-mail", _("Work E-Mail"));
-//	NATEON_GOT_INFO_GET_FIELD("Work IM", _("Work IM"));
-//	NATEON_GOT_INFO_GET_FIELD("Start date", _("Start Date"));
-//	NATEON_GOT_INFO_GET_FIELD("Notes", _("Notes"));
-//
-//	if (sect_info)
-//	{
-//		business = g_strdup_printf(_("<br><b>Business</b><br>%s"), s->str);
-//		s = g_string_truncate(s, 0);
-//		sect_info = FALSE;
-//	}
-//
-//	if ((personal != NULL) || (business != NULL))
-//	{
-//		/* trim off the trailing "<br>\n" */
-//		g_string_truncate(s, strlen(s->str) - 5);
-//
-//		has_info = TRUE;
-//		g_string_append_printf(s2, _("<hr><b>Contact Info</b>%s%s"),
-//							   personal ? personal : "",
-//							   business ? business : "");
-//	}
-//
-//	g_free(personal);
-//	g_free(business);
-//	g_string_free(s, TRUE);
-//	s = s2;
-//
-//#if 0 /* these probably don't show up any more */
-//	/*
-//	 * The fields, 'A Little About Me', 'Favorite Things', 'Hobbies
-//	 * and Interests', 'Favorite Quote', and 'My Homepage' may or may
-//	 * not appear, in any combination. However, they do appear in
-//	 * certain order, so we can successively search to pin down the
-//	 * distinct values.
-//	 */
-//
-//	/* Check if they have A Little About Me */
-//	found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//			" A Little About Me \n\n", 0, "Favorite Things", '\n', NULL,
-//			_("A Little About Me"), 0, NULL, NULL);
-//
-//	if (!found)
-//	{
-//		found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" A Little About Me \n\n", 0, "Hobbies and Interests", '\n',
-//				NULL, _("A Little About Me"), 0, NULL, NULL);
-//	}
-//
-//	if (!found)
-//	{
-//		found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" A Little About Me \n\n", 0, "Favorite Quote", '\n', NULL,
-//				_("A Little About Me"), 0, NULL, NULL);
-//	}
-//
-//	if (!found)
-//	{
-//		found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" A Little About Me \n\n", 0, "My Homepage \n\nTake a look",
-//				'\n',
-//				NULL, _("A Little About Me"), 0, NULL, NULL);
-//	}
-//
-//	if (!found)
-//	{
-//		purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" A Little About Me \n\n", 0, "last updated", '\n', NULL,
-//				_("A Little About Me"), 0, NULL, NULL);
-//	}
-//
-//	if (found)
-//		has_info = TRUE;
-//
-//	/* Check if they have Favorite Things */
-//	found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//			" Favorite Things \n\n", 0, "Hobbies and Interests", '\n', NULL,
-//			_("Favorite Things"), 0, NULL, NULL);
-//
-//	if (!found)
-//	{
-//		found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" Favorite Things \n\n", 0, "Favorite Quote", '\n', NULL,
-//				_("Favorite Things"), 0, NULL, NULL);
-//	}
-//
-//	if (!found)
-//	{
-//		found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" Favorite Things \n\n", 0, "My Homepage \n\nTake a look", '\n',
-//				NULL, _("Favorite Things"), 0, NULL, NULL);
-//	}
-//
-//	if (!found)
-//	{
-//		purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" Favorite Things \n\n", 0, "last updated", '\n', NULL,
-//				_("Favorite Things"), 0, NULL, NULL);
-//	}
-//
-//	if (found)
-//		has_info = TRUE;
-//
-//	/* Check if they have Hobbies and Interests */
-//	found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//			" Hobbies and Interests \n\n", 0, "Favorite Quote", '\n', NULL,
-//			_("Hobbies and Interests"), 0, NULL, NULL);
-//
-//	if (!found)
-//	{
-//		found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" Hobbies and Interests \n\n", 0, "My Homepage \n\nTake a look",
-//				'\n', NULL, _("Hobbies and Interests"), 0, NULL, NULL);
-//	}
-//
-//	if (!found)
-//	{
-//		purple_markup_extract_info_field(stripped, stripped_len, s,
-//				" Hobbies and Interests \n\n", 0, "last updated", '\n', NULL,
-//				_("Hobbies and Interests"), 0, NULL, NULL);
-//	}
-//
-//	if (found)
-//		has_info = TRUE;
-//
-//	/* Check if they have Favorite Quote */
-//	found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//			"Favorite Quote \n\n", 0, "My Homepage \n\nTake a look", '\n', NULL,
-//			_("Favorite Quote"), 0, NULL, NULL);
-//
-//	if (!found)
-//	{
-//		purple_markup_extract_info_field(stripped, stripped_len, s,
-//				"Favorite Quote \n\n", 0, "last updated", '\n', NULL,
-//				_("Favorite Quote"), 0, NULL, NULL);
-//	}
-//
-//	if (found)
-//		has_info = TRUE;
-//
-//	/* Extract the last updated date and put it in */
-//	found = purple_markup_extract_info_field(stripped, stripped_len, s,
-//			" last updated:", 1, "\n", 0, NULL, _("Last Updated"), 0,
-//			NULL, nateon_info_date_reformat);
-//
-//	if (found)
-//		has_info = TRUE;
-//#endif
-//
-//	/* If we were able to fetch a homepage url earlier, stick it in there */
-//	if (user_url != NULL)
-//	{
-//		g_snprintf(buf, sizeof(buf),
-//				   "<b>%s:</b><br><a href=\"%s\">%s</a><br>\n",
-//				   _("Homepage"), user_url, user_url);
-//
-//		g_string_append(s, buf);
-//
-//		g_free(user_url);
-//
-//		has_info = TRUE;
-//	}
-//
-//	if (!has_info)
-//	{
-//		/* NATEON doesn't actually distinguish between "unknown member" and
-//		 * a known member with an empty profile. Try to explain this fact.
-//		 * Note that if we have a nonempty tooltip_text, we know the user
-//		 * exists.
-//		 */
-//		/* This doesn't work with the new spaces profiles - Stu 3/2/06
-//		char *p = strstr(url_buffer, "Unknown Member </TITLE>");
-//		 * This might not work for long either ... */
-//		char *p = strstr(url_buffer, "form id=\"SpacesSearch\" name=\"SpacesSearch\"");
-//		PurpleBuddy *b = purple_find_buddy
-//				(purple_connection_get_account(info_data->gc), info_data->name);
-//		g_string_append_printf(s, "<br><b>%s</b><br>%s<br><br>",
-//				_("Error retrieving profile"),
-//				((p && b)?
-//					_("The user has not created a public profile."):
-//				 p? _("NATEON reported not being able to find the user's profile. "
-//					  "This either means that the user does not exist, "
-//					  "or that the user exists "
-//					  "but has not created a public profile."):
-//					_("Purple could not find "	/* This should never happen */
-//					  "any information in the user's profile. "
-//					  "The user most likely does not exist.")));
-//	}
-//	/* put a link to the actual profile URL */
-//	g_string_append_printf(s, _("<hr><b>%s:</b> "), _("Profile URL"));
-//	g_string_append_printf(s, "<br><a href=\"%s%s\">%s%s</a><br>",
-//			PROFILE_URL, info_data->name, PROFILE_URL, info_data->name);
-//
-//	/* Finish it off, and show it to them */
-//	g_string_append(s, "</body></html>\n");
-//
-//#if PHOTO_SUPPORT
-//	/* Find the URL to the photo; must be before the marshalling [Bug 994207] */
-//	photo_url_text = nateon_get_photo_url(url_text);
-//
-//	/* Marshall the existing state */
-//	info2_data = g_malloc0(sizeof(NateonGetInfoStepTwoData));
-//	info2_data->info_data = info_data;
-//	info2_data->stripped = stripped;
-//	info2_data->url_buffer = url_buffer;
-//	info2_data->s = s;
-//	info2_data->photo_url_text = photo_url_text;
-//	info2_data->tooltip_text = tooltip_text;
-//	info2_data->title = title;
-//
-//	/* Try to put the photo in there too, if there's one */
-//	if (photo_url_text)
-//	{
-//		purple_url_fetch(photo_url_text, FALSE, NULL, FALSE, nateon_got_photo,
-//					   info2_data);
-//	}
-//	else
-//	{
-//		/* Emulate a callback */
-//		nateon_got_photo(info2_data, NULL, 0);
-//	}
-//}
-//
-//static void
-//nateon_got_photo(void *data, const char *url_text, size_t len)
-//{
-//	NateonGetInfoStepTwoData *info2_data = (NateonGetInfoStepTwoData *)data;
-//	int id = -1;
-//
-//	/* Unmarshall the saved state */
-//	NateonGetInfoData *info_data = info2_data->info_data;
-//	char *stripped = info2_data->stripped;
-//	char *url_buffer = info2_data->url_buffer;
-//	GString *s = info2_data->s;
-//	char *photo_url_text = info2_data->photo_url_text;
-//	char *tooltip_text = info2_data->tooltip_text;
-//
-//	/* Make sure the connection is still valid if we got here by fetching a photo url */
-//	if (url_text &&
-//		g_list_find(purple_connections_get_all(), info_data->gc) == NULL)
-//	{
-//		purple_debug_warning("nateon", "invalid connection. ignoring buddy photo info.\n");
-//		g_free(stripped);
-//		g_free(url_buffer);
-//		g_string_free(s, TRUE);
-//		g_free(tooltip_text);
-//		g_free(info_data->name);
-//		g_free(info_data);
-//		g_free(photo_url_text);
-//		g_free(info2_data);
-//
-//		return;
-//	}
-//
-//	/* Try to put the photo in there too, if there's one and is readable */
-//	if (data && url_text && len != 0)
-//	{
-//		if (strstr(url_text, "400 Bad Request")
-//			|| strstr(url_text, "403 Forbidden")
-//			|| strstr(url_text, "404 Not Found"))
-//		{
-//
-//			purple_debug_info("nateon", "Error getting %s: %s\n",
-//					photo_url_text, url_text);
-//		}
-//		else
-//		{
-//			char buf[1024];
-//			purple_debug_info("nateon", "%s is %d bytes\n", photo_url_text, len);
-//			id = purple_imgstore_add(url_text, len, NULL);
-//			g_snprintf(buf, sizeof(buf), "<img id=\"%d\"><br>", id);
-//			g_string_prepend(s, buf);
-//		}
-//	}
-//
-//	/* We continue here from nateon_got_info, as if nothing has happened */
-//#endif
-//
-//	g_string_prepend(s, tooltip_text);
-//	purple_notify_userinfo(info_data->gc, info_data->name, s->str, NULL, NULL);
-//
-//	g_free(stripped);
-//	g_free(url_buffer);
-//	g_string_free(s, TRUE);
-//	g_free(tooltip_text);
-//	g_free(info_data->name);
-//	g_free(info_data);
-//#if PHOTO_SUPPORT
-//	g_free(photo_url_text);
-//	g_free(info2_data);
-//	if (id != -1)
-//		purple_imgstore_unref(id);
-//#endif
-//}
-//
-//static void
-//nateon_get_info(PurpleConnection *gc, const char *name)
-//{
-//	NateonGetInfoData *data;
-//	char *url;
-//
-//	data       = g_new0(NateonGetInfoData, 1);
-//	data->gc   = gc;
-//	data->name = g_strdup(name);
-//
-//	url = g_strdup_printf("%s%s", PROFILE_URL, name);
-//
-//	purple_url_fetch(url, FALSE,
-//				   "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
-//				   TRUE, nateon_got_info, data);
-//
-//	g_free(url);
-//}
 
+/**
+ * Extract info text from info_data and add it to user_info
+ */
+static gboolean
+nateon_tooltip_extract_info_text(PurpleNotifyUserInfo *user_info, NateonGetInfoData *info_data)
+{
+	PurpleBuddy *b;
+
+	b = purple_find_buddy(purple_connection_get_account(info_data->gc),
+						info_data->name);
+
+	if (b)
+	{
+		char *tmp;
+
+		if (b->alias && b->alias[0])
+		{
+			char *aliastext = g_markup_escape_text(b->alias, -1);
+			purple_notify_user_info_add_pair(user_info, _("Alias"), aliastext);
+			g_free(aliastext);
+		}
+
+		if (b->server_alias)
+		{
+			char *nicktext = g_markup_escape_text(b->server_alias, -1);
+			tmp = g_strdup_printf("<font sml=\"nateon\">%s</font><br>", nicktext);
+			purple_notify_user_info_add_pair(user_info, _("Nickname"), tmp);
+			g_free(tmp);
+			g_free(nicktext);
+		}
+
+		/* Add the tooltip information */
+		nateon_tooltip_text(b, user_info, TRUE);
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+#if PHOTO_SUPPORT
+
+static void nateon_got_photo(PurpleUtilFetchUrlData *url_data, gpointer data,
+		const gchar *url_text, size_t len, const gchar *error_message);
+static void nateon_got_photo_frame(PurpleUtilFetchUrlData *url_data, gpointer data,
+		const gchar *url_text, size_t len, const gchar *error_message);
+
+#endif
+
+#define NATEON_GOT_INFO_GET_FIELD(a, b) \
+	purple_markup_extract_info_field(stripped, stripped_len, user_info, \
+			" " a "\t", 0, "\n", 0, "Undisclosed", b, 0, NULL, NULL); \
+
+static void
+nateon_got_info(PurpleUtilFetchUrlData *url_data, gpointer data,
+		const gchar *url_text, size_t len, const gchar *error_message)
+{
+	NateonGetInfoData *info_data = (NateonGetInfoData *)data;
+	PurpleNotifyUserInfo *user_info;
+	char *stripped, *p, *tmp;
+	gboolean has_tooltip_text = FALSE;
+	gboolean has_info = FALSE;
+	char *url_buffer;
+	int stripped_len;
+#if PHOTO_SUPPORT
+	char *photo_url_text = NULL;
+	char *photo_frame_url_text = NULL;
+	NateonGetInfoStepTwoData *info2_data = NULL;
+#endif
+
+	purple_debug_info("nateon", "In nateon_got_info\n");
+
+	/* Make sure the connection is still valid */
+	if (g_list_find(purple_connections_get_all(), info_data->gc) == NULL)
+	{
+		purple_debug_warning("nateon", "invalid connection. ignoring buddy info.\n");
+		g_free(info_data->name);
+		g_free(info_data);
+		return;
+	}
+
+	user_info = purple_notify_user_info_new();
+	has_tooltip_text = nateon_tooltip_extract_info_text(user_info, info_data);
+
+	if (error_message != NULL || url_text == NULL || strcmp(url_text, "") == 0)
+	{
+		tmp = g_strdup_printf("<b>%s</b>", _("Error retrieving profile"));
+		purple_notify_user_info_add_pair(user_info, NULL, tmp);
+		g_free(tmp);
+
+		purple_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL);
+		purple_notify_user_info_destroy(user_info);
+
+		g_free(info_data->name);
+		g_free(info_data);
+		return;
+	}
+
+	url_buffer = g_strdup(url_text);
+
+	if ((p = strstr(url_text,
+			"\xec\xa1\xb4\xec\x9e\xac\xed\x95\x98"
+			"\xec\xa7\x80 \xec\x95\x8a\xeb\x8a\x94 "
+			"\xec\x82\xac\xec\x9a\xa9\xec\x9e\x90"
+			"\xec\x9e\x85\xeb\x8b\x88\xeb\x8b\xa4.")) == NULL)
+	{
+		has_info = TRUE;
+	}
+
+	/* Nuke the html, it's easier than trying to parse the horrid stuff */
+	stripped = purple_markup_strip_html(url_buffer);
+	stripped_len = strlen(stripped);
+
+	purple_debug_misc("nateon", "stripped = %p\n", stripped);
+	purple_debug_misc("nateon", "url_buffer = %p\n", url_buffer);
+
+	/* General section header */
+	if (has_tooltip_text)
+		purple_notify_user_info_add_section_break(user_info);
+	
+	/* Personal */
+	purple_notify_user_info_add_section_header(user_info, _("Personal Information"));
+	
+	/* Extract their Name, minihp and put it in */
+	purple_markup_extract_info_field(stripped, stripped_len, user_info,
+			" \xec\x9d\xb4\xeb\xa6\x84\t", 0, " ", 0, "Undisclosed", _("Name"), 0, NULL, NULL);
+	purple_notify_user_info_remove_last_item(user_info);
+
+	NATEON_GOT_INFO_GET_FIELD("\xec\x9d\xb4\xeb\xa9\x94\xec\x9d\xbc", _("Email"));
+	NATEON_GOT_INFO_GET_FIELD("\xec\x83\x9d\xec\x9d\xbc", _("Birthday"));
+	NATEON_GOT_INFO_GET_FIELD("\xed\x9c\xb4\xeb\x8c\x80\xed\x8f\xb0", _("Mobile Phone"));
+	NATEON_GOT_INFO_GET_FIELD("\xec\x9e\x90\xea\xb8\xb0\xec\x86\x8c\xea\xb0\x9c", _("A Little About Me"));
+
+	if (strstr(stripped, "openWindow_minihompy") != NULL)
+	{
+		tmp = g_strdup_printf(NATEON_MINIHP_URL, info_data->id);
+		purple_notify_user_info_add_pair(user_info, _("Homepage"), tmp);
+		g_free(tmp);
+	}
+
+
+	if (!has_info)
+	{
+		PurpleBuddy *b = purple_find_buddy
+				(purple_connection_get_account(info_data->gc), info_data->name);
+		purple_notify_user_info_add_pair(user_info, _("Error retrieving profile"),
+									   ((p && b) ? _("The user has not created a public profile.") :
+										(p ? _("NATEON reported not being able to find the user's profile. "
+											   "This either means that the user does not exist, "
+											   "or that the user exists "
+											   "but has not created a public profile.") :
+										 _("Could not find "	/* This should never happen */
+										   "any information in the user's profile. "
+										   "The user most likely does not exist."))));
+	}
+
+	/* put a link to the actual profile URL */
+	tmp = g_strdup_printf("<a href=\"%s%s\">%s%s</a>",
+					NATEON_PROFILE_URL, info_data->id,
+					NATEON_PROFILE_URL, info_data->id);
+	purple_notify_user_info_add_pair(user_info, _("Profile URL"), tmp);
+	g_free(tmp);
+
+#if PHOTO_SUPPORT
+
+	/* Marshall the existing state */
+	info2_data = g_malloc0(sizeof(NateonGetInfoStepTwoData));
+	info2_data->info_data = info_data;
+	info2_data->stripped = stripped;
+	info2_data->url_buffer = url_buffer;
+	info2_data->user_info = user_info;
+
+	/* Try to put the photo in there too, if there's one */
+	if (strstr(url_text, "openProfileImage") != NULL)
+	{
+		photo_frame_url_text = g_strdup_printf(NATEON_PHOTO_URL, info_data->id);
+		info2_data->photo_frame_url_text = photo_frame_url_text;
+		purple_util_fetch_url(photo_frame_url_text, FALSE, NULL, FALSE, nateon_got_photo_frame,
+					   info2_data);
+	}
+	else
+	{
+		/* Emulate a callback */
+		/* TODO: Huh? */
+		nateon_got_photo(NULL, info2_data, NULL, 0, NULL);
+	}
+}
+
+static void
+nateon_got_photo_frame(PurpleUtilFetchUrlData *url_data, gpointer user_data,
+		const gchar *url_text, size_t len, const gchar *error_message)
+{
+	NateonGetInfoStepTwoData *info2_data = (NateonGetInfoStepTwoData *)user_data;
+	char *p, *q, *tmp, *photo_url_text;
+
+	if ( (p=strstr(url_text, "/profileimage")) != NULL && (q=strstr(p, "\"")) != NULL)
+	{
+		tmp = g_strndup(p, q - p);
+		photo_url_text = g_strdup_printf("%s%s", NATEON_PROFILE_BASE, tmp);
+		info2_data->photo_url_text = photo_url_text;
+		purple_util_fetch_url(photo_url_text, FALSE, NULL, FALSE, nateon_got_photo,
+					   info2_data);
+		g_free(tmp);
+	}
+	else
+	{
+		/* Emulate a callback */
+		/* TODO: Huh? */
+		nateon_got_photo(NULL, info2_data, NULL, 0, NULL);
+	}
+}
+
+static void
+nateon_got_photo(PurpleUtilFetchUrlData *url_data, gpointer user_data,
+		const gchar *url_text, size_t len, const gchar *error_message)
+{
+	NateonGetInfoStepTwoData *info2_data = (NateonGetInfoStepTwoData *)user_data;
+	int id = -1;
+
+	/* Unmarshall the saved state */
+	NateonGetInfoData *info_data = info2_data->info_data;
+	char *stripped = info2_data->stripped;
+	char *url_buffer = info2_data->url_buffer;
+	PurpleNotifyUserInfo *user_info = info2_data->user_info;
+	char *photo_url_text = info2_data->photo_url_text;
+	char *photo_frame_url_text = info2_data->photo_frame_url_text;
+
+	/* Make sure the connection is still valid if we got here by fetching a photo url */
+	if (url_text && (error_message != NULL ||
+					 g_list_find(purple_connections_get_all(), info_data->gc) == NULL))
+	{
+		purple_debug_warning("nateon", "invalid connection. ignoring buddy photo info.\n");
+		g_free(stripped);
+		g_free(url_buffer);
+		g_free(user_info);
+		g_free(info_data->name);
+		g_free(info_data);
+		g_free(photo_url_text);
+		g_free(photo_frame_url_text);
+		g_free(info2_data);
+
+		return;
+	}
+
+	/* Try to put the photo in there too, if there's one and is readable */
+	if (user_data && url_text && len != 0)
+	{
+		if (strstr(url_text, "400 Bad Request")
+			|| strstr(url_text, "403 Forbidden")
+			|| strstr(url_text, "404 Not Found"))
+		{
+
+			purple_debug_info("nateon", "Error getting %s: %s\n",
+					photo_url_text, url_text);
+		}
+		else
+		{
+			char buf[1024];
+			purple_debug_info("nateon", "%s is %d bytes\n", photo_url_text, len);
+			id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
+			g_snprintf(buf, sizeof(buf), "<img id=\"%d\"><br>", id);
+			purple_notify_user_info_prepend_pair(user_info, NULL, buf);
+		}
+	}
+
+	/* We continue here from nateon_got_info, as if nothing has happened */
+#endif
+	purple_notify_userinfo(info_data->gc, info_data->name, user_info, NULL, NULL);
+
+	g_free(stripped);
+	g_free(url_buffer);
+	purple_notify_user_info_destroy(user_info);
+	g_free(info_data->name);
+	g_free(info_data);
+#if PHOTO_SUPPORT
+	g_free(photo_url_text);
+	g_free(photo_frame_url_text);
+	g_free(info2_data);
+	if (id != -1)
+		purple_imgstore_unref_by_id(id);
+#endif
+}
+
+static void
+nateon_get_info(PurpleConnection *gc, const char *name)
+{
+	NateonGetInfoData *data;
+	char *url;
+	const char *id;
+	NateonSession *session;
+
+	data       = g_new0(NateonGetInfoData, 1);
+	data->gc   = gc;
+	data->name = g_strdup(name);
+	session    = gc->proto_data;
+	id         = nateon_userlist_find_user_with_name(session->userlist, name)->id;
+	data->id = g_strdup(id);
+
+	url = g_strdup_printf("%s%s", NATEON_PROFILE_URL, id);
+
+	purple_util_fetch_url(url, TRUE,
+				   "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
+				   TRUE, nateon_got_info, data);
+
+	g_free(url);
+}
+
 static gboolean nateon_load(PurplePlugin *plugin)
 {
 	nateon_notification_init();
@@ -1959,7 +1683,7 @@
 	nateon_send_im,				/* send_im */
 	NULL,					/* set_info */
 	nateon_send_typing,			/* send_typing */
-	NULL, //nateon_get_info,			/* get_info */
+	nateon_get_info,			/* get_info */
 	nateon_set_status,			/* set_away */
 	nateon_set_idle,			/* set_idle */
 	NULL,					/* change_passwd */
Index: libpurple/protocols/nateon/nateon.h
===================================================================
--- libpurple/protocols/nateon/nateon.h	(revision 57)
+++ libpurple/protocols/nateon/nateon.h	(working copy)
@@ -65,21 +65,23 @@
 #define NATEON_TYPING_RECV_TIMEOUT 	6
 #define NATEON_TYPING_SEND_TIMEOUT	4
 
-//#define HOTMAIL_URL "http://www.hotmail.com/cgi-bin/folders"
-//#define PASSPORT_URL "http://lc1.law13.hotmail.passport.com/cgi-bin/dologin?login="
-//#define PROFILE_URL "http://spaces.msn.com/profile.aspx?mem="
-//
-//#define USEROPT_HOTMAIL 0
-//
-//#define BUDDY_ALIAS_MAXLEN 387
-//
-//#define NATEON_FT_GUID "{5D3E02AB-6190-11d3-BBBB-00C04F795683}"
-//
-//#define NATEON_CLIENTINFO \
-//	"Client-Name: Purple/" VERSION "\r\n" \
-//	"Chat-Logging: Y\r\n"
+#define NATEON_PROFILE_BASE "http://nateonweb.nate.com"
+#define NATEON_PROFILE_URL NATEON_PROFILE_BASE "/client/profile2/view.php?CMN="
+#define NATEON_PHOTO_URL NATEON_PROFILE_BASE "/client/profile2/getProfileImage.php?CMN=%s"
+#define NATEON_MINIHP_URL NATEON_PROFILE_BASE "/client/profile2/minihompi_send.php?menu=Home&TargetCMN=%s"
 
+/*
 
+#define BUDDY_ALIAS_MAXLEN 387
+
+#define NATEON_FT_GUID "{5D3E02AB-6190-11d3-BBBB-00C04F795683}"
+
+#define NATEON_CLIENTINFO \
+	"Client-Name: Purple/" VERSION "\r\n" \
+	"Chat-Logging: Y\r\n"
+*/
+
+
 typedef enum
 {
 	NATEON_LIST_FL_OP,

