changeset 29688:8b17877d3294

propagate from branch 'im.pidgin.pidgin' (head 74c00c33cab0e208691543b25eeae7906f6e4181) to branch 'im.pidgin.cpw.attention_ui' (head 3471a591582c3bbaaf1ed35288bce15461b920e3)
author Marcus Lundblad <ml@update.uu.se>
date Mon, 22 Jun 2009 21:53:53 +0000
parents 42c64c41cf87 (current diff) ef9e68020265 (diff)
children 42360009f2e5
files libpurple/connection.h libpurple/conversation.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/message.c libpurple/protocols/msn/msn.c libpurple/protocols/yahoo/yahoo.c pidgin/gtkconv.c
diffstat 52 files changed, 732 insertions(+), 333 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Mon Jun 08 18:28:31 2009 +0000
+++ b/COPYRIGHT	Mon Jun 22 21:53:53 2009 +0000
@@ -224,6 +224,7 @@
 Jochen Kemnade
 Yann Kerherve
 Gordian Klein
+Krzysztof Klinikowski
 Akuke Kok
 Kir Kolyshkin
 F.W. Kong
@@ -332,6 +333,7 @@
 Luke Petre
 Diego Petten
 Nathan Peterson
+Dmitry Petroff
 Sebastián E. Peyrott
 Andrea Piccinelli
 Celso Pinto
@@ -510,6 +512,7 @@
 Ma Xuan
 Jared Yanovich
 Timmy Yee
+Li Yuan
 Nickolai Zeldovich
 Tom Zickel
 Marco Ziech
--- a/ChangeLog	Mon Jun 08 18:28:31 2009 +0000
+++ b/ChangeLog	Mon Jun 22 21:53:53 2009 +0000
@@ -20,9 +20,6 @@
 	  moved to a new network and the old servers are not accessible.
 	* Gadu-Gadu accounts can specify a server to which to connect.
 	  (Krzysztof "kreez" Tobola)
-	* Modifying the MSN privacy list for buddies not added by you (i.e.
-	  spammers and other generally unwanted users) should no longer cause
-	  a 240 error and disconnection.
 
 	XMPP:
 	* Voice & Video support with Jingle (XEP-0166, 0167, 0176, & 0177), voice
@@ -69,9 +66,6 @@
 	  (Sulabh Mahajan)
 	* Addition of MSN buddies to Yahoo accounts by adding them as
 	  'msn/buddy@somedomain.com' is now supported.  (Sulabh Mahajan)
-	* Yahoo Protocol 16 support, including new HTTPS login method; this should
-	  fix a number of login problems that have recently cropped up.  (Sulabh
-	  Mahajan, Mike "Maiku" Ruprecht)
 
 	Pidgin:
 	* Added -f command line option to tell Pidgin to ignore NetworkManager
@@ -99,6 +93,12 @@
 	  collapse buddy groups or contacts. (Peter Ruibal)
 	* Support saving animated custom smileys as animated images or animated
 	  custom smileys. (Andrea Piccinelli)
+	* Support for keyboard navigation on the status icon. (Li Yuan)
+	* IMG tags without 'id' attributes are turned into links to the image URL.
+	  (Dmitry Petroff)
+	* Draw the user's buddy icon at the bottom of the Buddy List with rounded
+	  corners for visual consistency with the actual icons in the Buddy List.
+	  (Kosta Arvanitis)
 
 	Finch:
 	* The hardware cursor is updated correctly. This will be useful
@@ -112,6 +112,16 @@
 	* Preferences have been reorganized into three tabs for Colors, Fonts, and
 	  Miscellaneous categories.
 
+version 2.5.7 (06/20/2009):
+	* Yahoo Protocol 16 support, including new HTTPS login method; this should
+	  fix a number of login problems that have recently cropped up.  (Sulabh
+	  Mahajan, Mike "Maiku" Ruprecht)
+	* Only display the AIM "Unable to Retrieve Buddy List" message once per
+	  connection.  (Rob Taft)
+	* Blocking MSN users not on your buddy list no longer disconnects you.
+	* When performing operations on MSN, assume users are on the MSN/Passport
+	  network if we don't get network ID's for them.
+
 version 2.5.6 (05/19/2009):
 	libpurple:
 	* Improve sleep behavior by aggregation of longer timeouts on second
--- a/ChangeLog.API	Mon Jun 08 18:28:31 2009 +0000
+++ b/ChangeLog.API	Mon Jun 22 21:53:53 2009 +0000
@@ -39,6 +39,7 @@
 		* purple_network_set_turn_server
 		* purple_network_get_stun_ip
 		* purple_network_get_turn_ip
+		* purple_network_remove_port_mapping
 		* purple_proxy_connect_udp
 		* purple_prpl_get_media_caps
 		* purple_prpl_got_account_actions
@@ -127,6 +128,12 @@
 			* Purple::Request::Field::string_new
 			* Purple::Request::Field::group_new
 
+version 2.5.7 (06/20/2009):
+	No changes
+
+version 2.5.6 (05/19/2009):
+	No changes
+
 version 2.5.5 (03/01/2009):
 	libpurple:
 		Changed:
--- a/ChangeLog.win32	Mon Jun 08 18:28:31 2009 +0000
+++ b/ChangeLog.win32	Mon Jun 22 21:53:53 2009 +0000
@@ -1,5 +1,11 @@
 version 2.6.0 (??/??/2009):
 
+version 2.5.7 (06/20/2009):
+	* No changes
+
+version 2.5.6 (05/19/2009):
+	* No changes
+
 version 2.5.5 (03/01/2009):
 	* Remove the "Flash window when chat messages are received" pref from
 	  the Windows Pidgin Options plugin - the Message Notification plugin
--- a/NEWS	Mon Jun 08 18:28:31 2009 +0000
+++ b/NEWS	Mon Jun 22 21:53:53 2009 +0000
@@ -2,6 +2,33 @@
 
 Our development blog is available at: http://planet.pidgin.im
 
+2.5.7 (06/20/2009):
+	John:  This release is really just a rushed fix for the broken Yahoo
+	protocol plugin.  I spent way more time on this release than I care
+	to admit, so I hope that time is well spent and this fixes the issues
+	people have been having.
+
+2.5.6 (05/19/2009):
+	Ka-Hing: Many much bugfixes. Hooray. (Paul told me to say that)
+	Oh, no one has met Paul yet? He's awesome, he backported my fixes
+	to the release branch so I didn't have to checkout a
+	workspace... except I just did to NEWS to tell you all about
+	that. Oh and I actually did do something for this release, none of
+	which is user visible though. This basically applies to the rest
+	of the release as well, nothing exciting, but you definitely want
+	it.
+
+	Daniel: This should fix a number of annoying issues that some users
+	have encountered.  We also would like to thank Veracode
+	(http://www.veracode.com) who performed a code analysis and found some
+	bugs that were addressed in this release.
+
+	Elliott: I feel like I'm repeating myself, but there are some more MSN
+	fixes that should make things better behaved at login as well, and
+	maybe you'll stop getting some of those annoying errors (though not all
+	are fixed yet).  Some other bugfixes, plus the craziness that is the
+	libxml "structured error handler" make up the rest of this release.
+
 2.5.5 (03/01/2009):
 	John: Well, yet another release with bug fixing and patches.  Hopefully
 	one of the fixed bugs is one that irritated you.  Also, thank Dimmuxx
--- a/finch/plugins/gnthistory.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/finch/plugins/gnthistory.c	Mon Jun 22 21:53:53 2009 +0000
@@ -31,6 +31,7 @@
 #include "util.h"
 #include "version.h"
 
+#include "gntconv.h"
 #include "gntplugin.h"
 #include "gntrequest.h"
 
@@ -54,6 +55,9 @@
 	if (convtype == PURPLE_CONV_TYPE_IM) {
 		GSList *buddies;
 		GSList *cur;
+		FinchConv *fc = FINCH_CONV(c);
+		if (fc->list && fc->list->next) /* We were already in the middle of a conversation. */
+			return;
 
 		/* If we're not logging, don't show anything.
 		 * Otherwise, we might show a very old log. */
--- a/libpurple/connection.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/connection.c	Mon Jun 22 21:53:53 2009 +0000
@@ -309,7 +309,7 @@
 	g_free(gc->password);
 	g_free(gc->display_name);
 
-	if (gc->disconnect_timeout)
+	if (gc->disconnect_timeout > 0)
 		purple_timeout_remove(gc->disconnect_timeout);
 
 	PURPLE_DBUS_UNREGISTER_POINTER(gc);
@@ -515,11 +515,20 @@
 static gboolean
 purple_connection_disconnect_cb(gpointer data)
 {
-	PurpleAccount *account = data;
-	char *password = g_strdup(purple_account_get_password(account));
+	PurpleAccount *account;
+	PurpleConnection *gc;
+	char *password;
+
+	account = data;
+	gc = purple_account_get_connection(account);
+
+	gc->disconnect_timeout = 0;
+
+	password = g_strdup(purple_account_get_password(account));
 	purple_account_disconnect(account);
 	purple_account_set_password(account, password);
 	g_free(password);
+
 	return FALSE;
 }
 
@@ -564,7 +573,7 @@
 	}
 
 	/* If we've already got one error, we don't need any more */
-	if (gc->disconnect_timeout)
+	if (gc->disconnect_timeout > 0)
 		return;
 
 	gc->wants_to_die = purple_connection_error_is_fatal (reason);
--- a/libpurple/connection.h	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/connection.h	Mon Jun 22 21:53:53 2009 +0000
@@ -560,6 +560,9 @@
  * Checks if gc is still a valid pointer to a gc.
  *
  * @return @c TRUE if gc is valid.
+ *
+ * @deprecated Do not use this.  Instead, cancel your asynchronous request
+ *             when the PurpleConnection is destroyed.
  */
 /*
  * TODO: Eventually this bad boy will be removed, because it is
--- a/libpurple/network.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/network.c	Mon Jun 22 21:53:53 2009 +0000
@@ -105,6 +105,10 @@
 static gchar *stun_ip = NULL;
 static gchar *turn_ip = NULL;
 
+/* Keep track of port mappings done with UPnP and NAT-PMP */
+static GHashTable *upnp_port_mappings = NULL;
+static GHashTable *nat_pmp_port_mappings = NULL;
+
 const unsigned char *
 purple_network_ip_atoi(const char *ip)
 {
@@ -257,6 +261,15 @@
 		return;
 	}
 
+	if (success) {
+		/* add port mapping to hash table */
+		gint *key = g_new(gint, 1);
+		gint *value = g_new(gint, 1);
+		*key = purple_network_get_port_from_fd(listen_data->listenfd);
+		*value = listen_data->socket_type;
+		g_hash_table_insert(upnp_port_mappings, key, value);
+	}
+
 	if (listen_data->cb)
 		listen_data->cb(listen_data->listenfd, listen_data->cb_data);
 
@@ -270,9 +283,16 @@
 purple_network_finish_pmp_map_cb(gpointer data)
 {
 	PurpleNetworkListenData *listen_data;
+	gint *key = g_new(gint, 1);
+	gint *value = g_new(gint, 1);
 
 	listen_data = data;
 
+	/* add port mapping to hash table */
+	*key = purple_network_get_port_from_fd(listen_data->listenfd);
+	*value = listen_data->socket_type;
+	g_hash_table_insert(nat_pmp_port_mappings, key, value);
+
 	if (listen_data->cb)
 		listen_data->cb(listen_data->listenfd, listen_data->cb_data);
 
@@ -892,6 +912,61 @@
 	return &handle;
 }
 
+static void
+purple_network_upnp_mapping_remove_cb(gboolean sucess, gpointer data)
+{
+	purple_debug_info("network", "done removing UPnP port mapping\n");
+}
+
+/* the reason for these functions to have these signatures is to be able to
+ use them for g_hash_table_foreach to clean remaining port mappings, which is
+ not yet done */
+static void
+purple_network_upnp_mapping_remove(gpointer key, gpointer value,
+	gpointer user_data)
+{
+	gint port = (gint) *((gint *) key);
+	gint protocol = (gint) *((gint *) value);
+	purple_debug_info("network", "removing UPnP port mapping for port %d\n",
+		port);
+	purple_upnp_remove_port_mapping(port, 
+		protocol == SOCK_STREAM ? "TCP" : "UDP", 
+		purple_network_upnp_mapping_remove_cb, NULL);
+	g_hash_table_remove(upnp_port_mappings, key);
+}
+
+static void
+purple_network_nat_pmp_mapping_remove(gpointer key, gpointer value,
+	gpointer user_data)
+{
+	gint port = (gint) *((gint *) key);
+	gint protocol = (gint) *((gint *) value);
+	purple_debug_info("network", "removing NAT-PMP port mapping for port %d\n",
+		port);
+	purple_pmp_destroy_map(
+		protocol == SOCK_STREAM ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP, 
+		port);
+	g_hash_table_remove(nat_pmp_port_mappings, key);
+}
+
+void
+purple_network_remove_port_mapping(gint fd)
+{
+	int port = purple_network_get_port_from_fd(fd);
+	gint *protocol = g_hash_table_lookup(upnp_port_mappings, &port);
+
+	if (protocol) {
+		purple_network_upnp_mapping_remove(&port, protocol, NULL);
+		g_hash_table_remove(upnp_port_mappings, protocol);
+	} else {
+		protocol = g_hash_table_lookup(nat_pmp_port_mappings, &port);
+		if (protocol) {
+			purple_network_nat_pmp_mapping_remove(&port, protocol, NULL);
+			g_hash_table_remove(nat_pmp_port_mappings, protocol);
+		}
+	}
+}
+	
 void
 purple_network_init(void)
 {
@@ -964,8 +1039,15 @@
 		purple_prefs_get_string("/purple/network/stun_server"));
 	purple_network_set_turn_server(
 		purple_prefs_get_string("/purple/network/turn_server"));
+
+	upnp_port_mappings = 
+		g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
+	nat_pmp_port_mappings =
+		g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
 }
 
+
+
 void
 purple_network_uninit(void)
 {
@@ -1008,4 +1090,10 @@
 	
 	if (stun_ip)
 		g_free(stun_ip);
+
+	g_hash_table_destroy(upnp_port_mappings);
+	g_hash_table_destroy(nat_pmp_port_mappings);
+
+	/* TODO: clean up remaining port mappings, note calling 
+	 purple_upnp_remove_port_mapping from here doesn't quite work... */
 }
--- a/libpurple/network.h	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/network.h	Mon Jun 22 21:53:53 2009 +0000
@@ -259,7 +259,14 @@
  */
 const gchar *purple_network_get_turn_ip(void);
 		
-	
+/**
+ * Remove a port mapping (UPnP or NAT-PMP) associated with listening socket
+ *
+ * @param fd Socket to remove the port mapping for
+ * @since 2.6.0
+ */
+void purple_network_remove_port_mapping(gint fd);	
+
 /**
  * Initializes the network subsystem.
  */
--- a/libpurple/notify.h	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/notify.h	Mon Jun 22 21:53:53 2009 +0000
@@ -427,7 +427,9 @@
  * Displays a notification for multiple emails to the user.
  *
  * @param handle    The plugin or connection handle.
- * @param count     The number of emails.
+ * @param count     The number of emails.  '0' can be used to signify that
+ *                  the user has no unread emails and the UI should remove
+ *                  the mail notification.
  * @param detailed  @c TRUE if there is information for each email in the
  *                  arrays.
  * @param subjects  The array of subjects.
--- a/libpurple/plugins/ssl/ssl-gnutls.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/plugins/ssl/ssl-gnutls.c	Mon Jun 22 21:53:53 2009 +0000
@@ -576,7 +576,6 @@
 							  out_buf, out_size);
 
 	g_free(out_buf);
-	g_return_val_if_fail(success, FALSE);
 	return success;
 }
 
--- a/libpurple/protocols/bonjour/bonjour_ft.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.c	Mon Jun 22 21:53:53 2009 +0000
@@ -880,7 +880,9 @@
 	purple_proxy_info_set_type(xf->proxy_info, PURPLE_PROXY_SOCKS5);
 	purple_proxy_info_set_host(xf->proxy_info, xf->proxy_host);
 	purple_proxy_info_set_port(xf->proxy_info, xf->proxy_port);
-	xf->proxy_connection = purple_proxy_connect_socks5(NULL, xf->proxy_info,
+	xf->proxy_connection = purple_proxy_connect_socks5(
+							   purple_account_get_connection(account),
+							   xf->proxy_info,
 							   dstaddr, 0,
 							   bonjour_bytestreams_connect_cb, xfer);
 
--- a/libpurple/protocols/bonjour/jabber.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/bonjour/jabber.c	Mon Jun 22 21:53:53 2009 +0000
@@ -926,7 +926,9 @@
 		}
 		purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_NONE);
 
-		connect_data = purple_proxy_connect(NULL, jdata->account,
+		connect_data = purple_proxy_connect(
+						    purple_account_get_connection(jdata->account),
+						    jdata->account,
 						    ip, bb->port_p2pj, _connected_to_buddy, pb);
 
 		if (connect_data == NULL) {
--- a/libpurple/protocols/gg/gg.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/gg/gg.c	Mon Jun 22 21:53:53 2009 +0000
@@ -931,12 +931,15 @@
 	purple_debug_info("gg", "ggp_status_by_id: %d\n", id);
 	switch (id) {
 		case GG_STATUS_NOT_AVAIL:
+		case GG_STATUS_NOT_AVAIL_DESCR:
 			st = _("Offline");
 			break;
 		case GG_STATUS_AVAIL:
+		case GG_STATUS_AVAIL_DESCR:
 			st = _("Available");
 			break;
 		case GG_STATUS_BUSY:
+		case GG_STATUS_BUSY_DESCR:
 			st = _("Away");
 			break;
 		default:
--- a/libpurple/protocols/jabber/jabber.h	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/jabber/jabber.h	Mon Jun 22 21:53:53 2009 +0000
@@ -325,8 +325,8 @@
 void jabber_add_feature(const gchar *namespace, JabberFeatureEnabled cb); /* cb may be NULL */
 void jabber_remove_feature(const gchar *namespace);
 
-/** Adds an identitiy to this jabber library instance. For list of valid values vistit the
- *	webiste of the XMPP Registrar ( http://www.xmpp.org/registrar/disco-categories.html#client ).
+/** Adds an identity to this jabber library instance. For list of valid values visit the
+ *	website of the XMPP Registrar ( http://www.xmpp.org/registrar/disco-categories.html#client ).
  *  @param category the category of the identity.
  *  @param type the type of the identity.
  *  @param language the language localization of the name. Can be NULL.
--- a/libpurple/protocols/jabber/presence.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/jabber/presence.c	Mon Jun 22 21:53:53 2009 +0000
@@ -245,7 +245,9 @@
 {
 	xmlnode *show, *status, *presence, *pri, *c;
 	const char *show_string = NULL;
+#ifdef USE_VV
 	gboolean audio_enabled, video_enabled;
+#endif
 
 	presence = xmlnode_new("presence");
 
--- a/libpurple/protocols/jabber/si.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/jabber/si.c	Mon Jun 22 21:53:53 2009 +0000
@@ -1321,6 +1321,11 @@
 			jabber_iq_remove_callback_by_id(js, jsx->iq_id);
 		if (jsx->local_streamhost_fd >= 0)
 			close(jsx->local_streamhost_fd);
+		if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND &&
+			xfer->fd >= 0) {
+			purple_debug_info("jabber", "remove port mapping\n");
+			purple_network_remove_port_mapping(xfer->fd);
+		}
 		if (jsx->connect_timeout > 0)
 			purple_timeout_remove(jsx->connect_timeout);
 		if (jsx->ibb_timeout_handle > 0)
--- a/libpurple/protocols/jabber/useravatar.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/jabber/useravatar.c	Mon Jun 22 21:53:53 2009 +0000
@@ -257,6 +257,8 @@
                                gsize len, const gchar *error_message)
 {
 	JabberBuddyAvatarUpdateURLInfo *info = user_data;
+	gpointer icon_data;
+
 	if(!url_text) {
 		purple_debug(PURPLE_DEBUG_ERROR, "jabber",
 		             "do_buddy_avatar_update_fromurl got error \"%s\"",
@@ -264,7 +266,8 @@
 		goto out;
 	}
 
-	purple_buddy_icons_set_for_user(purple_connection_get_account(info->js->gc), info->from, (void*)url_text, len, info->id);
+	icon_data = g_memdup(url_text, len);
+	purple_buddy_icons_set_for_user(purple_connection_get_account(info->js->gc), info->from, icon_data, len, info->id);
 
 out:
 	g_free(info->from);
--- a/libpurple/protocols/msn/notification.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/msn/notification.c	Mon Jun 22 21:53:53 2009 +0000
@@ -327,14 +327,13 @@
 	/* NOTE: cmd is not always cmdproc->last_cmd, sometimes cmd is a queued
 	 * command and we are processing it */
 	if (cmd->payload == NULL) {
-		cmdproc->last_cmd->payload_cb  = msg_cmd_post;
+		cmdproc->last_cmd->payload_cb = msg_cmd_post;
 		cmd->payload_len = atoi(cmd->params[2]);
-
 	} else {
 		g_return_if_fail(cmd->payload_cb != NULL);
 
 #if 0 /* glib on win32 doesn't correctly support precision modifiers for a string */
-		purple_debug_info("msn", "MSG payload:{%.*s}\n", cmd->payload_len, cmd->payload);
+		purple_debug_info("msn", "MSG payload:{%.*s}\n", (guint)cmd->payload_len, cmd->payload);
 #endif
 		cmd->payload_cb(cmdproc, cmd, cmd->payload, cmd->payload_len);
 	}
--- a/libpurple/protocols/myspace/markup.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/myspace/markup.c	Mon Jun 22 21:53:53 2009 +0000
@@ -112,8 +112,10 @@
 	}
 }
 
-/** Convert typographical font point size to HTML font size.
- * Based on libpurple/gtkimhtml.c */
+/**
+ * Convert typographical font point size to HTML font size.
+ * Based on libpurple/gtkimhtml.c
+ */
 static guint
 msim_point_to_purple_size(MsimSession *session, guint point)
 {
@@ -135,7 +137,9 @@
 	return this_point;
 }
 
-/** Convert HTML font size to point size. */
+/**
+ * Convert HTML font size to point size.
+ */
 static guint
 msim_purple_size_to_point(MsimSession *session, guint size)
 {
@@ -155,7 +159,9 @@
 	return point;
 }
 
-/** Convert a msim markup font pixel height to the more usual point size, for incoming messages. */
+/**
+ * Convert a msim markup font pixel height to the more usual point size, for incoming messages.
+ */
 static guint
 msim_height_to_point(MsimSession *session, guint height)
 {
@@ -169,7 +175,9 @@
 	 * _font_size_ichat_to_purple */
 }
 
-/** Convert point size to msim pixel height font size specification, for outgoing messages. */
+/**
+ * Convert point size to msim pixel height font size specification, for outgoing messages.
+ */
 static guint
 msim_point_to_height(MsimSession *session, guint point)
 {
@@ -180,7 +188,9 @@
 	return (guint)msim_round((dpi * 1. / POINTS_PER_INCH) * point);
 }
 
-/** Convert the msim markup <f> (font) tag into HTML. */
+/**
+ * Convert the msim markup <f> (font) tag into HTML.
+ */
 static void
 msim_markup_f_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
 {
@@ -244,7 +254,8 @@
 	*end = g_string_free(gs_end, FALSE);
 }
 
-/** Convert a msim markup color to a color suitable for libpurple.
+/**
+ * Convert a msim markup color to a color suitable for libpurple.
  *
  * @param msim Either a color name, or an rgb(x,y,z) code.
  *
@@ -268,7 +279,9 @@
 	return g_strdup_printf("#%.2x%.2x%.2x", red, green, blue);
 }
 
-/** Convert the msim markup <a> (anchor) tag into HTML. */
+/**
+ * Convert the msim markup <a> (anchor) tag into HTML.
+ */
 static void
 msim_markup_a_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
 {
@@ -283,7 +296,9 @@
 	*end = g_strdup("</a>");
 }
 
-/** Convert the msim markup <p> (paragraph) tag into HTML. */
+/**
+ * Convert the msim markup <p> (paragraph) tag into HTML.
+ */
 static void
 msim_markup_p_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
 {
@@ -356,7 +371,9 @@
 	g_free(purple_color);
 }
 
-/** Convert the msim markup <i> tag (emoticon image) into HTML. */
+/**
+ * Convert the msim markup <i> tag (emoticon image) into HTML.
+ */
 static void
 msim_markup_i_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
 {
@@ -387,7 +404,9 @@
 	*end = g_strdup("");
 }
 
-/** Convert an individual msim markup tag to HTML. */
+/**
+ * Convert an individual msim markup tag to HTML.
+ */
 static int
 msim_markup_tag_to_html(MsimSession *session, xmlnode *root, gchar **begin,
 		gchar **end)
@@ -416,7 +435,9 @@
 	return 0;
 }
 
-/** Convert an individual HTML tag to msim markup. */
+/**
+ * Convert an individual HTML tag to msim markup.
+ */
 static int
 html_tag_to_msim_markup(MsimSession *session, xmlnode *root, gchar **begin,
 		gchar **end)
@@ -568,7 +589,8 @@
 	return ret;
 }
 
-/** Convert an xmlnode of msim markup or HTML to an HTML string or msim markup.
+/**
+ * Convert an xmlnode of msim markup or HTML to an HTML string or msim markup.
  *
  * @param f Function to convert tags.
  *
@@ -635,7 +657,9 @@
 	g_free(end);
 }
 
-/** Convert XML to something based on MSIM_XMLNODE_CONVERT. */
+/**
+ * Convert XML to something based on MSIM_XMLNODE_CONVERT.
+ */
 static gchar *
 msim_convert_xml(MsimSession *session, const gchar *raw, MSIM_XMLNODE_CONVERT f)
 {
@@ -669,7 +693,8 @@
 	return g_string_free(str, FALSE);
 }
 
-/** Convert plaintext smileys to <i> markup tags.
+/**
+ * Convert plaintext smileys to <i> markup tags.
  *
  * @param before Original text with ASCII smileys. Will be freed.
  * @return A new string with <i> tags, if applicable. Must be g_free()'d.
--- a/libpurple/protocols/myspace/myspace.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Mon Jun 22 21:53:53 2009 +0000
@@ -1824,17 +1824,19 @@
 					gchar *suggestion;
 
 					suggestion = g_strdup_printf(_("%s Your password is "
-							"%d characters, greater than the "
-							"expected maximum length of %d for "
-							"MySpaceIM. Please shorten your "
+							"%zu characters, which is longer than the "
+							"maximum length of %d.  Please shorten your "
 							"password at http://profileedit.myspace.com/index.cfm?fuseaction=accountSettings.changePassword and try again."),
-							full_errmsg, (int)
+							full_errmsg,
 							strlen(session->account->password),
 							MSIM_MAX_PASSWORD_LENGTH);
 
 					/* Replace full_errmsg. */
 					g_free(full_errmsg);
 					full_errmsg = suggestion;
+				} else {
+					g_free(full_errmsg);
+					full_errmsg = g_strdup(_("Incorrect username or password"));
 				}
 #endif
 				break;
--- a/libpurple/protocols/oscar/family_auth.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/oscar/family_auth.c	Mon Jun 22 21:53:53 2009 +0000
@@ -129,6 +129,8 @@
 	GSList *tlvlist = NULL;
 	int passwdlen;
 	guint8 *password_encoded;
+	const char *clientstring;
+	guint32 distrib;
 
 	passwdlen = strlen(password);
 	password_encoded = (guint8 *)g_malloc(passwdlen+1);
@@ -139,18 +141,25 @@
 
 	aim_encode_password(password, password_encoded);
 
+	clientstring = purple_prefs_get_string("/plugins/prpl/oscar/clientstring");
+	if (clientstring == NULL)
+		clientstring = ci->clientstring;
+	distrib = purple_prefs_get_int("/plugins/prpl/oscar/distid");
+	if ((gint32)distrib == -1)
+		distrib = ci->distrib;
+
 	byte_stream_put32(&frame->data, 0x00000001); /* FLAP Version */
 	aim_tlvlist_add_str(&tlvlist, 0x0001, sn);
 	aim_tlvlist_add_raw(&tlvlist, 0x0002, passwdlen, password_encoded);
 
-	if (ci->clientstring)
-		aim_tlvlist_add_str(&tlvlist, 0x0003, ci->clientstring);
+	if (clientstring)
+		aim_tlvlist_add_str(&tlvlist, 0x0003, clientstring);
 	aim_tlvlist_add_16(&tlvlist, 0x0016, (guint16)ci->clientid);
 	aim_tlvlist_add_16(&tlvlist, 0x0017, (guint16)ci->major);
 	aim_tlvlist_add_16(&tlvlist, 0x0018, (guint16)ci->minor);
 	aim_tlvlist_add_16(&tlvlist, 0x0019, (guint16)ci->point);
 	aim_tlvlist_add_16(&tlvlist, 0x001a, (guint16)ci->build);
-	aim_tlvlist_add_32(&tlvlist, 0x0014, (guint32)ci->distrib); /* distribution chan */
+	aim_tlvlist_add_32(&tlvlist, 0x0014, distrib); /* distribution chan */
 	aim_tlvlist_add_str(&tlvlist, 0x000f, ci->lang);
 	aim_tlvlist_add_str(&tlvlist, 0x000e, ci->country);
 
@@ -210,6 +219,8 @@
 	guint8 digest[16];
 	aim_snacid_t snacid;
 	size_t password_len;
+	const char *clientstring;
+	guint32 distrib;
 
 	if (!ci || !sn || !password)
 		return -EINVAL;
@@ -236,20 +247,27 @@
 
 	aim_encode_password_md5(password, password_len, key, digest);
 
+	clientstring = purple_prefs_get_string("/plugins/prpl/oscar/clientstring");
+	if (clientstring == NULL)
+		clientstring = ci->clientstring;
+	distrib = purple_prefs_get_int("/plugins/prpl/oscar/distid");
+	if ((gint32)distrib == -1)
+		distrib = ci->distrib;
+
 	aim_tlvlist_add_raw(&tlvlist, 0x0025, 16, digest);
 
 #ifndef USE_OLD_MD5
 	aim_tlvlist_add_noval(&tlvlist, 0x004c);
 #endif
 
-	if (ci->clientstring)
-		aim_tlvlist_add_str(&tlvlist, 0x0003, ci->clientstring);
+	if (clientstring)
+		aim_tlvlist_add_str(&tlvlist, 0x0003, clientstring);
 	aim_tlvlist_add_16(&tlvlist, 0x0016, (guint16)ci->clientid);
 	aim_tlvlist_add_16(&tlvlist, 0x0017, (guint16)ci->major);
 	aim_tlvlist_add_16(&tlvlist, 0x0018, (guint16)ci->minor);
 	aim_tlvlist_add_16(&tlvlist, 0x0019, (guint16)ci->point);
 	aim_tlvlist_add_16(&tlvlist, 0x001a, (guint16)ci->build);
-	aim_tlvlist_add_32(&tlvlist, 0x0014, (guint32)ci->distrib);
+	aim_tlvlist_add_32(&tlvlist, 0x0014, distrib);
 	aim_tlvlist_add_str(&tlvlist, 0x000f, ci->lang);
 	aim_tlvlist_add_str(&tlvlist, 0x000e, ci->country);
 
--- a/libpurple/protocols/oscar/flap_connection.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c	Mon Jun 22 21:53:53 2009 +0000
@@ -46,7 +46,7 @@
 	FlapFrame *frame;
 
 	frame = flap_frame_new(od, 0x01, 4);
-	byte_stream_put32(&frame->data, 0x00000001);
+	byte_stream_put32(&frame->data, 0x00000001); /* FLAP Version */
 	flap_connection_send(conn, frame);
 }
 
@@ -64,7 +64,7 @@
 	GSList *tlvlist = NULL;
 
 	frame = flap_frame_new(od, 0x01, 4 + 2 + 2 + length);
-	byte_stream_put32(&frame->data, 0x00000001);
+	byte_stream_put32(&frame->data, 0x00000001); /* FLAP Version */
 	aim_tlvlist_add_raw(&tlvlist, 0x0006, length, chipsahoy);
 	aim_tlvlist_write(&frame->data, &tlvlist);
 	aim_tlvlist_free(tlvlist);
--- a/libpurple/protocols/oscar/oscar.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Mon Jun 22 21:53:53 2009 +0000
@@ -1833,13 +1833,6 @@
 	gchar *buf;
 	gssize result;
 
-	if (!PURPLE_CONNECTION_IS_VALID(pos->gc))
-	{
-		g_free(pos->modname);
-		g_free(pos);
-		return;
-	}
-
 	pos->fd = source;
 
 	if (source < 0) {
@@ -1879,7 +1872,8 @@
 /* size of icbmui.ocm, the largest module in AIM 3.5 */
 #define AIM_MAX_FILE_SIZE 98304
 
-int purple_memrequest(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
+static int purple_memrequest(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
+{
 	va_list ap;
 	struct pieceofcrap *pos;
 	guint32 offset, len;
@@ -1937,8 +1931,7 @@
 	pos->len = len;
 	pos->modname = g_strdup(modname);
 
-	/* TODO: Keep track of this return value. */
-	if (purple_proxy_connect(NULL, pos->gc->account, "pidgin.im", 80,
+	if (purple_proxy_connect(pos->gc, pos->gc->account, "pidgin.im", 80,
 			straight_to_hell, pos) == NULL)
 	{
 		char buf[256];
@@ -7022,6 +7015,16 @@
 	/* Preferences */
 	purple_prefs_add_none("/plugins/prpl/oscar");
 	purple_prefs_add_bool("/plugins/prpl/oscar/recent_buddies", FALSE);
+
+	/*
+	 * These two preferences will normally not be changed.  UIs can optionally
+	 * use them to override these two version fields which are sent to the
+	 * server when logging in.  AOL requested this change to allow clients to
+	 * use custom values.
+	 */
+	purple_prefs_add_string("/plugins/prpl/oscar/clientstring", NULL);
+	purple_prefs_add_int("/plugins/prpl/oscar/distid", -1);
+
 	purple_prefs_remove("/plugins/prpl/oscar/show_idle");
 	purple_prefs_remove("/plugins/prpl/oscar/always_use_rv_proxy");
 
--- a/libpurple/protocols/sametime/sametime.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Mon Jun 22 21:53:53 2009 +0000
@@ -1466,7 +1466,7 @@
 
   if(purple_account_get_bool(account, MW_KEY_FORCE, FALSE) ||
      !host || (! strcmp(current_host, host)) ||
-     (purple_proxy_connect(NULL, account, host, port, connect_cb, pd) == NULL)) {
+     (purple_proxy_connect(gc, account, host, port, connect_cb, pd) == NULL)) {
 
     /* if we're configured to force logins, or if we're being
        redirected to the already configured host, or if we couldn't
--- a/libpurple/protocols/simple/simple.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/simple/simple.c	Mon Jun 22 21:53:53 2009 +0000
@@ -446,13 +446,6 @@
 	struct simple_account_data *sip;
 	struct sip_connection *conn;
 
-	if (!PURPLE_CONNECTION_IS_VALID(gc))
-	{
-		if (source >= 0)
-			close(source);
-		return;
-	}
-
 	if(source < 0) {
 		purple_connection_error_reason(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
@@ -1735,13 +1728,6 @@
 	struct simple_account_data *sip;
 	struct sip_connection *conn;
 
-	if (!PURPLE_CONNECTION_IS_VALID(gc))
-	{
-		if (source >= 0)
-			close(source);
-		return;
-	}
-
 	if(source < 0) {
 		purple_connection_error_reason(gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
--- a/libpurple/protocols/yahoo/util.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/util.c	Mon Jun 22 21:53:53 2009 +0000
@@ -22,7 +22,7 @@
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif /* HAVE_CONFIG_H */
 
 #include "debug.h"
 #include "internal.h"
@@ -42,7 +42,7 @@
 /*
  * Returns cookies formatted as a null terminated string for the given connection.
  * Must g_free return value.
- * 
+ *
  * TODO:will work, but must test for strict correctness
  */
 gchar* yahoo_get_cookies(PurpleConnection *gc)
@@ -191,7 +191,7 @@
 /*
  * I found these on some website but i don't know that they actually
  * work (or are supposed to work). I didn't implement them yet.
- * 
+ *
      * [0;30m ---black
      * [1;37m ---white
      * [0;37m ---tan
--- a/libpurple/protocols/yahoo/yahoo.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo.c	Mon Jun 22 21:53:53 2009 +0000
@@ -64,7 +64,7 @@
 static void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *, PurpleGroup *);
 #ifdef TRY_WEBMESSENGER_LOGIN
 static void yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message);
-#endif
+#endif /* TRY_WEBMESSENGER_LOGIN */
 static void yahoo_set_status(PurpleAccount *account, PurpleStatus *status);
 
 static void yahoo_update_status(PurpleConnection *gc, const char *name, YahooFriend *f)
@@ -523,7 +523,7 @@
 					purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n",account->username, norm_bud);
 					purple_privacy_deny_add(account, norm_bud, 1);
 				}
-			
+
 				protocol = 0;
 				stealth = 0;
 				norm_bud = NULL;
@@ -554,7 +554,7 @@
 	}
 
 	g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL);
-	
+
 	/* Now that we have processed the buddy list, we can say yahoo has connected */
 	purple_connection_set_display_name(gc, purple_normalize(account, purple_account_get_username(account)));
 	purple_connection_set_state(gc, PURPLE_CONNECTED);
@@ -813,6 +813,7 @@
 	int time;
 	int utf8;
 	int buddy_icon;
+	char *id;
 	char *msg;
 };
 
@@ -824,8 +825,8 @@
 	struct yahoo_data *yd;
 	char *server_msg = NULL;
 	char *m;
-	
-	yd = gc->proto_data;	
+
+	yd = gc->proto_data;
 	account = purple_connection_get_account(gc);
 
 	while (l != NULL) {
@@ -858,7 +859,7 @@
 		}
 		else
 			purple_notify_error(gc, NULL, _("Your SMS was not delivered"), NULL);
-		
+
 		g_free(sms->from);
 		g_free(sms);
 		return ;
@@ -871,7 +872,7 @@
 
 	m = yahoo_string_decode(gc, sms->msg, sms->utf8);
 	serv_got_im(gc, sms->from, m, 0, sms->time);
-		
+
 	g_free(m);
 	g_free(sms->from);
 	g_free(sms);
@@ -930,6 +931,9 @@
 			{
 				imv = pair->value;
 			}
+			if (pair->key == 429)
+				if (im)
+					im->id = pair->value;
 			l = l->next;
 		}
 	} else if (pkt->status == 2) {
@@ -997,6 +1001,28 @@
 			return;
 		}
 
+		/*
+		 * TODO: Is there anything else we should check when determining whether
+		 *       we should send an acknowledgement?
+		 */
+		if (im->id != NULL) {
+			/* Send acknowledgement.  If we don't do this then the official
+			 * Yahoo Messenger client for Windows will send us the same
+			 * message 7 seconds later as an offline message.  This is true
+			 * for at least version 9.0.0.2162 on Windows XP. */
+			struct yahoo_packet *pkt2;
+			pkt2 = yahoo_packet_new(YAHOO_SERVICE_MESSAGE_ACK,
+					YAHOO_STATUS_AVAILABLE, pkt->id);
+			yahoo_packet_hash(pkt2, "ssisii",
+					1, purple_connection_get_display_name(gc),
+					5, im->from,
+					302, 430,
+					430, im->id,
+					303, 430,
+					450, 0);
+			yahoo_packet_send_and_free(pkt2, yd);
+		}
+
 		m = yahoo_string_decode(gc, im->msg, im->utf8);
 		/* This may actually not be necessary, but it appears
 		 * that at least at one point some clients were sending
@@ -1024,7 +1050,7 @@
 				username = g_markup_escape_text(msn_from, -1);
 			else
 				username = g_markup_escape_text(im->from, -1);
-			
+
 			purple_prpl_got_attention(gc, username, YAHOO_BUZZ);
 			purple_conversation_attention(c, username, 0, PURPLE_MESSAGE_RECV,
 				time(NULL));
@@ -1045,7 +1071,7 @@
 
 		g_free(m2);
 
-		/* laters : implement buddy icon for msn friends */ 
+		/* laters : implement buddy icon for msn friends */
 		if(!msn) {
 			if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) {
 				if (yahoo_friend_get_buddy_icon_need_request(f)) {
@@ -1627,16 +1653,21 @@
 		purple_debug_error("yahoo", "Login Failed, unable to retrieve stage 2 url: %s\n", error_message);
 		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message);
 		g_free(auth_data->seed);
-		g_free(auth_data);	
+		g_free(auth_data);
 		return;
 	}
 	else if (len > 0 && ret_data && *ret_data) {
 		gchar **split_data = g_strsplit(ret_data, "\r\n", -1);
-		int totalelements = g_strv_length(split_data);
+		int totalelements = 0;
 		int response_no = -1;
 		char *crumb = NULL;
 		char *crypt = NULL;
 
+#if GLIB_CHECK_VERSION(2,6,0)
+		totalelements = g_strv_length(split_data);
+#else
+		while (split_data[++totalelements] != NULL);	
+#endif
 		if (totalelements >= 5) {
 			response_no = strtol(split_data[1], NULL, 10);
 			crumb = g_strdup(split_data[2] + strlen("crumb="));
@@ -1714,10 +1745,15 @@
 	}
 	else if (len > 0 && ret_data && *ret_data) {
 		gchar **split_data = g_strsplit(ret_data, "\r\n", -1);
-		int totalelements = g_strv_length(split_data);
+		int totalelements = 0;
 		int response_no = -1;
 		char *token = NULL;
 
+#if GLIB_CHECK_VERSION(2,6,0)
+		totalelements = g_strv_length(split_data);
+#else
+		while (split_data[++totalelements] != NULL);	
+#endif
 		if(totalelements >= 5) {
 			response_no = strtol(split_data[1], NULL, 10);
 			token = g_strdup(split_data[2] + strlen("ymsgr="));
@@ -1974,7 +2010,7 @@
 {
 #ifdef TRY_WEBMESSENGER_LOGIN
 	struct yahoo_data *yd = gc->proto_data;
-#endif
+#endif /* TRY_WEBMESSENGER_LOGIN */
 	GSList *l = pkt->hash;
 	int err = 0;
 	char *msg;
@@ -2018,7 +2054,7 @@
 				yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
 			return;
 		}
-#endif
+#endif /* TRY_WEBMESSENGER_LOGIN */
 		if (!purple_account_get_remember_password(account))
 			purple_account_set_password(account, NULL);
 
@@ -2084,7 +2120,7 @@
 		return;
 	if (!group)
 		group = "";
-	
+
 	if(msn)
 		who = g_strconcat("msn/", temp, NULL);
 	else
@@ -2125,7 +2161,7 @@
 {
 	size_t pkt_len;
 	guchar *raw_packet;
-	
+
 	/*build the raw packet and send it to the host*/
 	pkt_len = yahoo_packet_build(pkt, 0, 0, 0, &raw_packet);
 	if(write(source, raw_packet, pkt_len) != pkt_len)
@@ -2304,7 +2340,7 @@
 			yahoo_p2p_disconnect_destroy_data(data);
 		return;
 	}
-	
+
 	if(len < YAHOO_PACKET_HDRLEN)
 		return;
 
@@ -2313,13 +2349,11 @@
 		purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n");
 
 		start = memchr(buf + 1, 'Y', len - 1);
-		if(start) {
-			g_memmove(buf, start, len - (start - buf));
-			len -= start - buf;
-		} else {
-			g_free(buf);
+		if (start == NULL)
 			return;
-		}
+
+		g_memmove(buf, start, len - (start - buf));
+		len -= start - buf;
 	}
 
 	pos += 4;	/* YMSG */
@@ -2444,7 +2478,7 @@
 void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13)
 {
 	const char *public_ip;
-	guint32 temp[4];	
+	guint32 temp[4];
 	guint32 ip;
 	char temp_str[100];
 	gchar *base64_ip = NULL;
@@ -2465,7 +2499,7 @@
 	if( strcmp(purple_normalize(account, purple_account_get_username(account)), who) == 0)
 		return;
 
-	/* send packet to only those friends who arent p2p connected and to whom we havent already sent. Do not send if this condition doesn't hold good */ 
+	/* send packet to only those friends who arent p2p connected and to whom we havent already sent. Do not send if this condition doesn't hold good */
 	if( !( f && (yahoo_friend_get_p2p_status(f) == YAHOO_P2PSTATUS_NOT_CONNECTED) && (f->p2p_packet_sent == 0)) )
 		return;
 
@@ -2528,7 +2562,7 @@
 	if(error_message != NULL) {
 		purple_debug_warning("yahoo","p2p: %s\n",error_message);
 		yahoo_send_p2p_pkt(p2p_data->gc, p2p_data->host_username, 2);/* send p2p init packet with val_13=2 */
-		
+
 		yahoo_p2p_disconnect_destroy_data(p2p_data);
 		return;
 	}
@@ -2649,7 +2683,7 @@
 		p2p_data->source = -1;
 
 		/* connect to host */
-		if((purple_proxy_connect(NULL, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, p2p_data))==NULL) {
+		if((purple_proxy_connect(gc, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, p2p_data))==NULL) {
 			purple_debug_info("yahoo","p2p: Connection to %s failed\n", host_ip);
 			g_free(p2p_data->host_ip);
 			g_free(p2p_data->host_username);
@@ -2967,11 +3001,6 @@
 	struct yahoo_data *yd;
 	struct yahoo_packet *pkt;
 
-	if (!PURPLE_CONNECTION_IS_VALID(gc)) {
-		close(source);
-		return;
-	}
-
 	if (source < 0) {
 		gchar *tmp;
 		tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"),
@@ -2999,11 +3028,6 @@
 	struct yahoo_data *yd;
 	struct yahoo_packet *pkt;
 
-	if (!PURPLE_CONNECTION_IS_VALID(gc)) {
-		close(source);
-		return;
-	}
-
 	if (source < 0) {
 		gchar *tmp;
 		tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"),
@@ -3293,7 +3317,7 @@
 
 	purple_cipher_context_destroy(context);
 }
-#endif
+#endif /* TRY_WEBMESSENGER_LOGIN */
 
 static void yahoo_server_check(PurpleAccount *account)
 {
@@ -3900,7 +3924,7 @@
 	struct yahoo_data *yd = gc->proto_data;
 
 	g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
-	
+
 	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
 
 	if (error_message != NULL)
@@ -4041,7 +4065,7 @@
 		xmlnode *validate_data_root = xmlnode_from_str(webdata, -1);
 		xmlnode *validate_data_child = xmlnode_get_child(validate_data_root, "mobile_no");
 		mobile_no = (char *)xmlnode_get_attrib(validate_data_child, "msisdn");
-		
+
 		validate_data_root = xmlnode_copy(validate_data_child);
 		validate_data_child = xmlnode_get_child(validate_data_root, "status");
 		status = xmlnode_get_data(validate_data_child);
@@ -4144,7 +4168,7 @@
 	struct yahoo_p2p_data *p2p_data;
 	gboolean msn = FALSE;
 	msg2 = yahoo_string_encode(gc, msg, &utf8);
-	
+
 	if(msg2) {
 		lenb = strlen(msg2);
 		lenc = g_utf8_strlen(msg2, -1);
@@ -4174,13 +4198,11 @@
 			struct yahoo_sms_carrier_cb_data *sms_cb_data;
 			sms_cb_data = g_malloc(sizeof(struct yahoo_sms_carrier_cb_data));
 			sms_cb_data->gc = gc;
-			sms_cb_data->who = g_malloc(strlen(who));
-			sms_cb_data->what = g_malloc(strlen(what));
-			strcpy(sms_cb_data->who, who);
-			strcpy(sms_cb_data->what, what);
+			sms_cb_data->who = g_strdup(who);
+			sms_cb_data->what = g_strdup(what);
 
 			purple_conversation_write(conv, NULL, "Getting mobile carrier to send the sms", PURPLE_MESSAGE_SYSTEM, time(NULL));
-			
+
 			yahoo_get_sms_carrier(gc, sms_cb_data);
 
 			g_free(msg);
@@ -4299,7 +4321,7 @@
 	if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !msn ) {
 		yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc),
 	                  14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
-	                  5, who, 11, p2p_data->session_id, 1002, "1");	/* To-do: key 15 to be sent in case of p2p */	
+	                  5, who, 11, p2p_data->session_id, 1002, "1");	/* To-do: key 15 to be sent in case of p2p */
 		yahoo_p2p_write_pkt(p2p_data->source, pkt);
 		yahoo_packet_free(pkt);
 	}
--- a/libpurple/protocols/yahoo/yahoo.h	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo.h	Mon Jun 22 21:53:53 2009 +0000
@@ -53,7 +53,7 @@
 #define YAHOOJP_XFER_HOST "filetransfer.msg.yahoo.co.jp"
 #define YAHOOJP_WEBCAM_HOST "wc.yahoo.co.jp"
 /* not sure, must test: */
-#define YAHOOJP_XFER_RELAY_HOST "relay.msg.yahoo.co.jp" 
+#define YAHOOJP_XFER_RELAY_HOST "relay.msg.yahoo.co.jp"
 #define YAHOOJP_XFER_RELAY_PORT 80
 #define YAHOOJP_ROOMLIST_URL "http://insider.msg.yahoo.co.jp/ycontent/"
 #define YAHOOJP_ROOMLIST_LOCALE "ja"
@@ -201,7 +201,7 @@
 	GSList *url_datas;
 	GHashTable *xfer_peer_idstring_map;/* Hey, i dont know, but putting this HashTable next to friends gives a run time fault... */
 	GSList *cookies;/* contains all cookies, including _y and _t */
-	
+
 	/**
 	 * We may receive a list15 in multiple packets with no prior warning as to how many we'll be getting;
 	 * the server expects us to keep track of the group for which it is sending us contact names.
--- a/libpurple/protocols/yahoo/yahoo_aliases.h	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_aliases.h	Mon Jun 22 21:53:53 2009 +0000
@@ -1,38 +1,38 @@
-/*
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- *
- */
-
-
-#include "internal.h"
-
-#include "account.h"
-#include "accountopt.h"
-#include "blist.h"
-#include "debug.h"
-#include "util.h"
-#include "version.h"
-#include "yahoo.h"
-#include "yahoo_packet.h"
-
-void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias);
-void yahoo_fetch_aliases(PurpleConnection *gc);
-
+/*
+ * purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
+ *
+ */
+
+
+#include "internal.h"
+
+#include "account.h"
+#include "accountopt.h"
+#include "blist.h"
+#include "debug.h"
+#include "util.h"
+#include "version.h"
+#include "yahoo.h"
+#include "yahoo_packet.h"
+
+void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias);
+void yahoo_fetch_aliases(PurpleConnection *gc);
+
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c	Mon Jun 22 21:53:53 2009 +0000
@@ -320,7 +320,7 @@
 
 	if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
 		if (yd->jp) {
-			if (purple_proxy_connect(NULL, account, purple_account_get_string(account, "xferjp_host",  YAHOOJP_XFER_HOST),
+			if (purple_proxy_connect(gc, account, purple_account_get_string(account, "xferjp_host",  YAHOOJP_XFER_HOST),
 			                       purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),
 			                       yahoo_sendfile_connected, xfer) == NULL)
 			{
@@ -329,7 +329,7 @@
 				purple_xfer_cancel_remote(xfer);
 			}
 		} else {
-			if (purple_proxy_connect(NULL, account, purple_account_get_string(account, "xfer_host",  YAHOO_XFER_HOST),
+			if (purple_proxy_connect(gc, account, purple_account_get_string(account, "xfer_host",  YAHOO_XFER_HOST),
 			                       purple_account_get_int(account, "xfer_port", YAHOO_XFER_PORT),
 			                       yahoo_sendfile_connected, xfer) == NULL)
 			{
@@ -340,7 +340,7 @@
 		}
 	} else {
 		xfer->fd = -1;
-		if (purple_proxy_connect(NULL, account, xfer_data->host, xfer_data->port,
+		if (purple_proxy_connect(gc, account, xfer_data->host, xfer_data->port,
 		                              yahoo_receivefile_connected, xfer) == NULL) {
 			purple_notify_error(gc, NULL, _("File Transfer Failed"),
 			             _("Unable to establish file descriptor."));
@@ -380,12 +380,12 @@
 			28,  xfer->size,
 			301, 268,
 			303, 268);
-		g_free(filename); 
+		g_free(filename);
 	} else {
 		if(xfer_data->firstoflist == TRUE) {
 			pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_15,
 				YAHOO_STATUS_AVAILABLE, yd->session_id);
-	
+
 			yahoo_packet_hash(pkt, "sssi",
 				1, purple_normalize(account, purple_account_get_username(account)),
 				5, xfer->who,
@@ -394,7 +394,7 @@
 		} else {
 			pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
 				YAHOO_STATUS_AVAILABLE, yd->session_id);
-	
+
 			yahoo_packet_hash(pkt, "sssi",
 				1, purple_normalize(account, purple_account_get_username(account)),
 				5, xfer->who,
@@ -623,7 +623,7 @@
 	else if (written <= 0)
 		purple_debug_info("yahoo", "p2p filetransfer: Unable to write HTTP OK");
 
-	/* close connection */	
+	/* close connection */
 	close(xfer->fd);
 	xfer->fd = -1;
 	g_free(tx);
@@ -644,14 +644,14 @@
 		/* Send HTTP OK in case of p2p transfer, when we act as server */
 		if((xfer_data->xfer_url != NULL) && (xfer_old->fd >=0) && (purple_xfer_get_status(xfer_old) == PURPLE_XFER_STATUS_DONE))
 			yahoo_p2p_ft_server_send_OK(xfer_old);
-		
+
 		/* removing top of filename & size list completely */
 		g_free( xfer_data->filename_list->data );
 		g_free( xfer_data->size_list->data );
-		   
+
 		xfer_data->filename_list->data = NULL;
 		xfer_data->size_list->data = NULL;
-		   
+
 		xfer_data->filename_list = g_slist_delete_link(xfer_data->filename_list, xfer_data->filename_list);
 		xfer_data->size_list = g_slist_delete_link(xfer_data->size_list, xfer_data->size_list);
 
@@ -697,16 +697,16 @@
 			/* Build the file transfer handle. */
 			xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, xfer_old->who);
 
-			
+
 			if (xfer) {
 				/* Set the info about the incoming file. */
 				char *utf8_filename = yahoo_string_decode(gc, filename, TRUE);
 				purple_xfer_set_filename(xfer, utf8_filename);
 				g_free(utf8_filename);
 				purple_xfer_set_size(xfer, filesize);
-		
+
 				xfer->data = xfer_data;
-	
+
 				/* Setup our I/O op functions */
 				purple_xfer_set_init_fnc(xfer,        yahoo_xfer_init_15);
 				purple_xfer_set_start_fnc(xfer,       yahoo_xfer_start);
@@ -1003,7 +1003,7 @@
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
-	
+
 	/* Discard the length... */
 	hosts = g_slist_remove(hosts, hosts->data);
 	if(!hosts)
@@ -1012,7 +1012,7 @@
 		purple_xfer_cancel_remote(xfer);
 		return;
 	}
-	
+
 	/* TODO:actually, u must try with addr no.1 , if its not working addr no.2 ..... */
 	addr = hosts->data;
 	actaddr = addr->sin_addr.s_addr;
@@ -1113,14 +1113,15 @@
 	while((did = read(source, buf, 998)) > 0)
 	{
 		xd->txbuflen += did;
-		buf[did] = '\0';  
+		buf[did] = '\0';
 		t = xd->txbuf;
 		xd->txbuf = g_strconcat(t,buf,NULL);
 		g_free(t);
 	}
 	g_free(buf);
 
-	if (did < 0 && errno == EAGAIN) return;
+	if (did < 0 && errno == EAGAIN)
+		return;
 	else if (did < 0) {
 		purple_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno);
 		purple_xfer_cancel_remote(xfer);
@@ -1136,7 +1137,7 @@
 		close(source);/* Is this required? */
 		g_free(xd->txbuf);
 		xd->txbuf = NULL;
-		if (purple_proxy_connect(NULL, account, xd->host, xd->port, yahoo_xfer_connected_15, xfer) == NULL)
+		if (purple_proxy_connect(gc, account, xd->host, xd->port, yahoo_xfer_connected_15, xfer) == NULL)
 		{
 			purple_notify_error(gc, NULL, _("File Transfer Failed"),
 				_("Unable to establish file descriptor."));
@@ -1276,7 +1277,7 @@
 				}
 		}
 		else if(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE && xd->status_15 == STARTED)
-		{	
+		{
 			if(xd->info_val_249 == 1)
 				{
 				/* receiving file via p2p, connected as client */
@@ -1592,7 +1593,7 @@
 	GSList *filename_list = NULL;
 	GSList *size_list = NULL;
 	int nooffiles = 0;
-	
+
 	yd = gc->proto_data;
 
 	for (l = pkt->hash; l; l = l->next) {
@@ -1617,7 +1618,7 @@
 			break;
 		case 222:
 			val_222 = atol(pair->value);
-			/* 1=send, 2=cancel, 3=accept, 4=reject */ 
+			/* 1=send, 2=cancel, 3=accept, 4=reject */
 			break;
 
 		/* check for p2p and imviron .... not sure it comes by this service packet. Since it was bundled with filexfer in old ymsg version, still keeping it. */
@@ -1655,7 +1656,7 @@
 		*	so, purple dnsquery is used... but retries, trying with next ip
 		*	address etc. is not implemented..TODO
 		*/
-		
+
 		/* To send through p2p */
 		if( g_hash_table_lookup(yd->peers, from) )	{
 			/* send p2p file transfer information */
@@ -1685,7 +1686,7 @@
 		g_hash_table_replace(yd->imvironments, g_strdup(from), g_strdup(imv));
 		return;
 	}
-	
+
 	if (pkt->service == YAHOO_SERVICE_P2PFILEXFER) {
 		if (service && (strcmp("FILEXFER", service) != 0)) {
 			purple_debug_misc("yahoo", "unhandled service 0x%02x\n", pkt->service);
@@ -1710,7 +1711,7 @@
 	xfer_data->xfer_peer_idstring = g_strdup(xfer_peer_idstring);
 	xfer_data->filename_list = filename_list;
 	xfer_data->size_list = size_list;
-	
+
 	/* Build the file transfer handle. */
 	xfer = purple_xfer_new(gc->account, PURPLE_XFER_RECEIVE, from);
 	xfer->message = NULL;
@@ -1739,7 +1740,7 @@
 		g_hash_table_insert(yd->xfer_peer_idstring_map,
 							xfer_data->xfer_peer_idstring,
 							xfer);
-		
+
 		if(nooffiles > 1) {
 			gchar* message;
 			message = g_strdup_printf(_("%s is trying to send you a group of %d files.\n"), xfer->who, nooffiles);
@@ -1825,7 +1826,7 @@
 			purple_xfer_cancel_remote(xfer);
 			return;
 		}
-		
+
 		account = purple_connection_get_account(xfer_data->gc);
 
 		pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_FILETRANS_ACC_15,
@@ -1841,7 +1842,7 @@
 
 		yahoo_packet_send_and_free(pkt_to_send, yd);
 
-		if (purple_proxy_connect(NULL, account, xfer_data->host, xfer_data->port,
+		if (purple_proxy_connect(gc, account, xfer_data->host, xfer_data->port,
 			yahoo_xfer_connected_15, xfer) == NULL) {
 			purple_notify_error(gc, NULL, _("File Transfer Failed"),
 				_("Unable to establish file descriptor."));
@@ -1916,12 +1917,12 @@
 	xfer_data = xfer->data;
 	if(url)
 		purple_url_parse(url, &(xfer_data->host), &(xfer_data->port), &(xfer_data->path), NULL, NULL);
-		
+
 	xfer_data->xfer_idstring_for_relay = g_strdup(xfer_idstring_for_relay);
 	xfer_data->status_15 = ACCEPTED;
 	account = purple_connection_get_account(gc);
 
-	if (purple_proxy_connect(NULL, account, xfer_data->host, xfer_data->port,
+	if (purple_proxy_connect(gc, account, xfer_data->host, xfer_data->port,
 		yahoo_xfer_connected_15, xfer) == NULL)
 	{
 		purple_notify_error(gc, NULL, _("File Transfer Failed"),_("Unable to connect"));
--- a/libpurple/protocols/yahoo/yahoo_packet.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_packet.c	Mon Jun 22 21:53:53 2009 +0000
@@ -195,7 +195,7 @@
 						   "Key: %d  \tValue: %s\n", pair->key, esc);
 				g_free(esc);
 			}
-#endif
+#endif /* DEBUG */
 		} else {
 			g_free(pair);
 		}
@@ -282,7 +282,7 @@
 	}
 
 	purple_debug(PURPLE_DEBUG_MISC, NULL, "\n");
-#endif
+#endif /* YAHOO_DEBUG */
 }
 
 static void
@@ -329,7 +329,7 @@
 	if (wm)
 		pos += yahoo_put16(data + pos, YAHOO_WEBMESSENGER_PROTO_VER);
 	else if (jp)
-		pos += yahoo_put16(data + pos, YAHOO_PROTO_VER_JAPAN);		
+		pos += yahoo_put16(data + pos, YAHOO_PROTO_VER_JAPAN);
 	else
 		pos += yahoo_put16(data + pos, YAHOO_PROTO_VER);
 	pos += yahoo_put16(data + pos, 0x0000);
--- a/libpurple/protocols/yahoo/yahoo_packet.h	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_packet.h	Mon Jun 22 21:53:53 2009 +0000
@@ -107,6 +107,7 @@
 	YAHOO_SERVICE_CHGRP_15 = 0xe7,
 	YAHOO_SERVICE_STATUS_15 = 0xf0,
 	YAHOO_SERVICE_LIST_15 = 0xf1,
+	YAHOO_SERVICE_MESSAGE_ACK = 0xfb,
 	YAHOO_SERVICE_WEBLOGIN = 0x0226,
 	YAHOO_SERVICE_SMS_MSG = 0x02ea
 	/* YAHOO_SERVICE_DISCONNECT = 0x07d1 Server forces us to disconnect. Is sent with TCP FIN flag set */
--- a/libpurple/protocols/yahoo/yahoo_picture.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_picture.c	Mon Jun 22 21:53:53 2009 +0000
@@ -126,7 +126,7 @@
 		gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
 
 		/* FIXME: Cleanup this strtol() stuff if possible. */
-		if (b && (locksum = purple_buddy_icons_get_checksum_for_user(b)) != NULL && 
+		if (b && (locksum = purple_buddy_icons_get_checksum_for_user(b)) != NULL &&
 				(checksum == strtol(locksum, NULL, 10)))
 			return;
 
@@ -506,7 +506,7 @@
 		"Content-Length: %" G_GSIZE_FORMAT "\r\n"
 		"Cache-Control: no-cache\r\n\r\n",
 		use_whole_url ? "http://" : "", use_whole_url ? tmp : "",
-		yd->cookie_t, yd->cookie_y, 
+		yd->cookie_t, yd->cookie_y,
 		tmp,
 		pkt_buf_len + 4 + d->str->len);
 	g_free(tmp);
@@ -573,7 +573,7 @@
 	purple_debug_misc("yahoo", "Calculated buddy icon checksum: %d\n", checksum);
 
 	return checksum;
-} 
+}
 
 void yahoo_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img)
 {
--- a/libpurple/protocols/yahoo/yahoo_profile.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_profile.c	Mon Jun 22 21:53:53 2009 +0000
@@ -29,7 +29,7 @@
 #include "util.h"
 #if PHOTO_SUPPORT
 #include "imgstore.h"
-#endif
+#endif /* PHOTO_SUPPORT */
 
 #include "yahoo.h"
 #include "yahoo_friend.h"
@@ -40,11 +40,11 @@
 } YahooGetInfoData;
 
 typedef enum profile_lang_id {
-	XX, DA, DE, EL, 
-	EN, EN_GB, 
+	XX, DA, DE, EL,
+	EN, EN_GB,
 	ES_AR, ES_ES, ES_MX, ES_US,
-	FR_CA, FR_FR, 
-	IT, JA, KO, NO, PT, SV, 
+	FR_CA, FR_FR,
+	IT, JA, KO, NO, PT, SV,
 	ZH_CN, ZH_HK, ZH_TW, ZH_US, PT_BR
 } profile_lang_id_t;
 
@@ -702,7 +702,7 @@
 		const char *balias = purple_buddy_get_local_buddy_alias(b);
 		if(balias && balias[0]) {
 			char *aliastext = g_markup_escape_text(balias, -1);
-			purple_notify_user_info_add_pair(user_info, _("Alias"), aliastext); 
+			purple_notify_user_info_add_pair(user_info, _("Alias"), aliastext);
 			g_free(aliastext);
 		}
 		#if 0
@@ -777,7 +777,7 @@
 	char *stripped;
 	int stripped_len;
 	char *last_updated_utf8_string = NULL;
-#endif
+#endif /* !PHOTO_SUPPORT */
 	const char *last_updated_string = NULL;
 	char *url_buffer;
 	GString *s;
@@ -899,7 +899,7 @@
 
 #if PHOTO_SUPPORT
 	photo_url_text = yahoo_get_photo_url(url_text, info_data->name);
-#endif
+#endif /* PHOTO_SUPPORT */
 
 	url_buffer = g_strdup(url_text);
 
@@ -1048,7 +1048,7 @@
 			purple_debug_info("yahoo", "%s is %" G_GSIZE_FORMAT
 					" bytes\n", photo_url_text, len);
 			id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
-			
+
 			tmp = g_strdup_printf("<img id=\"%d\"><br>", id);
 			purple_notify_user_info_add_pair(user_info, NULL, tmp);
 			g_free(tmp);
@@ -1259,7 +1259,7 @@
 	g_free(info2_data);
 	if (id != -1)
 		purple_imgstore_unref_by_id(id);
-#endif
+#endif /* PHOTO_SUPPORT */
 }
 
 void yahoo_get_info(PurpleConnection *gc, const char *name)
--- a/libpurple/protocols/yahoo/yahoochat.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoochat.c	Mon Jun 22 21:53:53 2009 +0000
@@ -30,7 +30,7 @@
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif /* HAVE_CONFIG_H */
 
 #include "debug.h"
 #include "privacy.h"
@@ -1519,7 +1519,7 @@
 
 	purple_roomlist_set_fields(rl, fields);
 
-	if (purple_proxy_connect(NULL, account, yrl->host, 80,
+	if (purple_proxy_connect(gc, account, yrl->host, 80,
 	                       yahoo_roomlist_got_connected, yrl) == NULL)
 	{
 		purple_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list."));
@@ -1588,8 +1588,9 @@
 	yrl->ucat = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat);
 	purple_roomlist_room_add(list, yrl->ucat);
 
-	if (purple_proxy_connect(NULL, list->account, yrl->host, 80,
-	                       yahoo_roomlist_got_connected, yrl) == NULL)
+	if (purple_proxy_connect(purple_account_get_connection(list->account),
+			list->account, yrl->host, 80,
+			yahoo_roomlist_got_connected, yrl) == NULL)
 	{
 		purple_notify_error(purple_account_get_connection(list->account),
 		                  NULL, _("Connection problem"), _("Unable to fetch room list."));
--- a/libpurple/protocols/yahoo/ycht.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/protocols/yahoo/ycht.c	Mon Jun 22 21:53:53 2009 +0000
@@ -225,7 +225,7 @@
 	}
 
 	purple_debug(PURPLE_DEBUG_MISC, NULL, "\n");
-#endif
+#endif /* YAHOO_YCHT_DEBUG */
 }
 
 static YchtPkt *ycht_packet_new(guint version, guint service, int status)
@@ -578,7 +578,7 @@
 
 	yd->ycht = ycht;
 
-	if (purple_proxy_connect(NULL, account,
+	if (purple_proxy_connect(gc, account,
 	                       purple_account_get_string(account, "ycht-server",  YAHOO_YCHT_HOST),
 	                       purple_account_get_int(account, "ycht-port", YAHOO_YCHT_PORT),
 	                       ycht_got_connected, ycht) == NULL)
--- a/libpurple/util.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/util.c	Mon Jun 22 21:53:53 2009 +0000
@@ -3898,7 +3898,7 @@
 	url_fetch_recv_cb(data, -1, cond);
 }
 
-/*
+/**
  * This function is called when the socket is available to be written
  * to.
  *
--- a/libpurple/xmlnode.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/xmlnode.c	Mon Jun 22 21:53:53 2009 +0000
@@ -382,7 +382,7 @@
 }
 
 char *
-xmlnode_get_data(xmlnode *node)
+xmlnode_get_data(const xmlnode *node)
 {
 	GString *str = NULL;
 	xmlnode *c;
@@ -405,7 +405,7 @@
 }
 
 char *
-xmlnode_get_data_unescaped(xmlnode *node)
+xmlnode_get_data_unescaped(const xmlnode *node)
 {
 	char *escaped = xmlnode_get_data(node);
 
--- a/libpurple/xmlnode.h	Mon Jun 08 18:28:31 2009 +0000
+++ b/libpurple/xmlnode.h	Mon Jun 22 21:53:53 2009 +0000
@@ -136,7 +136,7 @@
  * @return The data from the node or NULL. This data is in raw escaped format.
  *         You must g_free this string when finished using it.
  */
-char *xmlnode_get_data(xmlnode *node);
+char *xmlnode_get_data(const xmlnode *node);
 
 /**
  * Gets unescaped data from a node.
@@ -146,7 +146,7 @@
  * @return The data from the node, in unescaped form.   You must g_free
  *         this string when finished using it.
  */
-char *xmlnode_get_data_unescaped(xmlnode *node);
+char *xmlnode_get_data_unescaped(const xmlnode *node);
 
 /**
  * Sets an attribute for a node.
--- a/pidgin/eggtrayicon.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/eggtrayicon.c	Mon Jun 22 21:53:53 2009 +0000
@@ -400,9 +400,35 @@
 static gboolean
 transparent_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
 {
-	gdk_window_clear_area (widget->window, event->area.x, event->area.y,
-	                      event->area.width, event->area.height);
-	return FALSE;
+  GtkWidget *focus_child = NULL;
+  gint border_width, x, y, width, height;
+  gboolean retval = FALSE;
+
+  gdk_window_clear_area (widget->window, event->area.x, event->area.y,
+                         event->area.width, event->area.height);
+
+  if (GTK_WIDGET_CLASS (parent_class)->expose_event)
+    retval = GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+
+  if (GTK_CONTAINER (widget)->focus_child)
+    focus_child = GTK_CONTAINER (GTK_CONTAINER (widget)->focus_child)->focus_child;
+  if (focus_child && GTK_WIDGET_HAS_FOCUS (focus_child))
+    {
+      border_width = GTK_CONTAINER (widget)->border_width;
+
+      x = widget->allocation.x + border_width;
+      y = widget->allocation.y + border_width;
+
+      width  = widget->allocation.width  - 2 * border_width;
+      height = widget->allocation.height - 2 * border_width;
+
+      gtk_paint_focus (widget->style, widget->window,
+                       GTK_WIDGET_STATE (widget),
+                       &event->area, widget, "tray_icon",
+                       x, y, width, height);
+    }
+
+  return retval;
 }
 
 static void
--- a/pidgin/gtkdocklet-x11.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/gtkdocklet-x11.c	Mon Jun 22 21:53:53 2009 +0000
@@ -32,6 +32,7 @@
 
 #include "eggtrayicon.h"
 #include "gtkdocklet.h"
+#include <gdk/gdkkeysyms.h>
 
 #define SHORT_EMBED_TIMEOUT 5000
 #define LONG_EMBED_TIMEOUT 15000
@@ -89,6 +90,33 @@
 	return TRUE;
 }
 
+static gboolean
+docklet_x11_pressed_cb(GtkWidget *button, GdkEventKey *event)
+{
+	guint state, keyval;
+
+	state = event->state & gtk_accelerator_get_default_mod_mask();
+	keyval = event->keyval;
+	if (state == 0 &&
+	    (keyval == GDK_Return ||
+	     keyval == GDK_KP_Enter ||
+	     keyval == GDK_ISO_Enter ||
+	     keyval == GDK_space ||
+	     keyval == GDK_KP_Space))
+	{
+		pidgin_docklet_clicked(1);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+docklet_x11_popup_cb(GtkWidget *button)
+{
+	pidgin_docklet_clicked(3);
+}
+
 static void
 docklet_x11_update_icon(PurpleStatusPrimitive status, gboolean connecting, gboolean pending)
 {
@@ -259,11 +287,14 @@
 	docklet = egg_tray_icon_new(PIDGIN_NAME);
 	box = gtk_event_box_new();
 	image = gtk_image_new();
+	GTK_WIDGET_SET_FLAGS (image, GTK_CAN_FOCUS);
 
 	g_signal_connect(G_OBJECT(docklet), "embedded", G_CALLBACK(docklet_x11_embedded_cb), NULL);
 	g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_x11_destroyed_cb), NULL);
 	g_signal_connect(G_OBJECT(docklet), "size-allocate", G_CALLBACK(docklet_x11_resize_icon), NULL);
 	g_signal_connect(G_OBJECT(box), "button-press-event", G_CALLBACK(docklet_x11_clicked_cb), NULL);
+	g_signal_connect(G_OBJECT(box), "key-press-event", G_CALLBACK(docklet_x11_pressed_cb), NULL);
+	g_signal_connect(G_OBJECT(box), "popup-menu", G_CALLBACK(docklet_x11_popup_cb), NULL);
 	gtk_container_add(GTK_CONTAINER(box), image);
 	gtk_container_add(GTK_CONTAINER(docklet), box);
 
--- a/pidgin/gtkft.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/gtkft.c	Mon Jun 22 21:53:53 2009 +0000
@@ -705,12 +705,12 @@
 	};
 
 	/* Setup the initial table */
-	dialog->table = table = gtk_table_new(9, 2, FALSE);
+	dialog->table = table = gtk_table_new(G_N_ELEMENTS(labels) + 1, 2, FALSE);
 	gtk_table_set_row_spacings(GTK_TABLE(table), PIDGIN_HIG_BOX_SPACE);
 	gtk_table_set_col_spacings(GTK_TABLE(table), PIDGIN_HIG_BOX_SPACE);
 
 	/* Setup the labels */
-	for (i = 0; i < sizeof(labels) / sizeof(*labels); i++) {
+	for (i = 0; i < G_N_ELEMENTS(labels); i++) {
 		GtkWidget *label;
 		char buf[256];
 
@@ -734,7 +734,9 @@
 
 	/* Setup the progress bar */
 	dialog->progress = gtk_progress_bar_new();
-	gtk_table_attach(GTK_TABLE(table), dialog->progress, 0, 2, 8, 9,
+	gtk_table_attach(GTK_TABLE(table), dialog->progress,
+					 0, 2,
+					 G_N_ELEMENTS(labels), G_N_ELEMENTS(labels) + 1,
 					 GTK_FILL, GTK_FILL, 0, 0);
 	gtk_widget_show(dialog->progress);
 
--- a/pidgin/gtkicon-theme-loader.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/gtkicon-theme-loader.c	Mon Jun 22 21:53:53 2009 +0000
@@ -41,7 +41,7 @@
 	filename_full = g_build_filename(dir, "theme.xml", NULL);
 
 	if (g_file_test(filename_full, G_FILE_TEST_IS_REGULAR))
-		root_node = xmlnode_from_file(dir, "theme.xml", "sound themes", "sound-theme-loader");
+		root_node = xmlnode_from_file(dir, "theme.xml", "icon themes", "icon-theme-loader");
 
 	g_free(filename_full);
 	g_return_val_if_fail(root_node != NULL, NULL);
--- a/pidgin/gtkimhtml.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/gtkimhtml.c	Mon Jun 22 21:53:53 2009 +0000
@@ -2996,10 +2996,21 @@
 							break;
 
 						id = gtk_imhtml_get_html_opt(tag, "ID=");
-						if (!id)
-							break;
-						gtk_imhtml_insert_image_at_iter(imhtml, atoi(id), iter);
-						g_free(id);
+						if (id) {
+							gtk_imhtml_insert_image_at_iter(imhtml, atoi(id), iter);
+							g_free(id);
+						} else {
+							char *src, *alt;
+							src = gtk_imhtml_get_html_opt(tag, "SRC=");
+							alt = gtk_imhtml_get_html_opt(tag, "ALT=");
+							if (src) {
+								gtk_imhtml_toggle_link(imhtml, src);
+								gtk_text_buffer_insert(imhtml->text_buffer, iter, alt ? alt : src, -1);
+								gtk_imhtml_toggle_link(imhtml, NULL);
+							}
+							g_free (src);
+							g_free (alt);
+						}
 						break;
 					}
 				case 47:	/* P (opt) */
--- a/pidgin/gtkstatusbox.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/gtkstatusbox.c	Mon Jun 22 21:53:53 2009 +0000
@@ -2045,17 +2045,11 @@
 
 	if (status_box->icon_box)
 	{
-		GtkTextDirection dir = gtk_widget_get_direction(widget);
 		parent_alc.width -= (parent_alc.height + border_width);
 		icon_alc = parent_alc;
 		icon_alc.height = MAX(1, icon_alc.height) - 2;
 		icon_alc.width = icon_alc.height;
-		if (dir == GTK_TEXT_DIR_RTL) {
-			icon_alc.x = parent_alc.x;
-			parent_alc.x += icon_alc.width + border_width;
-		} else {
-			icon_alc.x = allocation->width - (icon_alc.width + border_width + 1);
-		}
+		icon_alc.x = allocation->width - (icon_alc.width + border_width + 1);
 		icon_alc.y += 1;
 
 		if (status_box->icon_size != icon_alc.height)
@@ -2264,14 +2258,22 @@
 
 	if (status_box->buddy_icon_img != NULL)
 	{
+		GdkPixbuf *buf, *scale;
+		int scale_width, scale_height;
 		GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
 		g_signal_connect(G_OBJECT(loader), "size-prepared", G_CALLBACK(pixbuf_size_prepared_cb), NULL);
 		gdk_pixbuf_loader_write(loader, purple_imgstore_get_data(status_box->buddy_icon_img),
 		                        purple_imgstore_get_size(status_box->buddy_icon_img), NULL);
 		gdk_pixbuf_loader_close(loader, NULL);
-		status_box->buddy_icon = gdk_pixbuf_loader_get_pixbuf(loader);
-		if (status_box->buddy_icon)
-			g_object_ref(status_box->buddy_icon);
+		buf = gdk_pixbuf_loader_get_pixbuf(loader);
+		scale_width = gdk_pixbuf_get_width(buf);
+		scale_height = gdk_pixbuf_get_height(buf);
+		scale = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_width, scale_height);
+		gdk_pixbuf_fill(scale, 0x00000000);
+		gdk_pixbuf_copy_area(buf, 0, 0, scale_width, scale_height, scale, 0, 0);
+		if (pidgin_gdk_pixbuf_is_opaque(scale))
+			pidgin_gdk_pixbuf_make_round(scale);
+		status_box->buddy_icon = scale;
 		g_object_unref(loader);
 	}
 
--- a/pidgin/plugins/Makefile.mingw	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/plugins/Makefile.mingw	Mon Jun 22 21:53:53 2009 +0000
@@ -7,6 +7,7 @@
 PIDGIN_TREE_TOP := ../..
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
+DISCO_PLUGIN := ./disco
 GTKPERL_PLUGIN := ./perl
 TICKER_PLUGIN := ./ticker
 TRANSPARENCY_PLUGIN := ./win32/transparency
@@ -58,12 +59,14 @@
 .PHONY: all clean plugins install
 
 all: plugins
+	$(MAKE) -C $(DISCO_PLUGIN) -f $(MINGW_MAKEFILE)
 	$(MAKE) -C $(GTKPERL_PLUGIN) -f $(MINGW_MAKEFILE)
 	$(MAKE) -C $(TICKER_PLUGIN) -f $(MINGW_MAKEFILE)
 	$(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(MINGW_MAKEFILE)
 	$(MAKE) -C $(WINPREFS_PLUGIN) -f $(MINGW_MAKEFILE)
 
 install: all $(PIDGIN_INSTALL_PLUGINS_DIR)
+	$(MAKE) -C $(DISCO_PLUGIN) -f $(MINGW_MAKEFILE) install
 	$(MAKE) -C $(GTKPERL_PLUGIN) -f $(MINGW_MAKEFILE) install
 	$(MAKE) -C $(TICKER_PLUGIN) -f $(MINGW_MAKEFILE) install
 	$(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(MINGW_MAKEFILE) install
@@ -95,6 +98,7 @@
 ##
 clean:
 	rm -f *.o *.dll
+	$(MAKE) -C $(DISCO_PLUGIN) -f $(MINGW_MAKEFILE) clean
 	$(MAKE) -C $(GTKPERL_PLUGIN) -f $(MINGW_MAKEFILE) clean
 	$(MAKE) -C $(TICKER_PLUGIN) -f $(MINGW_MAKEFILE) clean
 	$(MAKE) -C $(TRANSPARENCY_PLUGIN) -f $(MINGW_MAKEFILE) clean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/plugins/disco/Makefile.mingw	Mon Jun 22 21:53:53 2009 +0000
@@ -0,0 +1,79 @@
+#
+# Makefile.mingw
+#
+# Description: Makefile for xmppdisco plugin.
+#
+
+PIDGIN_TREE_TOP := ../../..
+include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
+
+TARGET = xmppdisco
+
+##
+## INCLUDE PATHS
+##
+INCLUDE_PATHS +=	-I. \
+			-I$(GTK_TOP)/include \
+			-I$(GTK_TOP)/include/gtk-2.0 \
+			-I$(GTK_TOP)/include/glib-2.0 \
+			-I$(GTK_TOP)/include/pango-1.0 \
+			-I$(GTK_TOP)/include/atk-1.0 \
+			-I$(GTK_TOP)/include/cairo \
+			-I$(GTK_TOP)/lib/glib-2.0/include \
+			-I$(GTK_TOP)/lib/gtk-2.0/include \
+			-I$(PURPLE_TOP) \
+			-I$(PURPLE_TOP)/win32 \
+			-I$(PIDGIN_TOP) \
+			-I$(PIDGIN_TOP)/win32 \
+			-I$(PIDGIN_TREE_TOP)
+
+LIB_PATHS +=		-L$(GTK_TOP)/lib \
+			-L$(PURPLE_TOP) \
+			-L$(PIDGIN_TOP)
+
+##
+##  SOURCES, OBJECTS
+##
+C_SRC =			xmppdisco.c \
+			gtkdisco.c
+
+OBJECTS = $(C_SRC:%.c=%.o)
+
+##
+## LIBRARIES
+##
+LIBS =			-lgtk-win32-2.0 \
+			-lglib-2.0 \
+			-lgdk-win32-2.0 \
+			-lgobject-2.0 \
+			-lpango-1.0 \
+			-lgdk_pixbuf-2.0 \
+			-lintl \
+			-lpurple \
+			-lpidgin
+
+include $(PIDGIN_COMMON_RULES)
+
+##
+## TARGET DEFINITIONS
+##
+.PHONY: all install clean
+
+all: $(TARGET).dll
+
+install: $(PIDGIN_INSTALL_PLUGINS_DIR) all
+	cp $(TARGET).dll $(PIDGIN_INSTALL_PLUGINS_DIR)
+
+$(OBJECTS): $(PIDGIN_CONFIG_H)
+
+$(TARGET).dll: $(PURPLE_DLL).a $(PIDGIN_DLL).a $(OBJECTS)
+	$(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -o $(TARGET).dll
+
+##
+## CLEAN RULES
+##
+clean:
+	rm -rf $(OBJECTS)
+	rm -rf $(TARGET).dll
+
+include $(PIDGIN_COMMON_TARGETS)
--- a/pidgin/plugins/gevolution/gevolution.c	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/plugins/gevolution/gevolution.c	Mon Jun 22 21:53:53 2009 +0000
@@ -39,6 +39,7 @@
 #include <libedata-book/Evolution-DataServer-Addressbook.h>
 
 #include <libedata-book/e-data-book-factory.h>
+/* TODO: bonobo is going away eventually, we'll need to find an alternative */
 #include <bonobo/bonobo-main.h>
 
 #include <glib.h>
--- a/pidgin/win32/nsis/pidgin-installer.nsi	Mon Jun 08 18:28:31 2009 +0000
+++ b/pidgin/win32/nsis/pidgin-installer.nsi	Mon Jun 22 21:53:53 2009 +0000
@@ -773,6 +773,7 @@
     Delete "$INSTDIR\plugins\win2ktrans.dll"
     Delete "$INSTDIR\plugins\winprefs.dll"
     Delete "$INSTDIR\plugins\xmppconsole.dll"
+    Delete "$INSTDIR\plugins\xmppdisco.dll"
     RMDir "$INSTDIR\plugins"
     RMDir /r "$INSTDIR\sasl2"
     Delete "$INSTDIR\sounds\purple\alert.wav"
--- a/po/de.po	Mon Jun 08 18:28:31 2009 +0000
+++ b/po/de.po	Mon Jun 22 21:53:53 2009 +0000
@@ -11,9 +11,9 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-06-01 12:31+0200\n"
-"PO-Revision-Date: 2009-06-01 12:31+0200\n"
-"Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
+"POT-Creation-Date: 2009-06-11 12:42+0200\n"
+"PO-Revision-Date: 2009-06-11 12:40+0200\n"
+"Last-Translator: Bjoern Voigt <bjoern@cs.tu-berlin.de>\n"
 "Language-Team: Deutsch <de@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -877,7 +877,7 @@
 msgstr "System-Mitschnitt"
 
 msgid "Calling ... "
-msgstr "Anrufen..."
+msgstr "Anrufen ... "
 
 msgid "Hangup"
 msgstr "Auflegen"
@@ -3169,6 +3169,10 @@
 msgid "Chat _name:"
 msgstr "Chat_name:"
 
+#. should this be a settings error?
+msgid "Unable to resolve server"
+msgstr "Verbindung zum Server nicht möglich"
+
 msgid "Chat error"
 msgstr "Chatfehler"
 
@@ -3217,6 +3221,10 @@
 msgid "Gadu-Gadu User"
 msgstr "Gadu-Gadu-Benutzer"
 
+#, fuzzy
+msgid "GG server"
+msgstr "Hole server"
+
 #, c-format
 msgid "Unknown command: %s"
 msgstr "Unbekanntes Kommando: %s"
@@ -3463,7 +3471,7 @@
 #. notify the user that their /nick command didn't go.
 #, c-format
 msgid "The nickname \"%s\" is already being used."
-msgstr "Der Spitzname \"%s\" existiert bereits."
+msgstr "Der Spitzname „%s“ existiert bereits."
 
 #, fuzzy
 msgid "Nickname in use"
@@ -4215,9 +4223,8 @@
 msgid "Invalid XMPP ID. Domain must be set."
 msgstr "Falsche XMPP-ID. Die Domain muss gesetzt werden."
 
-#, fuzzy
 msgid "Malformed BOSH Connect Server"
-msgstr "Verbindung zum Server nicht möglich."
+msgstr ""
 
 #, c-format
 msgid "Registration of %s@%s successful"
@@ -4243,9 +4250,6 @@
 msgid "Unregistration Failed"
 msgstr "Aufheben der Registrierung gescheitert"
 
-msgid "Already Registered"
-msgstr "Schon registriert"
-
 msgid "State"
 msgstr "Provinz/Bundesland"
 
@@ -4258,6 +4262,9 @@
 msgid "Date"
 msgstr "Datum"
 
+msgid "Already Registered"
+msgstr "Schon registriert"
+
 msgid "Unregister"
 msgstr "Aufheben der Registrierung"
 
@@ -4631,7 +4638,7 @@
 "session."
 msgstr ""
 "Bitte wählen Sie die Ressource von %s, mir der Sie eine Medien-Sitzung "
-"starten möchten"
+"starten möchten."
 
 msgid "Select a Resource"
 msgstr "Wählen Sie eine Ressource"
@@ -4795,12 +4802,11 @@
 msgid "Error in chat %s"
 msgstr "Fehler im Chat %s"
 
-#, fuzzy
 msgid "An error occured on the in-band bytestream transfer\n"
-msgstr "Beim Öffnen der Datei trat ein Fehler auf."
+msgstr "Beim Übertragen der Datei trat ein Fehler auf\n"
 
 msgid "Transfer was closed."
-msgstr "Übertragung wurde geschlossen"
+msgstr "Übertragung wurde geschlossen."
 
 msgid "Failed to open the file"
 msgstr "Öffnen der Datei fehlgeschlagen"
@@ -5441,32 +5447,6 @@
 msgid "The following users are missing from your addressbook"
 msgstr "Die folgenden Benutzer fehlen in Ihrem Adressbuch"
 
-#, c-format
-msgid "Unable to add user on %s (%s)"
-msgstr "Kann den Benutzer nicht zu %s (%s) hinzufügen"
-
-#, c-format
-msgid "Unable to block user on %s (%s)"
-msgstr "Kann den Benutzer nicht für %s (%s) blockieren"
-
-#, c-format
-msgid "Unable to permit user on %s (%s)"
-msgstr "Kann den Benutzer nicht für %s (%s) erlauben"
-
-#, c-format
-msgid "%s could not be added because your buddy list is full."
-msgstr "%s konnte nicht hinzugefügt werden, da Ihre Buddy-Liste voll ist."
-
-#, c-format
-msgid "%s is not a valid passport account."
-msgstr "%s ist kein gültiges Passport-Konto."
-
-msgid "Service Temporarily Unavailable."
-msgstr "Dienst momentan nicht verfügbar."
-
-msgid "Unknown error."
-msgstr "Unbekannter Fehler."
-
 msgid "Mobile message was not sent because it was too long."
 msgstr "Mobile Nachricht wurde nicht gesendet, da sie zu lang war."
 
@@ -5566,6 +5546,9 @@
 "Ihre MSN-Buddy-Liste ist temporär nicht verfügbar. Bitte warten Sie und "
 "versuchen Sie es später nochmal."
 
+msgid "Unknown error."
+msgstr "Unbekannter Fehler."
+
 msgid "Handshaking"
 msgstr "Abgleich"
 
@@ -5669,6 +5652,29 @@
 msgid "%s on %s (%s)"
 msgstr "%s auf %s (%s)"
 
+#, c-format
+msgid "Unable to add user on %s (%s)"
+msgstr "Kann den Benutzer nicht zu %s (%s) hinzufügen"
+
+#, c-format
+msgid "Unable to block user on %s (%s)"
+msgstr "Kann den Benutzer nicht für %s (%s) blockieren"
+
+#, c-format
+msgid "Unable to permit user on %s (%s)"
+msgstr "Kann den Benutzer nicht für %s (%s) erlauben"
+
+#, c-format
+msgid "%s could not be added because your buddy list is full."
+msgstr "%s konnte nicht hinzugefügt werden, da Ihre Buddy-Liste voll ist."
+
+#, c-format
+msgid "%s is not a valid passport account."
+msgstr "%s ist kein gültiges Passport-Konto."
+
+msgid "Service Temporarily Unavailable."
+msgstr "Dienst momentan nicht verfügbar."
+
 msgid "Unable to rename group"
 msgstr "Kann die Gruppe nicht umbenennen"
 
@@ -6783,7 +6789,7 @@
 msgstr "Möchten Sie diesen Buddy zu Ihrer Buddy-Liste hinzufügen?"
 
 msgid "_Add"
-msgstr "_Hinzufügen"
+msgstr "Hinzu_fügen"
 
 msgid "_Decline"
 msgstr "_Ablehnen"
@@ -9568,16 +9574,26 @@
 msgstr "Falsches Passwort"
 
 #. security lock from too many failed login attempts
-msgid "Account locked: Too many failed login attempts"
-msgstr "Konto gesperrt: Zu viele erfolglose Login-Versuche"
+#, fuzzy
+msgid ""
+"Account locked: Too many failed login attempts.\n"
+"Logging into the Yahoo! website may fix this."
+msgstr ""
+"Unbekannte Fehlernummer %d. Vielleicht kann dies repariert werden, wenn Sie "
+"sich auf der Yahoo! Webseite anmelden."
 
 #. the username does not exist
 msgid "Username does not exist"
 msgstr "Benutzername existiert nicht"
 
 #. indicates a lock of some description
-msgid "Account locked: See the debug log"
-msgstr "Konto gesperrt: Sehen Sie in den Debug-Mitschnitt"
+#, fuzzy
+msgid ""
+"Account locked: Unknown reason.\n"
+"Logging into the Yahoo! website may fix this."
+msgstr ""
+"Unbekannte Fehlernummer %d. Vielleicht kann dies repariert werden, wenn Sie "
+"sich auf der Yahoo! Webseite anmelden."
 
 #. username or password missing
 msgid "Username or password missing"
@@ -10492,9 +10508,8 @@
 msgid "Please update the necessary fields."
 msgstr "Bitte aktualisieren Sie die erforderlichen Felder."
 
-#, fuzzy
 msgid "A_ccount"
-msgstr "Konto"
+msgstr "K_onto"
 
 msgid ""
 "Please enter the appropriate information about the chat you would like to "
@@ -11646,7 +11661,7 @@
 msgstr "_Name"
 
 msgid "_Account"
-msgstr "_Konto"
+msgstr "K_onto"
 
 msgid "Get User Info"
 msgstr "Benutzer-Info abrufen"
@@ -12400,19 +12415,19 @@
 msgstr "Bei wem alarmieren"
 
 msgid "_Account:"
-msgstr "_Konto:"
+msgstr "K_onto:"
 
 msgid "_Buddy name:"
-msgstr "_Buddy-Name:"
+msgstr "Budd_y-Name:"
 
 msgid "Si_gns on"
-msgstr "_sich anmeldet"
+msgstr "si_ch anmeldet"
 
 msgid "Signs o_ff"
 msgstr "sich abmel_det"
 
 msgid "Goes a_way"
-msgstr "_hinausgeht"
+msgstr "hinausgeh_t"
 
 msgid "Ret_urns from away"
 msgstr "wi_eder anwesend ist"
@@ -12421,22 +12436,22 @@
 msgstr "_untätig wird"
 
 msgid "Is no longer i_dle"
-msgstr "nicht meh_r untätig ist"
+msgstr "nicht _mehr untätig ist"
 
 msgid "Starts _typing"
-msgstr "zu _tippen beginnt"
+msgstr "zu tippen _beginnt"
 
 msgid "P_auses while typing"
-msgstr "beim Tippen an_hält"
+msgstr "beim Tippen anh_ält"
 
 msgid "Stops t_yping"
 msgstr "aufhört _zu tippen"
 
 msgid "Sends a _message"
-msgstr "eine _Nachricht sendet"
+msgstr "eine Nachr_icht sendet"
 
 msgid "Ope_n an IM window"
-msgstr "Gesprächsfenster ö_ffnen"
+msgstr "_Gesprächsfenster öffnen"
 
 msgid "_Pop up a notification"
 msgstr "_Popup-Benachrichtigung"
@@ -12445,22 +12460,22 @@
 msgstr "_Nachricht senden"
 
 msgid "E_xecute a command"
-msgstr "Befeh_l ausführen"
+msgstr "Befehl ausfüh_ren"
 
 msgid "P_lay a sound"
-msgstr "einen _Klang abspielen"
+msgstr "Einen _Klang abspielen"
 
 msgid "Brows_e..."
-msgstr "Aus_wählen..."
+msgstr "Au_swählen..."
 
 msgid "Br_owse..."
-msgstr "Aus_wählen..."
+msgstr "Auswäh_len..."
 
 msgid "Pre_view"
 msgstr "_Vorschau"
 
 msgid "P_ounce only when my status is not Available"
-msgstr "Nur _alarmieren, wenn ich nicht verfügbar bin"
+msgstr "Nur alarmieren, wenn ich nicht ver_fügbar bin"
 
 msgid "_Recurring"
 msgstr "_Wiederkehrend"
@@ -13802,12 +13817,6 @@
 "- Es sendet eine Nachricht zu Leuten in Ihrer Buddy Liste, direkt wenn Sie "
 "sich angemeldet haben"
 
-msgid "Cursor Color"
-msgstr "Cursor-Farbe"
-
-msgid "Secondary Cursor Color"
-msgstr "Sekundäre Cursor-Farbe"
-
 msgid "Hyperlink Color"
 msgstr "Hyperlink-Farbe"
 
@@ -13817,6 +13826,10 @@
 msgid "Highlighted Message Name Color"
 msgstr "Farbe des Absendernamens für hervorgehobene Nachrichten"
 
+#, fuzzy
+msgid "Typing Notification Color"
+msgstr "Farbe der Tipp-Benachrichtigung"
+
 msgid "GtkTreeView Horizontal Separation"
 msgstr "GtkTreeview horizontaler Abstand"
 
@@ -13845,35 +13858,24 @@
 msgid "GTK+ Text Shortcut Theme"
 msgstr "GTK+ Text Shortcut-Thema"
 
-#.
-#. for (i = 0; i < G_N_ELEMENTS(widget_bool_prefs); i++) {
-#. hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
-#. gtk_box_pack_start(GTK_BOX(frame), hbox, FALSE, FALSE, 0);
-#.
-#. check = pidgin_prefs_checkbox(_(widget_bool_names[i]),
-#. widget_bool_prefs_set[i], hbox);
-#. gtk_size_group_add_widget(labelsg, check);
-#.
-#. widget_bool_widgets[i] = pidgin_prefs_checkbox("", widget_bool_prefs[i], hbox);
-#. *
-#. gtk_size_group_add_widget(widgetsb, widget_bool_widgets[i]);
-#. *
-#. gtk_widget_set_sensitive(widget_bool_widgets[i],
-#. purple_prefs_get_bool(widget_bool_prefs_set[i]));
-#. g_signal_connect(G_OBJECT(check), "toggled",
-#. G_CALLBACK(pidgin_toggle_sensitive),
-#. widget_bool_widgets[i]);
-#. }
-#.
-msgid "Interface colors"
-msgstr "UI-Farben"
-
-msgid "Widget Sizes"
-msgstr "Widget-Größen"
+#, fuzzy
+msgid "Disable Typing Notification Text"
+msgstr "Tipp-Benachrichtigung aktivieren"
+
+#, fuzzy
+msgid "GTK+ Theme Control Settings"
+msgstr "Pidgin GTK+ Themenkontrolle"
+
+#, fuzzy
+msgid "Colors"
+msgstr "Schließen"
 
 msgid "Fonts"
 msgstr "Schrift"
 
+msgid "Miscellaneous"
+msgstr ""
+
 msgid "Gtkrc File Tools"
 msgstr "Gtkrc-Datei-Werkzeuge"