changeset 32665:a92f4cb593a4

propagate from branch 'im.pidgin.pidgin' (head c0e633bbd723352b9614b1bfcfab551e416a29dc) to branch 'im.pidgin.cpw.qulogic.gtk3' (head 1887cd5f7ea1e4bc0950747da36d56d618ecd105)
author Marcus Lundblad <ml@update.uu.se>
date Wed, 02 Feb 2011 23:26:42 +0000
parents a7397a3d67ef (current diff) 6448e3f3ddd4 (diff)
children 974722699032
files configure.ac pidgin/gtkutils.c pidgin/plugins/vvconfig.c
diffstat 54 files changed, 1412 insertions(+), 714 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Sun Jan 09 23:32:10 2011 +0000
+++ b/COPYRIGHT	Wed Feb 02 23:26:42 2011 +0000
@@ -81,6 +81,7 @@
 Norbert Buchmuller
 Johannes Buchner
 Sean Burke
+Gabriel Burt
 Thomas Butter
 Trevor Caira
 Andrea Canciani
@@ -131,6 +132,7 @@
 Florian Delizy
 Jiri Denemark
 Vinicius Depizzol
+Marc Dequènes
 Philip Derrin
 Taso N. Devetzis
 Balwinder Singh Dheeman
@@ -377,6 +379,7 @@
 Riley Patterson
 Havoc Pennington
 Ted Percival
+Hugo Pereira Da Costa
 Eduardo Pérez
 Matt Perry
 Ani Peter
@@ -580,6 +583,7 @@
 Timmy Yee
 Li Yuan
 Yuriy Yevgrafov
+Jan Zachorowski
 Nickolai Zeldovich
 Tom Zickel
 Marco Ziech
--- a/ChangeLog	Sun Jan 09 23:32:10 2011 +0000
+++ b/ChangeLog	Wed Feb 02 23:26:42 2011 +0000
@@ -6,9 +6,20 @@
 	  number of times video must be scaled down, saving CPU time. (Jakub Adam)
 	  (half of #13095)
 	* Starting multiple video calls and ending one no longer causes the other
-	  calls to stop sending audio and video. (Jakub Adam) (#12758)
+	  calls to stop sending audio and video. (Jakub Adam) (#12758, #13237)
 	* Perl bindings now respect LDFLAGS. (Peter Volkov, Markos Chandras)
 	  (#12638)
+	* Added AddTrust External Root CA.  (#11554)
+	* Resolve some issues validating X.509 certificates signed off the CAcert
+	  Class 3 intermediate cert when using the GnuTLS SSL/TLS plugin.
+
+	Gadu-Gadu:
+	* Don't drop whole messages when text is colored. (Jan Zachorowski)
+	  (#13259)
+
+	Groupwise:
+	* Don't show two windows when using "Get Info" on a buddy. (Gabriel Burt;
+	  Novell, Inc.) (#13108)
 
 	IRC:
 	* Don't send ISON messages longer than 512 bytes. (Jeffrey Honig) (#9692)
@@ -27,10 +38,15 @@
 	  the conversation window.  (Ryan Flegel) (#13127)
 	* Fix a few memory leaks. (Nader Morshed) (#13162)
 	* Support rendering strikethrough when received as in-line CSS. (#13168)
+	* Editable comboboxes are now more friendly to some GTK+ themes. (Hugo
+	  Pereira Da Costa) (#13164).
 
 	Plugins:
 	* The Voice/Video Settings plugin no longer resets selected devices to
 	  defaults. (Jakub Adam) (#13044)
+	* The Voice/Video Settings plugin no longer crashes when a stored device
+	  name is not found in the list of available devices. (Jakub Adam)
+	  (#13238)
 	* The Autoaccept plugin now allows disabling filename escaping. (Rok
 	  Mandeljc) (half of #11459)
 	* The Autoaccept plugin now allows choosing Reject/Ask/Accept for
@@ -42,6 +58,10 @@
 	XMPP:
 	* Don't crash when receiving an unexpected/invalid jingle transport type.
 	  (Nikita Kozlov) (#13136)
+	* Handle Connection: Close headers for BOSH, when the server does not
+	  terminate the connection itself. (#13008)
+	* Improved parsing for DIGEST-MD5, which should resolve issues
+	  connecting to some jabberd2 servers. (#a14514)
 
 	Yahoo!/Yahoo! JAPAN:
 	* Fix a crash when an account disconnects before a p2p session is
@@ -927,7 +947,7 @@
 	  from you on MSN.
 	* Support sending an invite message to buddies when requesting
 	  authorization from them on MSN.
-	* Timeout switchboard connections aggressively (60 seconds).
+	* Timeout switchboard connections after 60 seconds (msn-pecan devs).
 
 	XMPP:
 	* Voice & Video support with Jingle (XEP-0166, 0167, 0176, & 0177),
--- a/configure.ac	Sun Jan 09 23:32:10 2011 +0000
+++ b/configure.ac	Wed Feb 02 23:26:42 2011 +0000
@@ -329,7 +329,7 @@
 dnl #######################################################################
 dnl # Check for GLib 2.12 (required)
 dnl #######################################################################
-PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.12.0 gio-2.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [
+PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.12.0 gobject-2.0 gmodule-2.0 gthread-2.0], , [
 	AC_MSG_RESULT(no)
 	AC_MSG_ERROR([
 
--- a/libpurple/certificate.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/certificate.c	Wed Feb 02 23:26:42 2011 +0000
@@ -1602,7 +1602,7 @@
 	GSList *ca_crts, *cur;
 	GByteArray *last_fpr, *ca_fpr;
 	gboolean valid = FALSE;
-	gchar *ca_id;
+	gchar *ca_id, *ca2_id;
 
 	peer_crt = (PurpleCertificate *) chain->data;
 
@@ -1619,7 +1619,6 @@
 		return;
 	} /* if (self signed) */
 
-	/* Next, attempt to verify the last certificate against a CA */
 	ca = purple_certificate_find_pool(x509_tls_cached.scheme_name, "ca");
 
 	/* Next, check that the certificate chain is valid */
@@ -1669,6 +1668,9 @@
 		return;
 	} /* if (signature chain not good) */
 
+	/* Next, attempt to verify the last certificate is signed by a trusted
+	 * CA, or is a trusted CA (based on fingerprint).
+	 */
 	/* If, for whatever reason, there is no Certificate Authority pool
 	   loaded, we'll verify the subject name and then warn about thsi. */
 	if ( !ca ) {
@@ -1684,27 +1686,31 @@
 
 	end_crt = g_list_last(chain)->data;
 
-	/* Attempt to look up the last certificate's issuer */
-	ca_id = purple_certificate_get_issuer_unique_id(end_crt);
+	/* Attempt to look up the last certificate, and the last certificate's
+	 * issuer. 
+	 */
+	ca_id  = purple_certificate_get_issuer_unique_id(end_crt);
+	ca2_id = purple_certificate_get_unique_id(end_crt);
 	purple_debug_info("certificate/x509/tls_cached",
 			  "Checking for a CA with DN=%s\n",
 			  ca_id);
-	ca_crts = x509_ca_get_certs(ca_id);
+	purple_debug_info("certificate/x509/tls_cached",
+			  "Also checking for a CA with DN=%s\n",
+			  ca2_id);
+	ca_crts = g_slist_concat(x509_ca_get_certs(ca_id), x509_ca_get_certs(ca2_id));
+	g_free(ca_id);
+	g_free(ca2_id);
 	if ( NULL == ca_crts ) {
 		flags |= PURPLE_CERTIFICATE_CA_UNKNOWN;
 
 		purple_debug_warning("certificate/x509/tls_cached",
-				  "Certificate Authority with DN='%s' not "
-				  "found. I'll prompt the user, I guess.\n",
-				  ca_id);
-		g_free(ca_id);
+				  "No Certificate Authorities with either DN found "
+				  "found. I'll prompt the user, I guess.\n");
 
 		x509_tls_cached_check_subject_name(vrq, flags);
 		return;
 	}
 
-	g_free(ca_id);
-
 	/*
 	 * Check the fingerprints; if they match, then this certificate *is* one
 	 * of the designated "trusted roots", and we don't need to verify the
@@ -1714,10 +1720,6 @@
 	 *
 	 * If the fingerprints don't match, we'll fall back to checking the
 	 * signature.
-	 *
-	 * GnuTLS doesn't seem to include the final root in the verification
-	 * list, so this check will never succeed.  NSS *does* include it in
-	 * the list, so here we are.
 	 */
 	last_fpr = purple_certificate_get_fingerprint_sha1(end_crt);
 	for (cur = ca_crts; cur; cur = cur->next) {
--- a/libpurple/media/backend-fs2.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/media/backend-fs2.c	Wed Feb 02 23:26:42 2011 +0000
@@ -155,6 +155,44 @@
 {
 }
 
+static gboolean
+event_probe_cb(GstPad *srcpad, GstEvent *event, gboolean release_pad)
+{
+	if (GST_EVENT_TYPE(event) == GST_EVENT_CUSTOM_DOWNSTREAM
+		&& gst_event_has_name(event, "purple-unlink-tee")) {
+
+		const GstStructure *s = gst_event_get_structure(event);
+
+		gst_pad_unlink(srcpad, gst_pad_get_peer(srcpad));
+
+		gst_pad_remove_event_probe(srcpad,
+			g_value_get_uint(gst_structure_get_value(s, "handler-id")));
+
+		if (g_value_get_boolean(gst_structure_get_value(s, "release-pad")))
+			gst_element_release_request_pad(GST_ELEMENT_PARENT(srcpad), srcpad);
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+unlink_teepad_dynamic(GstPad *srcpad, gboolean release_pad)
+{
+	guint id = gst_pad_add_event_probe(srcpad, G_CALLBACK(event_probe_cb), NULL);
+
+	if (GST_IS_GHOST_PAD(srcpad))
+		srcpad = gst_ghost_pad_get_target(GST_GHOST_PAD(srcpad));
+
+	gst_element_send_event(gst_pad_get_parent_element(srcpad),
+		gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM,
+			gst_structure_new("purple-unlink-tee",
+				"release-pad", G_TYPE_BOOLEAN, release_pad,
+				"handler-id", G_TYPE_UINT, id,
+				NULL)));
+}
+
 static void
 purple_media_backend_fs2_dispose(GObject *obj)
 {
@@ -179,7 +217,7 @@
 					g_list_delete_link(sessions, sessions)) {
 				PurpleMediaBackendFs2Session *session = sessions->data;
 				if (session->srcpad) {
-					gst_pad_set_blocked(session->srcpad, TRUE);
+					unlink_teepad_dynamic(session->srcpad, FALSE);
 					gst_object_unref(session->srcpad);
 					session->srcpad = NULL;
 				}
--- a/libpurple/mediamanager.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/mediamanager.c	Wed Feb 02 23:26:42 2011 +0000
@@ -400,7 +400,6 @@
 	GstIteratorResult result;
 
 	gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad);
-	gst_pad_set_blocked(pad, FALSE);
 
 	iter = gst_element_iterate_src_pads(parent);
 
--- a/libpurple/protocols/gg/gg.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/gg/gg.c	Wed Feb 02 23:26:42 2011 +0000
@@ -1464,6 +1464,10 @@
 				increased_len += 4;
 				under = FALSE;
 			}
+
+			if (actformat->font & GG_FONT_COLOR) {
+				cformats += sizeof(struct gg_msg_richtext_color);
+			}
 		}
 
 		msg = message->str;
--- a/libpurple/protocols/jabber/Makefile.am	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/jabber/Makefile.am	Wed Feb 02 23:26:42 2011 +0000
@@ -11,6 +11,7 @@
 			  auth.c \
 			  auth.h \
 			  auth_digest_md5.c \
+			  auth_digest_md5.h \
 			  auth_plain.c \
 			  auth_scram.c \
 			  auth_scram.h \
--- a/libpurple/protocols/jabber/auth_cyrus.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/jabber/auth_cyrus.c	Wed Feb 02 23:26:42 2011 +0000
@@ -520,9 +520,12 @@
 		g_free(dec_in);
 
 		if (js->sasl_state != SASL_OK) {
-			/* This should never happen! */
+			/* This happens when the server sends back jibberish
+			 * in the "additional data with success" case.
+			 * Seen with Wildfire 3.0.1.
+			 */
 			*error = g_strdup(_("Invalid response from server"));
-			g_return_val_if_reached(JABBER_SASL_STATE_FAIL);
+			return JABBER_SASL_STATE_FAIL;
 		}
 	}
 
--- a/libpurple/protocols/jabber/auth_digest_md5.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/jabber/auth_digest_md5.c	Wed Feb 02 23:26:42 2011 +0000
@@ -27,6 +27,7 @@
 #include "util.h"
 #include "xmlnode.h"
 
+#include "auth_digest_md5.h"
 #include "auth.h"
 #include "jabber.h"
 
@@ -43,7 +44,7 @@
 }
 
 /* Parts of this algorithm are inspired by stuff in libgsasl */
-static GHashTable* parse_challenge(const char *challenge)
+GHashTable* jabber_auth_digest_md5_parse(const char *challenge)
 {
 	const char *token_start, *val_start, *val_end, *cur;
 	GHashTable *ret = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -77,12 +78,12 @@
 					val_start++;
 
 				val_end = cur;
-				while (val_end != val_start && (*val_end == ' ' || *val_end == ',' || *val_end == '\t'
+				while (val_end >= val_start && (*val_end == ' ' || *val_end == ',' || *val_end == '\t'
 						|| *val_end == '\r' || *val_end == '\n'
 						|| *val_end == '"'  || *val_end == '\0'))
 					val_end--;
 
-				if (val_start != val_end)
+				if (val_end - val_start + 1 >= 0)
 					value = g_strndup(val_start, val_end - val_start + 1);
 			}
 
@@ -186,7 +187,7 @@
 			dec_in != NULL ? strlen(dec_in) : 0,
 			dec_in != NULL  ? dec_in : "(null)");
 
-	parts = parse_challenge(dec_in);
+	parts = jabber_auth_digest_md5_parse(dec_in);
 
 	if (g_hash_table_lookup(parts, "rspauth")) {
 		char *rspauth = g_hash_table_lookup(parts, "rspauth");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/jabber/auth_digest_md5.h	Wed Feb 02 23:26:42 2011 +0000
@@ -0,0 +1,39 @@
+/**
+ * @file auth_digest_md5.h Implementation of SASL DIGEST-MD5 authentication
+ *
+ * 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
+ */
+#ifndef PURPLE_JABBER_AUTH_DIGEST_MD5_H_
+#define PURPLE_JABBER_AUTH_DIGEST_MD5_H_
+
+#include "internal.h"
+
+/*
+ * Every function in this file is ONLY exposed for tests.
+ * DO NOT USE ANYTHING HERE OR YOU WILL BE SENT TO THE PIT OF DESPAIR.
+ */
+
+/*
+ * Parse a DIGEST-MD5 challenge.
+ */
+GHashTable *jabber_auth_digest_md5_parse(const char *challenge);
+
+#endif /* PURPLE_JABBER_AUTH_DIGEST_MD5_H_ */
--- a/libpurple/protocols/jabber/bosh.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/jabber/bosh.c	Wed Feb 02 23:26:42 2011 +0000
@@ -108,8 +108,27 @@
 	int requests; /* number of outstanding HTTP requests */
 
 	gboolean headers_done;
+	gboolean close;
+};
 
-};
+static void
+debug_dump_http_connections(PurpleBOSHConnection *conn)
+{
+	int i;
+
+	g_return_if_fail(conn != NULL);
+
+	for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
+		PurpleHTTPConnection *httpconn = conn->connections[i];
+		if (httpconn == NULL)
+			purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n",
+			                  conn, i);
+		else
+			purple_debug_misc("jabber", "BOSH %p->connections[%d] = %p, state = %d"
+			                  ", requests = %d\n", conn, i, httpconn,
+			                  httpconn->state, httpconn->requests);
+	}
+}
 
 static void http_connection_connect(PurpleHTTPConnection *conn);
 static void http_connection_send_request(PurpleHTTPConnection *conn,
@@ -263,18 +282,8 @@
 {
 	int i;
 
-	if (purple_debug_is_verbose()) {
-		for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
-			PurpleHTTPConnection *httpconn = conn->connections[i];
-			if (httpconn == NULL)
-				purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n",
-				                  conn, i);
-			else
-				purple_debug_misc("jabber", "BOSH %p->connections[%d] = %p, state = %d"
-				                  ", requests = %d\n", conn, i, httpconn,
-				                  httpconn->state, httpconn->requests);
-		}
-	}
+	if (purple_debug_is_verbose())
+		debug_dump_http_connections(conn);
 
 	/* Easy solution: Does everyone involved support pipelining? Hooray! Just use
 	 * one TCP connection! */
@@ -297,11 +306,23 @@
 			return NULL;
 	}
 
-	/* Third loop, look for one that's NULL and create a new connection */
+	/* Third loop, is something offline that we can connect? */
+	for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
+		if (conn->connections[i] &&
+				conn->connections[i]->state == HTTP_CONN_OFFLINE) {
+			purple_debug_info("jabber", "bosh: Reconnecting httpconn "
+			                            "(%i, %p)\n", i, conn->connections[i]);
+			http_connection_connect(conn->connections[i]);
+			return NULL;
+		}
+	}
+
+	/* Fourth loop, look for one that's NULL and create a new connection */
 	for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
 		if (!conn->connections[i]) {
-			purple_debug_info("jabber", "bosh: Creating and connecting new httpconn\n");
 			conn->connections[i] = jabber_bosh_http_connection_init(conn);
+			purple_debug_info("jabber", "bosh: Creating and connecting new httpconn "
+			                            "(%i, %p)\n", i, conn->connections[i]);
 
 			http_connection_connect(conn->connections[i]);
 			return NULL;
@@ -344,6 +365,8 @@
 	chosen = find_available_http_connection(conn);
 
 	if (!chosen) {
+		if (type == PACKET_FLUSH)
+			return;
 		/*
 		 * For non-ordinary traffic, we can't 'buffer' it, so use the
 		 * first connection.
@@ -444,6 +467,27 @@
 	send_timer_cb(bosh);
 }
 
+static void
+jabber_bosh_disable_pipelining(PurpleBOSHConnection *bosh)
+{
+	/* Do nothing if it's already disabled */
+	if (!bosh->pipelining)
+		return;
+
+	purple_debug_info("jabber", "BOSH: Disabling pipelining on conn %p\n",
+	                            bosh);
+	bosh->pipelining = FALSE;
+	if (bosh->connections[1] == NULL) {
+		bosh->connections[1] = jabber_bosh_http_connection_init(bosh);
+		http_connection_connect(bosh->connections[1]);
+	} else {
+		/* Shouldn't happen; this should be the only place pipelining
+		 * is turned off.
+		 */
+		g_warn_if_reached();
+	}
+}
+
 static void jabber_bosh_connection_received(PurpleBOSHConnection *conn, xmlnode *node) {
 	xmlnode *child;
 	JabberStream *js = conn->js;
@@ -611,6 +655,8 @@
 static void
 connection_common_established_cb(PurpleHTTPConnection *conn)
 {
+	purple_debug_misc("jabber", "bosh: httpconn %p re-connected\n", conn);
+
 	/* Indicate we're ready and reset some variables */
 	conn->state = HTTP_CONN_CONNECTED;
 	if (conn->requests != 0)
@@ -622,9 +668,13 @@
 		g_string_free(conn->read_buf, TRUE);
 		conn->read_buf = NULL;
 	}
+	conn->close = FALSE;
 	conn->headers_done = FALSE;
 	conn->handled_len = conn->body_len = 0;
 
+	if (purple_debug_is_verbose())
+		debug_dump_http_connections(conn->bosh);
+
 	if (conn->bosh->js->reinit)
 		jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL);
 	else if (conn->bosh->state == BOSH_CONN_ONLINE) {
@@ -639,6 +689,7 @@
 
 static void http_connection_disconnected(PurpleHTTPConnection *conn)
 {
+	gboolean had_requests = FALSE;
 	/*
 	 * Well, then. Fine! I never liked you anyway, server! I was cheating on you
 	 * with AIM!
@@ -662,7 +713,8 @@
 		conn->writeh = 0;
 	}
 
-	if (conn->requests > 0 && conn->read_buf->len == 0) {
+	had_requests = (conn->requests > 0);
+	if (had_requests && conn->read_buf->len == 0) {
 		purple_debug_error("jabber", "bosh: Adjusting BOSHconn requests (%d) to %d\n",
 		                   conn->bosh->requests, conn->bosh->requests - conn->requests);
 		conn->bosh->requests -= conn->requests;
@@ -671,13 +723,15 @@
 
 	if (conn->bosh->pipelining) {
 		/* Hmmmm, fall back to multiple connections */
-		conn->bosh->pipelining = FALSE;
-		if (conn->bosh->connections[1] == NULL) {
-			conn->bosh->connections[1] = jabber_bosh_http_connection_init(conn->bosh);
-			http_connection_connect(conn->bosh->connections[1]);
-		}
+		jabber_bosh_disable_pipelining(conn->bosh);
 	}
 
+	if (!had_requests)
+		/* If the server disconnected us without any requests, let's
+		 * just wait until we have something to send before we reconnect
+		 */
+		return;
+
 	if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) {
 		purple_connection_error_reason(conn->bosh->js->gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
@@ -704,30 +758,49 @@
 
 	cursor = conn->read_buf->str + conn->handled_len;
 
+	if (purple_debug_is_verbose())
+		purple_debug_misc("jabber", "BOSH server sent: %s\n", cursor);
+
+	/* TODO: Chunked encoding and check response version :/ */
 	if (!conn->headers_done) {
-		const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length");
+		const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length:");
+		const char *connection = purple_strcasestr(cursor, "\r\nConnection:");
 		const char *end_of_headers = strstr(cursor, "\r\n\r\n");
 
 		/* Make sure Content-Length is in headers, not body */
 		if (content_length && (!end_of_headers || content_length < end_of_headers)) {
-			const char *sep;
 			int len;
 
-			if ((sep = strstr(content_length, ": ")) == NULL ||
-					strstr(sep, "\r\n") == NULL)
+			if (strstr(content_length, "\r\n") == NULL)
 				/*
 				 * The packet ends in the middle of the Content-Length line.
 				 * We'll try again later when we have more.
 				 */
 				return;
 
-			len = atoi(sep + 2);
+			len = atoi(content_length + strlen("\r\nContent-Length:"));
 			if (len == 0)
-				purple_debug_warning("jabber", "Found mangled Content-Length header.\n");
+				purple_debug_warning("jabber", "Found mangled Content-Length header, or server returned 0-length response.\n");
 
 			conn->body_len = len;
 		}
 
+		if (connection && (!end_of_headers || content_length < end_of_headers)) {
+			const char *tmp;
+			if (strstr(connection, "\r\n") == NULL)
+				return;
+
+
+			tmp = connection + strlen("\r\nConnection:");
+			while (*tmp && (*tmp == ' ' || *tmp == '\t'))
+				++tmp;
+
+			if (!g_ascii_strncasecmp(tmp, "close", strlen("close"))) {
+				conn->close = TRUE;
+				jabber_bosh_disable_pipelining(conn->bosh);
+			}
+		}
+
 		if (end_of_headers) {
 			conn->headers_done = TRUE;
 			conn->handled_len = end_of_headers - conn->read_buf->str + 4;
@@ -752,6 +825,14 @@
 	http_received_cb(conn->read_buf->str + conn->handled_len, conn->body_len,
 	                 conn->bosh);
 
+	/* Connection: Close? */
+	if (conn->close && conn->state == HTTP_CONN_CONNECTED) {
+		if (purple_debug_is_verbose())
+			purple_debug_misc("jabber", "bosh (%p), server sent Connection: "
+			                            "close\n", conn);
+		http_connection_disconnected(conn);
+	}
+
 	if (conn->bosh->state == BOSH_CONN_ONLINE &&
 			(conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) {
 		purple_debug_misc("jabber", "BOSH: Sending an empty request\n");
@@ -791,10 +872,11 @@
 
 	if (cnt == 0 || (cnt < 0 && errno != EAGAIN)) {
 		if (cnt < 0)
-			purple_debug_info("jabber", "bosh read=%d, errno=%d, error=%s\n",
-			                  cnt, errno, g_strerror(errno));
+			purple_debug_info("jabber", "BOSH (%p) read=%d, errno=%d, error=%s\n",
+			                  conn, cnt, errno, g_strerror(errno));
 		else
-			purple_debug_info("jabber", "bosh server closed the connection\n");
+			purple_debug_info("jabber", "BOSH server closed the connection (%p)\n",
+			                  conn);
 
 		/*
 		 * If the socket is closed, the processing really needs to know about
@@ -911,6 +993,9 @@
 	else
 		ret = write(conn->fd, data, len);
 
+	if (purple_debug_is_verbose())
+		purple_debug_misc("jabber", "BOSH (%p): wrote %d bytes\n", conn, ret);
+
 	return ret;
 }
 
@@ -975,7 +1060,10 @@
 
 	if (purple_debug_is_unsafe() && purple_debug_is_verbose())
 		/* Will contain passwords for SASL PLAIN and is verbose */
-		purple_debug_misc("jabber", "BOSH: Sending %s\n", data);
+		purple_debug_misc("jabber", "BOSH (%p): Sending %s\n", conn, data);
+	else if (purple_debug_is_verbose())
+		purple_debug_misc("jabber", "BOSH (%p): Sending request of "
+		                            "%" G_GSIZE_FORMAT " bytes.\n", conn, len);
 
 	if (conn->writeh == 0)
 		ret = http_connection_do_send(conn, data, len);
--- a/libpurple/protocols/msn/error.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/error.c	Wed Feb 02 23:26:42 2011 +0000
@@ -31,7 +31,7 @@
 
 typedef struct
 {
-	PurpleConnection *gc;
+	MsnSession *session;
 	char *who;
 	char *group;
 	gboolean add;
@@ -293,9 +293,9 @@
 		group = purple_find_group(data->group);
 
 	if (group != NULL)
-		buddy = purple_find_buddy_in_group(purple_connection_get_account(data->gc), data->who, group);
+		buddy = purple_find_buddy_in_group(data->session->account, data->who, group);
 	else
-		buddy = purple_find_buddy(purple_connection_get_account(data->gc), data->who);
+		buddy = purple_find_buddy(data->session->account, data->who);
 
 	if (buddy != NULL)
 		purple_blist_remove_buddy(buddy);
@@ -309,14 +309,9 @@
 	/* this *should* be necessary !! */
 	msn_complete_sync_issue(data);
 #endif
+	MsnUserList *userlist = data->session->userlist;
 
-	if (g_list_find(purple_connections_get_all(), data->gc) != NULL)
-	{
-		MsnSession *session = data->gc->proto_data;
-		MsnUserList *userlist = session->userlist;
-
-		msn_userlist_add_buddy(userlist, data->who, data->group);
-	}
+	msn_userlist_add_buddy(userlist, data->who, data->group);
 
 	g_free(data->group);
 	g_free(data->who);
@@ -326,18 +321,14 @@
 static void
 msn_rem_cb(MsnAddRemData *data)
 {
+	MsnUserList *userlist = data->session->userlist;
 	msn_complete_sync_issue(data);
 
-	if (g_list_find(purple_connections_get_all(), data->gc) != NULL)
-	{
-		MsnSession *session = data->gc->proto_data;
-		MsnUserList *userlist = session->userlist;
 
-		if (data->group == NULL) {
-			msn_userlist_rem_buddy_from_list(userlist, data->who, MSN_LIST_FL);
-		} else {
-			g_free(data->group);
-		}
+	if (data->group == NULL) {
+		msn_userlist_rem_buddy_from_list(userlist, data->who, MSN_LIST_FL);
+	} else {
+		g_free(data->group);
 	}
 
 	g_free(data->who);
@@ -356,10 +347,10 @@
 	account = session->account;
 	gc = purple_account_get_connection(account);
 
-	data        = g_new0(MsnAddRemData, 1);
-	data->who   = g_strdup(passport);
-	data->group = g_strdup(group_name);
-	data->gc    = gc;
+	data          = g_new0(MsnAddRemData, 1);
+	data->who     = g_strdup(passport);
+	data->group   = g_strdup(group_name);
+	data->session = session;
 
 	msg = g_strdup_printf(_("Buddy list synchronization issue in %s (%s)"),
 						  purple_account_get_username(account),
@@ -382,7 +373,7 @@
 	}
 
 	purple_request_action(gc, NULL, msg, reason, PURPLE_DEFAULT_ACTION_NONE,
-						purple_connection_get_account(gc), data->who, NULL,
+						account, data->who, NULL,
 						data, 2,
 						_("Yes"), G_CALLBACK(msn_add_cb),
 						_("No"), G_CALLBACK(msn_rem_cb));
@@ -390,3 +381,4 @@
 	g_free(reason);
 	g_free(msg);
 }
+
--- a/libpurple/protocols/msn/msg.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/msg.c	Wed Feb 02 23:26:42 2011 +0000
@@ -613,15 +613,7 @@
 
 	if (msg->msnslp_message)
 	{
-		g_string_append_printf(str, "Session ID: %u\r\n", msg->part->header->session_id);
-		g_string_append_printf(str, "ID:         %u\r\n", msg->part->header->id);
-		g_string_append_printf(str, "Offset:     %" G_GUINT64_FORMAT "\r\n", msg->part->header->offset);
-		g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", msg->part->header->total_size);
-		g_string_append_printf(str, "Length:     %u\r\n", msg->part->header->length);
-		g_string_append_printf(str, "Flags:      0x%x\r\n", msg->part->header->flags);
-		g_string_append_printf(str, "ACK ID:     %u\r\n", msg->part->header->ack_id);
-		g_string_append_printf(str, "SUB ID:     %u\r\n", msg->part->header->ack_sub_id);
-		g_string_append_printf(str, "ACK Size:   %" G_GUINT64_FORMAT "\r\n", msg->part->header->ack_size);
+		msn_slpmsgpart_to_string(msg->part, str);
 
 		if (purple_debug_is_verbose() && body != NULL)
 		{
@@ -638,27 +630,17 @@
 			else
 			{
 				int i;
-				int bin_len;
 
-				if (msg->part->footer->value == P2P_APPID_SESSION)
-					bin_len = P2P_PACKET_HEADER_SIZE;
-				else
-					bin_len = body_len;
-
-				for (i = 0; i < bin_len; i++)
+				for (i = 0; i < body_len; i++)
 				{
 					g_string_append_printf(str, "%.2hhX ", body[i]);
 					if ((i % 16) == 15)
 						g_string_append(str, "\r\n");
 				}
 
-				if (bin_len == P2P_PACKET_HEADER_SIZE)
-					g_string_append_printf(str, "%s ", body + P2P_PACKET_HEADER_SIZE);
 				g_string_append(str, "\r\n");
 			}
 		}
-
-		g_string_append_printf(str, "Footer:     0x%08X\r\n", msg->part->footer->value);
 	}
 	else
 	{
--- a/libpurple/protocols/msn/msg.h	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/msg.h	Wed Feb 02 23:26:42 2011 +0000
@@ -79,7 +79,6 @@
 	MsnMsgType type;
 
 	gboolean msnslp_message;
-	MsnSlpMessage *slpmsg;
 	MsnSlpMessagePart *part;
 
 	char *remote_user;
@@ -99,7 +98,6 @@
 								  been ref'ed for using it in a callback. */
 
 	MsnCommand *cmd;
-	MsnTransaction *trans;
 
 	MsnMsgCb ack_cb; /**< The callback to call when we receive an ACK of this
 					   message. */
@@ -107,8 +105,6 @@
 					   message. */
 	void *ack_data; /**< The data used by callbacks. */
 
-	MsnMsgErrorType error; /**< The error of the message. */
-
 	guint32 retries;
 };
 
--- a/libpurple/protocols/msn/p2p.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/p2p.c	Wed Feb 02 23:26:42 2011 +0000
@@ -27,12 +27,32 @@
 #include "p2p.h"
 #include "msnutils.h"
 
-MsnP2PHeader *
-msn_p2p_header_from_wire(const char *wire)
+MsnP2PInfo *
+msn_p2p_info_new(void)
+{
+	return g_new0(MsnP2PInfo, 1);
+}
+
+MsnP2PInfo *
+msn_p2p_info_dup(MsnP2PInfo *info)
+{
+	MsnP2PInfo *new_info = g_new0(MsnP2PInfo, 1);
+	*new_info = *info;
+	return new_info;
+}
+
+void
+msn_p2p_info_free(MsnP2PInfo *info)
+{
+	g_free(info);
+}
+
+size_t
+msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire)
 {
 	MsnP2PHeader *header;
 
-	header = g_new(MsnP2PHeader, 1);
+	header = &info->header;
 
 	header->session_id = msn_pop32le(wire);
 	header->id         = msn_pop32le(wire);
@@ -44,15 +64,17 @@
 	header->ack_sub_id = msn_pop32le(wire);
 	header->ack_size   = msn_pop64le(wire);
 
-	return header;
+	return P2P_PACKET_HEADER_SIZE;
 }
 
 char *
-msn_p2p_header_to_wire(MsnP2PHeader *header)
+msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len)
 {
+	MsnP2PHeader *header;
 	char *wire;
 	char *tmp;
 
+	header = &info->header;
 	tmp = wire = g_new(char, P2P_PACKET_HEADER_SIZE);
 
 	msn_push32le(tmp, header->session_id);
@@ -65,35 +87,58 @@
 	msn_push32le(tmp, header->ack_sub_id);
 	msn_push64le(tmp, header->ack_size);
 
+	if (len)
+		*len = P2P_PACKET_HEADER_SIZE;
+
 	return wire;
 
 }
 
-MsnP2PFooter *
-msn_p2p_footer_from_wire(const char *wire)
+size_t
+msn_p2p_footer_from_wire(MsnP2PInfo *info, const char *wire)
 {
 	MsnP2PFooter *footer;
 
-	footer = g_new(MsnP2PFooter, 1);
+	footer = &info->footer;
 
 	footer->value = msn_pop32be(wire);
 
-	return footer;
+	return P2P_PACKET_FOOTER_SIZE;
 }
 
 char *
-msn_p2p_footer_to_wire(MsnP2PFooter *footer)
+msn_p2p_footer_to_wire(MsnP2PInfo *info, size_t *len)
 {
+	MsnP2PFooter *footer;
 	char *wire;
 	char *tmp;
 
+	footer = &info->footer;
 	tmp = wire = g_new(char, P2P_PACKET_FOOTER_SIZE);
 
 	msn_push32be(tmp, footer->value);
 
+	if (len)
+		*len = P2P_PACKET_FOOTER_SIZE;
+
 	return wire;
 }
 
+void
+msn_p2p_info_to_string(MsnP2PInfo *info, GString *str)
+{
+	g_string_append_printf(str, "Session ID: %u\r\n", info->header.session_id);
+	g_string_append_printf(str, "ID:         %u\r\n", info->header.id);
+	g_string_append_printf(str, "Offset:     %" G_GUINT64_FORMAT "\r\n", info->header.offset);
+	g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", info->header.total_size);
+	g_string_append_printf(str, "Length:     %u\r\n", info->header.length);
+	g_string_append_printf(str, "Flags:      0x%x\r\n", info->header.flags);
+	g_string_append_printf(str, "ACK ID:     %u\r\n", info->header.ack_id);
+	g_string_append_printf(str, "SUB ID:     %u\r\n", info->header.ack_sub_id);
+	g_string_append_printf(str, "ACK Size:   %" G_GUINT64_FORMAT "\r\n", info->header.ack_size);
+	g_string_append_printf(str, "Footer:     0x%08X\r\n", info->footer.value);
+}
+
 gboolean
 msn_p2p_msg_is_data(const MsnP2PHeaderFlag flags)
 {
@@ -102,3 +147,135 @@
 	        flags == P2P_FILE_DATA);
 }
 
+gboolean
+msn_p2p_info_is_valid(MsnP2PInfo *info)
+{
+	return info->header.total_size >= info->header.length;
+}
+
+gboolean
+msn_p2p_info_is_final(MsnP2PInfo *info)
+{
+	return info->header.offset + info->header.length >= info->header.total_size;
+}
+
+guint32
+msn_p2p_info_get_session_id(MsnP2PInfo *info)
+{
+	return info->header.session_id;
+}
+
+guint32
+msn_p2p_info_get_id(MsnP2PInfo *info)
+{
+	return info->header.id;
+}
+
+guint64
+msn_p2p_info_get_offset(MsnP2PInfo *info)
+{
+	return info->header.offset;
+}
+
+guint64
+msn_p2p_info_get_total_size(MsnP2PInfo *info)
+{
+	return info->header.total_size;
+}
+
+guint32
+msn_p2p_info_get_length(MsnP2PInfo *info)
+{
+	return info->header.length;
+}
+
+guint32
+msn_p2p_info_get_flags(MsnP2PInfo *info)
+{
+	return info->header.flags;
+}
+
+guint32
+msn_p2p_info_get_ack_id(MsnP2PInfo *info)
+{
+	return info->header.ack_id;
+}
+
+guint32
+msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info)
+{
+	return info->header.ack_sub_id;
+}
+
+guint64
+msn_p2p_info_get_ack_size(MsnP2PInfo *info)
+{
+	return info->header.ack_size;
+}
+
+guint32
+msn_p2p_info_get_app_id(MsnP2PInfo *info)
+{
+	return info->footer.value;
+}
+
+void
+msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id)
+{
+	info->header.session_id = session_id;
+}
+
+void
+msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id)
+{
+	info->header.id = id;
+}
+
+void
+msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset)
+{
+	info->header.offset = offset;
+}
+
+void
+msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size)
+{
+	info->header.total_size = total_size;
+}
+
+void
+msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length)
+{
+	info->header.length = length;
+}
+
+void
+msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags)
+{
+	info->header.flags = flags;
+}
+
+void
+msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id)
+{
+	info->header.ack_id = ack_id;
+}
+
+void
+msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id)
+{
+	info->header.ack_sub_id = ack_sub_id;
+}
+
+void
+msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size)
+{
+	info->header.ack_size = ack_size;
+}
+
+void
+msn_p2p_info_set_app_id(MsnP2PInfo *info, guint32 app_id)
+{
+	info->footer.value = app_id;
+}
+
--- a/libpurple/protocols/msn/p2p.h	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/p2p.h	Wed Feb 02 23:26:42 2011 +0000
@@ -58,6 +58,11 @@
 } MsnP2PFooter;
 #define P2P_PACKET_FOOTER_SIZE (1 * 4)
 
+typedef struct {
+	MsnP2PHeader header;
+	MsnP2PFooter footer;
+} MsnP2PInfo;
+
 typedef enum
 {
 	P2P_NO_FLAG         = 0x0,        /**< No flags specified */
@@ -88,19 +93,98 @@
 	P2P_APPID_DISPLAY   = 0xC         /**< Display Image */
 } MsnP2PAppId;
 
-MsnP2PHeader *
-msn_p2p_header_from_wire(const char *wire);
+MsnP2PInfo *
+msn_p2p_info_new(void);
+
+MsnP2PInfo *
+msn_p2p_info_dup(MsnP2PInfo *info);
+
+void
+msn_p2p_info_free(MsnP2PInfo *info);
+
+size_t
+msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire);
 
 char *
-msn_p2p_header_to_wire(MsnP2PHeader *header);
+msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len);
 
-MsnP2PFooter *
-msn_p2p_footer_from_wire(const char *wire);
+size_t
+msn_p2p_footer_from_wire(MsnP2PInfo *info, const char *wire);
 
 char *
-msn_p2p_footer_to_wire(MsnP2PFooter *footer);
+msn_p2p_footer_to_wire(MsnP2PInfo *info, size_t *len);
+
+void
+msn_p2p_info_to_string(MsnP2PInfo *info, GString *str);
 
 gboolean
 msn_p2p_msg_is_data(const MsnP2PHeaderFlag flags);
 
+gboolean
+msn_p2p_info_is_valid(MsnP2PInfo *info);
+
+gboolean
+msn_p2p_info_is_final(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_session_id(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_id(MsnP2PInfo *info);
+
+guint64
+msn_p2p_info_get_offset(MsnP2PInfo *info);
+
+guint64
+msn_p2p_info_get_total_size(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_length(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_flags(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_ack_id(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info);
+
+guint64
+msn_p2p_info_get_ack_size(MsnP2PInfo *info);
+
+guint32
+msn_p2p_info_get_app_id(MsnP2PInfo *info);
+
+void
+msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id);
+
+void
+msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id);
+
+void
+msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset);
+
+void
+msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size);
+
+void
+msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length);
+
+void
+msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags);
+
+void
+msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id);
+
+void
+msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id);
+
+void
+msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size);
+
+void
+msn_p2p_info_set_app_id(MsnP2PInfo *info, guint32 app_id);
+
 #endif /* MSN_P2P_H */
+
--- a/libpurple/protocols/msn/sbconn.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/sbconn.c	Wed Feb 02 23:26:42 2011 +0000
@@ -126,8 +126,6 @@
 	trans->payload = payload;
 	trans->payload_len = payload_len;
 
-	msg->trans = trans;
-
 	msn_cmdproc_send_trans(cmdproc, trans);
 }
 
--- a/libpurple/protocols/msn/slpcall.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Wed Feb 02 23:26:42 2011 +0000
@@ -1059,16 +1059,21 @@
 	MsnSlpCall *slpcall;
 	const guchar *body;
 	gsize body_len;
+	guint32 session_id;
+	guint32 flags;
 
 	slpcall = NULL;
 	body = slpmsg->buffer;
-	body_len = slpmsg->header->offset;
+	body_len = msn_p2p_info_get_offset(slpmsg->p2p_info);
 
-	if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP)
+	session_id = msn_p2p_info_get_session_id(slpmsg->p2p_info);
+	flags = msn_p2p_info_get_flags(slpmsg->p2p_info);
+
+	if (flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP)
 	{
 		char *body_str;
 
-		if (slpmsg->header->session_id == 64)
+		if (session_id == 64)
 		{
 			/* This is for handwritten messages (Ink) */
 			GError *error = NULL;
@@ -1125,9 +1130,9 @@
 		}
 		g_free(body_str);
 	}
-	 else if (msn_p2p_msg_is_data(slpmsg->header->flags))
+	 else if (msn_p2p_msg_is_data(flags))
 	{
-		slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->header->session_id);
+		slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id);
 
 		if (slpcall != NULL)
 		{
@@ -1142,13 +1147,13 @@
 			slpcall->wasted = TRUE;
 		}
 	}
-	else if (slpmsg->header->flags == P2P_ACK)
+	else if (flags == P2P_ACK)
 	{
 		/* Acknowledgement of previous message. Don't do anything currently. */
 	}
 	else
 		purple_debug_warning("msn", "Unprocessed SLP message with flags 0x%04x\n",
-		                     slpmsg->header->flags);
+		                     flags);
 
 	return slpcall;
 }
--- a/libpurple/protocols/msn/slplink.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/slplink.c	Wed Feb 02 23:26:42 2011 +0000
@@ -281,17 +281,21 @@
 msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
 {
 	MsnSlpMessagePart *part;
+	MsnP2PInfo *info;
 	long long real_size;
 	size_t len = 0;
+	guint64 offset;
 
 	/* Maybe we will want to create a new msg for this slpmsg instead of
 	 * reusing the same one all the time. */
-	part = msn_slpmsgpart_new(slpmsg->header, slpmsg->footer);
+	info = slpmsg->p2p_info;
+	part = msn_slpmsgpart_new(info);
 	part->ack_data = slpmsg;
 
-	real_size = (slpmsg->header->flags == P2P_ACK) ? 0 : slpmsg->size;
+	real_size = (msn_p2p_info_get_flags(info) == P2P_ACK) ? 0 : slpmsg->size;
 
-	if (slpmsg->header->offset < real_size)
+	offset = msn_p2p_info_get_offset(info);
+	if (offset < real_size)
 	{
 		if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND &&
 				purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
@@ -301,15 +305,15 @@
 		}
 		else
 		{
-			len = slpmsg->size - slpmsg->header->offset;
+			len = slpmsg->size - offset;
 
 			if (len > MSN_SBCONN_MAX_SIZE)
 				len = MSN_SBCONN_MAX_SIZE;
 
-			msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + slpmsg->header->offset, len);
+			msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + offset, len);
 		}
 
-		slpmsg->header->length = len;
+		msn_p2p_info_set_length(slpmsg->p2p_info, len);
 	}
 
 #if 0
@@ -326,7 +330,7 @@
 	msn_slplink_send_part(slplink, part);
 
 
-	if (msn_p2p_msg_is_data(slpmsg->header->flags) &&
+	if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(info)) &&
 		(slpmsg->slpcall != NULL))
 	{
 		slpmsg->slpcall->progress = TRUE;
@@ -334,7 +338,7 @@
 		if (slpmsg->slpcall->progress_cb != NULL)
 		{
 			slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
-										 len, slpmsg->header->offset);
+										 len, offset);
 		}
 	}
 
@@ -344,27 +348,30 @@
 static void
 msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
 {
-	slpmsg = slpmsg;
-	slpmsg->footer = g_new0(MsnP2PFooter, 1);
+	MsnP2PInfo *info;
+	guint32 flags;
+
+	info = slpmsg->p2p_info;
 
-	if (slpmsg->header->flags == P2P_NO_FLAG)
+	flags = msn_p2p_info_get_flags(info);
+	if (flags == P2P_NO_FLAG)
 	{
-		slpmsg->header->ack_id = rand() % 0xFFFFFF00;
+		msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00);
 	}
-	else if (msn_p2p_msg_is_data(slpmsg->header->flags))
+	else if (msn_p2p_msg_is_data(flags))
 	{
 		MsnSlpCall *slpcall;
 		slpcall = slpmsg->slpcall;
 
 		g_return_if_fail(slpcall != NULL);
-		slpmsg->header->session_id = slpcall->session_id;
-		slpmsg->footer->value = slpcall->app_id;
-		slpmsg->header->ack_id = rand() % 0xFFFFFF00;
+		msn_p2p_info_set_session_id(info, slpcall->session_id);
+		msn_p2p_info_set_app_id(info, slpcall->app_id);
+		msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00);
 	}
 
-	slpmsg->header->id = slpmsg->id;
+	msn_p2p_info_set_id(info, slpmsg->id);
 
-	slpmsg->header->total_size = slpmsg->size;
+	msn_p2p_info_set_total_size(info, slpmsg->size);
 
 	msn_slplink_send_msgpart(slplink, slpmsg);
 }
@@ -400,20 +407,20 @@
 }
 
 static MsnSlpMessage *
-msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PHeader *header)
+msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PInfo *info)
 {
 	MsnSlpMessage *slpmsg;
 
-	slpmsg = msn_slpmsg_ack_new(header);
+	slpmsg = msn_slpmsg_ack_new(info);
 	msn_slpmsg_set_slplink(slpmsg, slplink);
 
 	return slpmsg;
 }
 
 static void
-msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PHeader *header)
+msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PInfo *info)
 {
-	MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, header);
+	MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, info);
 
 	msn_slplink_send_slpmsg(slplink, slpmsg);
 	msn_slpmsg_destroy(slpmsg);
@@ -428,7 +435,7 @@
 	{
 		MsnSlpMessage *slpmsg = e->data;
 
-		if ((slpmsg->header->session_id == session_id) && (slpmsg->id == id))
+		if ((msn_p2p_info_get_session_id(slpmsg->p2p_info) == session_id) && (slpmsg->id == id))
 			return slpmsg;
 	}
 
@@ -436,22 +443,26 @@
 }
 
 static MsnSlpMessage *
-init_first_msg(MsnSlpLink *slplink, MsnP2PHeader *header)
+init_first_msg(MsnSlpLink *slplink, MsnP2PInfo *info)
 {
 	MsnSlpMessage *slpmsg;
+	guint32 session_id;
+	guint32 flags;
 
 	slpmsg = msn_slpmsg_new(slplink);
-	slpmsg->id = header->id;
-	slpmsg->header->session_id = header->session_id;
-	slpmsg->size = header->total_size;
-	slpmsg->header->flags = header->flags;
+	slpmsg->id = msn_p2p_info_get_id(info);
+	session_id = msn_p2p_info_get_session_id(info);
+	msn_p2p_info_set_session_id(slpmsg->p2p_info, session_id);
+	slpmsg->size = msn_p2p_info_get_total_size(info);
+	flags = msn_p2p_info_get_flags(info);
+	msn_p2p_info_set_flags(slpmsg->p2p_info, flags);
 
-	if (slpmsg->header->session_id)
+	if (session_id)
 	{
-		slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->header->session_id);
+		slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id);
 		if (slpmsg->slpcall != NULL)
 		{
-			if (msn_p2p_msg_is_data(header->flags))
+			if (msn_p2p_msg_is_data(flags))
 			{
 				PurpleXfer *xfer = slpmsg->slpcall->xfer;
 				if (xfer != NULL)
@@ -488,9 +499,10 @@
 }
 
 static void
-process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PHeader *header)
+process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PInfo *info)
 {
 	MsnSlpCall *slpcall;
+	guint32 flags;
 
 	slpcall = msn_slp_process_msg(slplink, slpmsg);
 
@@ -501,8 +513,10 @@
 
 	purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n");
 
-	if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP ||
-			msn_p2p_msg_is_data(slpmsg->header->flags))
+	flags = msn_p2p_info_get_flags(slpmsg->p2p_info);
+
+	if (flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP ||
+	    msn_p2p_msg_is_data(flags))
 	{
 		/* Release all the messages and send the ACK */
 
@@ -515,11 +529,11 @@
 			 */
 			purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n");
 
-			slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, header);
+			slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, info);
 		} else if (!slpcall->wasted) {
 			purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n");
 
-			msn_slplink_send_ack(slplink, header);
+			msn_slplink_send_ack(slplink, info);
 			msn_slplink_send_queued_slpmsgs(slplink);
 		}
 	}
@@ -539,16 +553,17 @@
 		purple_xfer_prpl_ready(slpmsg->slpcall->xfer);
 	}
 	else if (slpmsg->size && slpmsg->buffer) {
-		if (G_MAXSIZE - part->size < part->header->offset
-				|| (part->header->offset + part->size) > slpmsg->size
-				|| slpmsg->header->offset != part->header->offset) {
+		guint64 offset = msn_p2p_info_get_offset(part->info);
+		if (G_MAXSIZE - part->size < offset
+				|| (offset + part->size) > slpmsg->size
+				|| msn_p2p_info_get_offset(slpmsg->p2p_info) != offset) {
 			purple_debug_error("msn",
 				"Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n",
-				slpmsg->size, part->header->offset, part->size);
+				slpmsg->size, offset, part->size);
 			g_return_if_reached();
 		} else {
-			memcpy(slpmsg->buffer + part->header->offset, part->buffer, part->size);
-			slpmsg->header->offset += part->size;
+			memcpy(slpmsg->buffer + offset, part->buffer, part->size);
+			msn_p2p_info_set_offset(slpmsg->p2p_info, offset + part->size);
 		}
 	}
 }
@@ -557,12 +572,12 @@
 msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpMessagePart *part)
 {
 	MsnSlpMessage *slpmsg;
-	MsnP2PHeader *header;
+	MsnP2PInfo *info;
 	guint64 offset;
 
-	header = part->header;
+	info = part->info;
 
-	if (header->total_size < header->length)
+	if (!msn_p2p_info_is_valid(info))
 	{
 		/* We seem to have received a bad header */
 		purple_debug_warning("msn", "Total size listed in SLP binary header "
@@ -571,12 +586,15 @@
 		return;
 	}
 
-	offset = header->offset;
+	offset = msn_p2p_info_get_offset(info);
 
 	if (offset == 0)
-		slpmsg = init_first_msg(slplink, header);
+		slpmsg = init_first_msg(slplink, info);
 	else {
-		slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id);
+		guint32 session_id, id;
+		session_id = msn_p2p_info_get_session_id(info);
+		id = msn_p2p_info_get_id(info);
+		slpmsg = msn_slplink_message_find(slplink, session_id, id);
 		if (slpmsg == NULL)
 		{
 			/* Probably the transfer was cancelled */
@@ -587,8 +605,7 @@
 
 	slpmsg_add_part(slpmsg, part);
 
-
-	if (msn_p2p_msg_is_data(slpmsg->header->flags) &&
+	if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(slpmsg->p2p_info)) &&
 		(slpmsg->slpcall != NULL))
 	{
 		slpmsg->slpcall->progress = TRUE;
@@ -606,8 +623,8 @@
 #endif
 
 	/* All the pieces of the slpmsg have been received */
-	if (header->offset + header->length >= header->total_size)
-		process_complete_msg(slplink, slpmsg, header);
+	if (msn_p2p_info_is_final(info))
+		process_complete_msg(slplink, slpmsg, info);
 
 	/* NOTE: The slpmsg will be destroyed in process_complete_msg or left in
 	   the slplink until fully received. Don't free it here!
--- a/libpurple/protocols/msn/slpmsg.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg.c	Wed Feb 02 23:26:42 2011 +0000
@@ -48,8 +48,7 @@
 	else
 		slpmsg->slplink = NULL;
 
-	slpmsg->header = g_new0(MsnP2PHeader, 1);
-	slpmsg->footer = NULL;
+	slpmsg->p2p_info = msn_p2p_info_new();
 
 	return slpmsg;
 }
@@ -90,8 +89,7 @@
 
 	slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg);
 
-	g_free(slpmsg->header);
-	g_free(slpmsg->footer);
+	msn_p2p_info_free(slpmsg->p2p_info);
 
 	g_free(slpmsg);
 }
@@ -193,7 +191,6 @@
 	slpmsg = msn_slpmsg_new(slplink);
 	msn_slpmsg_set_body(slpmsg, body, body_len);
 
-	slpmsg->sip = TRUE;
 	slpmsg->slpcall = slpcall;
 
 	g_free(body);
@@ -201,18 +198,20 @@
 	return slpmsg;
 }
 
-MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PHeader *header)
+MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PInfo *ack_info)
 {
 	MsnSlpMessage *slpmsg;
+	MsnP2PInfo *new_info;
 
 	slpmsg = msn_slpmsg_new(NULL);
 
-	slpmsg->header->session_id = header->session_id;
-	slpmsg->size       = header->total_size;
-	slpmsg->header->flags      = P2P_ACK;
-	slpmsg->header->ack_id     = header->id;
-	slpmsg->header->ack_sub_id = header->ack_id;
-	slpmsg->header->ack_size   = header->total_size;
+	new_info = slpmsg->p2p_info;
+	msn_p2p_info_set_session_id(new_info, msn_p2p_info_get_session_id(ack_info));
+	slpmsg->size = msn_p2p_info_get_total_size(ack_info);
+	msn_p2p_info_set_flags(new_info, P2P_ACK);
+	msn_p2p_info_set_ack_id(new_info, msn_p2p_info_get_id(ack_info));
+	msn_p2p_info_set_ack_sub_id(new_info, msn_p2p_info_get_ack_id(ack_info));
+	msn_p2p_info_set_ack_size(new_info, msn_p2p_info_get_total_size(ack_info));
 	slpmsg->info = "SLP ACK";
 
 	return slpmsg;
@@ -224,7 +223,7 @@
 
 	slpmsg = msn_slpmsg_new(NULL);
 	slpmsg->slpcall = slpcall;
-	slpmsg->header->flags = P2P_MSN_OBJ_DATA;
+	msn_p2p_info_set_flags(slpmsg->p2p_info, P2P_MSN_OBJ_DATA);
 	slpmsg->info = "SLP DATA";
 
 	msn_slpmsg_set_image(slpmsg, img);
@@ -239,7 +238,7 @@
 	slpmsg = msn_slpmsg_new(NULL);
 
 	slpmsg->slpcall = slpcall;
-	slpmsg->header->session_id = slpcall->session_id;
+	msn_p2p_info_set_session_id(slpmsg->p2p_info, slpcall->session_id);
 	msn_slpmsg_set_body(slpmsg, NULL, 4);
 	slpmsg->info = "SLP DATA PREP";
 
@@ -254,7 +253,7 @@
 	slpmsg = msn_slpmsg_new(NULL);
 
 	slpmsg->slpcall = slpcall;
-	slpmsg->header->flags = P2P_FILE_DATA;
+	msn_p2p_info_set_flags(slpmsg->p2p_info, P2P_FILE_DATA);
 	slpmsg->info = "SLP FILE";
 	slpmsg->size = size;
 
@@ -267,27 +266,25 @@
 	char *footer;
 	char *base;
 	char *tmp;
-	size_t siz;
+	size_t header_size, footer_size;
 
-	base = g_malloc(P2P_PACKET_HEADER_SIZE + slpmsg->size + P2P_PACKET_FOOTER_SIZE);
+	header = msn_p2p_header_to_wire(slpmsg->p2p_info, &header_size);
+	footer = msn_p2p_footer_to_wire(slpmsg->p2p_info, &footer_size);
+
+	base = g_malloc(header_size + slpmsg->size + footer_size);
 	tmp = base;
 
-	header = msn_p2p_header_to_wire(slpmsg->header);
-	footer = msn_p2p_footer_to_wire(slpmsg->footer);
-
-	siz = P2P_PACKET_HEADER_SIZE;
 	/* Copy header */
-	memcpy(tmp, header, siz);
-	tmp += siz;
+	memcpy(tmp, header, header_size);
+	tmp += header_size;
 
 	/* Copy body */
 	memcpy(tmp, slpmsg->buffer, slpmsg->size);
 	tmp += slpmsg->size;
 
 	/* Copy footer */
-	siz = P2P_PACKET_FOOTER_SIZE;
-	memcpy(tmp, footer, siz);
-	tmp += siz;
+	memcpy(tmp, footer, footer_size);
+	tmp += footer_size;
 
 	*ret_size = tmp - base;
 
@@ -303,15 +300,7 @@
 
 	str = g_string_new(NULL);
 
-	g_string_append_printf(str, "Session ID: %u\r\n", slpmsg->header->session_id);
-	g_string_append_printf(str, "ID:         %u\r\n", slpmsg->header->id);
-	g_string_append_printf(str, "Offset:     %" G_GUINT64_FORMAT "\r\n", slpmsg->header->offset);
-	g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", slpmsg->header->total_size);
-	g_string_append_printf(str, "Length:     %u\r\n", slpmsg->header->length);
-	g_string_append_printf(str, "Flags:      0x%x\r\n", slpmsg->header->flags);
-	g_string_append_printf(str, "ACK ID:     %u\r\n", slpmsg->header->ack_id);
-	g_string_append_printf(str, "SUB ID:     %u\r\n", slpmsg->header->ack_sub_id);
-	g_string_append_printf(str, "ACK Size:   %" G_GUINT64_FORMAT "\r\n", slpmsg->header->ack_size);
+	msn_p2p_info_to_string(slpmsg->p2p_info, str);
 
 	if (purple_debug_is_verbose() && slpmsg->buffer != NULL) {
 		g_string_append_len(str, (gchar*)slpmsg->buffer, slpmsg->size);
@@ -324,7 +313,5 @@
 
 	}
 
-	g_string_append_printf(str, "Footer:     %u\r\n", slpmsg->footer->value);
-
 	purple_debug_info("msn", "SlpMessage %s:\n{%s}\n", slpmsg->info, str->str);
 }
--- a/libpurple/protocols/msn/slpmsg.h	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg.h	Wed Feb 02 23:26:42 2011 +0000
@@ -45,13 +45,10 @@
 	MsnSlpLink *slplink; /**< The slplink through which this slp message is being sent. */
 	MsnSession *session;
 
-	MsnP2PHeader *header;
-	MsnP2PFooter *footer;
+	MsnP2PInfo *p2p_info;
 
 	long id;
 
-	gboolean sip; /**< A flag that states if this is a SIP slp message. */
-
 	gboolean ft;
 	PurpleStoredImage *img;
 	guchar *buffer;
@@ -94,8 +91,6 @@
 void msn_slpmsg_set_body(MsnSlpMessage *slpmsg, const char *body,
 						 long long size);
 void msn_slpmsg_set_image(MsnSlpMessage *slpmsg, PurpleStoredImage *img);
-void msn_slpmsg_open_file(MsnSlpMessage *slpmsg,
-						  const char *file_name);
 MsnSlpMessage * msn_slpmsg_sip_new(MsnSlpCall *slpcall, int cseq,
 								   const char *header,
 								   const char *branch,
@@ -109,7 +104,7 @@
  *
  * @return A new SlpMessage with ACK headers
  */
-MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PHeader *header);
+MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PInfo *info);
 
 /**
  * Create a new SLP message for MsnObject data.
--- a/libpurple/protocols/msn/slpmsg_part.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg_part.c	Wed Feb 02 23:26:42 2011 +0000
@@ -28,16 +28,14 @@
 #include "slpmsg.h"
 #include "slpmsg_part.h"
 
-MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer)
+MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PInfo *info)
 {
 	MsnSlpMessagePart *part;
 
 	part = g_new0(MsnSlpMessagePart, 1);
 
-	if (header)
-		part->header = g_memdup(header, P2P_PACKET_HEADER_SIZE);
-	if (footer)
-		part->footer = g_memdup(footer, P2P_PACKET_FOOTER_SIZE);
+	if (info)
+		part->info = msn_p2p_info_dup(info);
 
 	part->ack_cb = msn_slpmsgpart_ack;
 	part->nak_cb = msn_slpmsgpart_nak;
@@ -48,20 +46,22 @@
 MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len)
 {
 	MsnSlpMessagePart *part;
+	size_t len;
 	int body_len;
 
 	if (data_len < P2P_PACKET_HEADER_SIZE) {
 		return NULL;
 	}
 
-	part = msn_slpmsgpart_new(NULL, NULL);
+	part = msn_slpmsgpart_new(NULL);
+	part->info = msn_p2p_info_new();
 
 	/* Extract the binary SLP header */
-	part->header = msn_p2p_header_from_wire(data);
-	data += P2P_PACKET_HEADER_SIZE;
+	len = msn_p2p_header_from_wire(part->info, data);
+	data += len;
 
 	/* Extract the body */
-	body_len = data_len - P2P_PACKET_HEADER_SIZE - P2P_PACKET_FOOTER_SIZE;
+	body_len = data_len - len - P2P_PACKET_FOOTER_SIZE;
 	/* msg->body_len = msg->msnslp_header.length; */
 
 	if (body_len > 0) {
@@ -73,15 +73,14 @@
 
 	/* Extract the footer */
 	if (body_len >= 0)
-		part->footer = msn_p2p_footer_from_wire(data);
+		msn_p2p_footer_from_wire(part->info, data);
 
 	return part;
 }
 
 static void msn_slpmsgpart_destroy(MsnSlpMessagePart *part)
 {
-	g_free(part->header);
-	g_free(part->footer);
+	g_free(part->info);
 	g_free(part->buffer);
 
 	g_free(part);
@@ -138,27 +137,25 @@
 	char *footer;
 	char *base;
 	char *tmp;
-	size_t siz;
+	size_t header_size, footer_size;
 
-	base = g_malloc(P2P_PACKET_HEADER_SIZE + part->size + P2P_PACKET_FOOTER_SIZE);
+	header = msn_p2p_header_to_wire(part->info, &header_size);
+	footer = msn_p2p_footer_to_wire(part->info, &footer_size);
+
+	base = g_malloc(header_size + part->size + footer_size);
 	tmp = base;
 
-	header = msn_p2p_header_to_wire(part->header);
-	footer = msn_p2p_footer_to_wire(part->footer);
-
-	siz = P2P_PACKET_HEADER_SIZE;
 	/* Copy header */
-	memcpy(tmp, header, siz);
-	tmp += siz;
+	memcpy(tmp, header, header_size);
+	tmp += header_size;
 
 	/* Copy body */
 	memcpy(tmp, part->buffer, part->size);
 	tmp += part->size;
 
 	/* Copy footer */
-	siz = P2P_PACKET_FOOTER_SIZE;
-	memcpy(tmp, footer, siz);
-	tmp += siz;
+	memcpy(tmp, footer, footer_size);
+	tmp += footer_size;
 
 	*ret_size = tmp - base;
 
@@ -167,23 +164,27 @@
 
 	return base;
 }
+
 /* We have received the message ack */
 void
 msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data)
 {
 	MsnSlpMessage *slpmsg;
+	guint64 offset;
 	long long real_size;
 
 	slpmsg = data;
 
-	real_size = (slpmsg->header->flags == P2P_ACK) ? 0 : slpmsg->size;
+	real_size = (msn_p2p_info_get_flags(slpmsg->p2p_info) == P2P_ACK) ? 0 : slpmsg->size;
 
-	slpmsg->header->offset += part->header->length;
+	offset = msn_p2p_info_get_offset(slpmsg->p2p_info);
+	offset += msn_p2p_info_get_length(part->info);
+	msn_p2p_info_set_offset(slpmsg->p2p_info, offset);
 
 	slpmsg->parts = g_list_remove(slpmsg->parts, part);
 	msn_slpmsgpart_unref(part);
 
-	if (slpmsg->header->offset < real_size)
+	if (offset < real_size)
 	{
 		if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
 		{
@@ -196,7 +197,7 @@
 	else
 	{
 		/* The whole message has been sent */
-		if (msn_p2p_msg_is_data(slpmsg->header->flags))
+		if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(slpmsg->p2p_info)))
 		{
 			if (slpmsg->slpcall != NULL)
 			{
@@ -222,3 +223,9 @@
 	msn_slpmsgpart_unref(part);
 }
 
+void
+msn_slpmsgpart_to_string(MsnSlpMessagePart *part, GString *str)
+{
+	msn_p2p_info_to_string(part->info, str);
+}
+
--- a/libpurple/protocols/msn/slpmsg_part.h	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/msn/slpmsg_part.h	Wed Feb 02 23:26:42 2011 +0000
@@ -34,8 +34,7 @@
 {
 	guint ref_count;
 
-	MsnP2PHeader *header;
-	MsnP2PFooter *footer;
+	MsnP2PInfo *info;
 
 	MsnSlpPartCb ack_cb;
 	MsnSlpPartCb nak_cb;
@@ -45,7 +44,7 @@
 	size_t size;
 };
 
-MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer);
+MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PInfo *info);
 
 MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len);
 
@@ -60,4 +59,8 @@
 void msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data);
 
 void msn_slpmsgpart_nak(MsnSlpMessagePart *part, void *data);
+
+void msn_slpmsgpart_to_string(MsnSlpMessagePart *part, GString *str);
+
 #endif /* MSN_SLPMSG_PART_H */
+
--- a/libpurple/protocols/novell/novell.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/novell/novell.c	Wed Feb 02 23:26:42 2011 +0000
@@ -74,7 +74,7 @@
 _sync_privacy_lists(NMUser *user);
 
 static void
-_show_info(PurpleConnection * gc, NMUserRecord * user_record);
+_show_info(PurpleConnection * gc, NMUserRecord * user_record, char * name);
 
 const char *
 _get_conference_name(int id);
@@ -705,7 +705,7 @@
 		user_record = (NMUserRecord *) resp_data;
 		if (user_record) {
 			_show_info(purple_account_get_connection(user->client_data),
-					   user_record);
+					   user_record, g_strdup(name));
 		}
 	} else {
 		gc = purple_account_get_connection(user->client_data);
@@ -1505,7 +1505,7 @@
 
 /* Display a dialog box showing the properties for the given user record */
 static void
-_show_info(PurpleConnection * gc, NMUserRecord * user_record)
+_show_info(PurpleConnection * gc, NMUserRecord * user_record, char * name)
 {
 	PurpleNotifyUserInfo *user_info =	purple_notify_user_info_new();
 	int count, i;
@@ -1544,9 +1544,10 @@
 		}
 	}
 
-	purple_notify_userinfo(gc, nm_user_record_get_userid(user_record),
-						 user_info, NULL, NULL);
+	purple_notify_userinfo(gc, name, user_info, NULL, NULL);
 	purple_notify_user_info_destroy(user_info);
+
+	g_free(name);
 }
 
 /* Send a join conference, the first item in the parms list is the
@@ -2912,11 +2913,9 @@
 
 		user_record = nm_find_user_record(user, name);
 		if (user_record) {
-
-			_show_info(gc, user_record);
+			_show_info(gc, user_record, g_strdup(name));
 
 		} else {
-
 			rc = nm_send_get_details(user, name,
 									 _get_details_resp_show_info, g_strdup(name));
 
--- a/libpurple/protocols/oscar/family_feedbag.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/oscar/family_feedbag.c	Wed Feb 02 23:26:42 2011 +0000
@@ -44,10 +44,66 @@
  */
 
 #include "oscar.h"
+#include "debug.h"
 
 static int aim_ssi_addmoddel(OscarData *od);
 
 /**
+ * List types based on http://dev.aol.com/aim/oscar/#FEEDBAG (archive.org)
+ * and http://iserverd.khstu.ru/oscar/ssi_item.html
+ *
+ * @param type The type of a list item as integer number, as provided by an aim_ssi_item struct.
+ * @return Returns the name of the item type as a character string.
+ */
+static const gchar*
+aim_ssi_type_to_string(guint16 type)
+{
+	struct TypeStringPair
+	{
+		guint16 type;
+		const gchar *string;
+	};
+	static const struct TypeStringPair type_strings[] = {
+		{ 0x0000, "Buddy" },
+		{ 0x0001, "Group" },
+		{ 0x0002, "Permit/Visible" },
+		{ 0x0003, "Deny/Invisible" },
+		{ 0x0004, "PDInfo" },
+		{ 0x0005, "PresencePrefs" }, 
+		{ 0x0006, "Non-Buddy Info" },
+		{ 0x0009, "ClientPrefs" },
+		{ 0x000e, "ICQDeny/Ignore" },
+		{ 0x0014, "Buddy Icon" }, 
+		{ 0x0015, "Recent Buddies" },
+		{ 0x0019, "Non-Buddy" },
+		{ 0x001d, "Vanity Info" },
+		{ 0x0020, "ICQ-MDir" },
+		{ 0x0029, "Facebook" },
+	};
+	int i;
+	for (i = 0; i < G_N_ELEMENTS(type_strings); i++) {
+		if (type_strings[i].type == type) {
+			return type_strings[i].string;
+		}
+	}
+	return "unknown";
+}
+
+/** For debug log output: Appends a line containing information about a given list item to a string.
+ *
+ * @param str String to which the line will be appended.
+ * @param prefix A string which will be prepended to the line.
+ * @param item List item from which information is extracted.
+ */
+static void
+aim_ssi_item_debug_append(GString *str, char *prefix, struct aim_ssi_item *item)
+{
+	g_string_append_printf(str, 
+		"%s gid=0x%04hx, bid=0x%04hx, list_type=0x%04hx [%s], name=%s.\n",
+		prefix, item->gid, item->bid, item->type, aim_ssi_type_to_string(item->type), item->name);
+}
+
+/**
  * Locally rebuild the 0x00c8 TLV in the additional data of the given group.
  *
  * @param list A pointer to a pointer to the current list of items.
@@ -478,6 +534,7 @@
 	struct aim_ssi_item *cur1, *cur2;
 	struct aim_ssi_tmp *cur, *new;
 	int n = 0;
+	GString *debugstr = g_string_new("");
 
 	/*
 	 * The variable "n" is used to limit the number of addmoddel's that
@@ -517,6 +574,7 @@
 					cur->next = new;
 				} else
 					od->ssi.pending = new;
+			       	aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1);
 			}
 		}
 	}
@@ -537,6 +595,7 @@
 					cur->next = new;
 				} else
 					od->ssi.pending = new;
+			       	aim_ssi_item_debug_append(debugstr, "Adding item ", cur1);
 			}
 		}
 	}
@@ -558,9 +617,21 @@
 					cur->next = new;
 				} else
 					od->ssi.pending = new;
+			       	aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1);
 			}
 		}
 	}
+	if (debugstr->len > 0) {
+		purple_debug_info("oscar", "%s", debugstr->str);
+		if (purple_debug_is_verbose()) {
+	    		g_string_truncate(debugstr, 0);
+			for (cur1 = od->ssi.local; cur1; cur1 = cur1->next) 
+				aim_ssi_item_debug_append(debugstr, "\t", cur1);
+			purple_debug_misc("oscar", "Dumping item list of account %s:\n%s",
+				purple_connection_get_account(od->gc)->username, debugstr->str);
+		}
+	}
+	g_string_free(debugstr, TRUE);
 
 	/* We're out of stuff to do, so tell the AIM servers we're done and exit */
 	if (!od->ssi.pending) {
@@ -1165,6 +1236,7 @@
 	guint16 namelen, gid, bid, type;
 	char *name;
 	GSList *data;
+	GString *debugstr = g_string_new("");
 
 	fmtver = byte_stream_get8(bs); /* Version of ssi data.  Should be 0x00 */
 	od->ssi.numitems += byte_stream_get16(bs); /* # of items in this SSI SNAC */
@@ -1179,10 +1251,13 @@
 		bid = byte_stream_get16(bs);
 		type = byte_stream_get16(bs);
 		data = aim_tlvlist_readlen(bs, byte_stream_get16(bs));
-		aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data);
+		aim_ssi_item_debug_append(debugstr, "\t", aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data));
 		g_free(name);
 		aim_tlvlist_free(data);
 	}
+	purple_debug_misc("oscar", "Reading items from tlvlist for account %s:\n%s",
+		purple_connection_get_account(od->gc)->username, debugstr->str);
+	g_string_free(debugstr, TRUE);
 
 	/* Read in the timestamp */
 	od->ssi.timestamp = byte_stream_get32(bs);
--- a/libpurple/protocols/zephyr/Zinternal.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/zephyr/Zinternal.c	Wed Feb 02 23:26:42 2011 +0000
@@ -30,7 +30,6 @@
 #else
 #include <arpa/inet.h>
 #include <sys/socket.h>
-#include <utmp.h>
 #endif
 
 int __Zephyr_fd = -1;
--- a/libpurple/protocols/zephyr/zephyr.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Wed Feb 02 23:26:42 2011 +0000
@@ -870,12 +870,12 @@
 			zephyr_triple *zt1, *zt2;
 			gchar *send_inst_utf8;
 			zephyr_account *zephyr = gc->proto_data;
-			zt1 = new_triple(gc->proto_data,notice.z_class, notice.z_class_inst, notice.z_recipient);
-			zt2 = find_sub_by_triple(gc->proto_data,zt1);
+			zt1 = new_triple(zephyr,notice.z_class, notice.z_class_inst, notice.z_recipient);
+			zt2 = find_sub_by_triple(zephyr,zt1);
 			if (!zt2) {
 				/* This is a server supplied subscription */
 				zephyr->subscrips = g_slist_append(zephyr->subscrips, new_triple(zephyr,zt1->class,zt1->instance,zt1->recipient));
-				zt2 = find_sub_by_triple(gc->proto_data,zt1);
+				zt2 = find_sub_by_triple(zephyr,zt1);
 			}
 
 			if (!zt2->open) {
@@ -1499,6 +1499,7 @@
 
 static void process_anyone(PurpleConnection *gc)
 {
+	zephyr_account *zephyr = purple_connection_get_protocol_data(gc);
 	FILE *fd;
 	gchar buff[BUFSIZ], *filename;
 	PurpleGroup *g;
@@ -1515,7 +1516,7 @@
 			strip_comments(buff);
 			if (buff[0]) {
 				if (!(b = purple_find_buddy(gc->account, buff))) {
-					char *stripped_user = zephyr_strip_local_realm(gc->proto_data,buff);
+					char *stripped_user = zephyr_strip_local_realm(zephyr,buff);
 					purple_debug_info("zephyr","stripped_user %s\n",stripped_user);
 					if (!(b = purple_find_buddy(gc->account,stripped_user))){
 						b = purple_buddy_new(gc->account, stripped_user, NULL);
@@ -1924,13 +1925,12 @@
 	fclose(fd);
 }
 
-static void write_anyone(PurpleConnection *gc)
+static void write_anyone(zephyr_account *zephyr)
 {
 	GSList *buddies;
 	char *fname;
 	FILE *fd;
 	PurpleAccount *account;
-	zephyr_account* zephyr = gc->proto_data;
 	fname = g_strdup_printf("%s/.anyone", purple_home_dir());
 	fd = g_fopen(fname, "w");
 	if (!fd) {
@@ -1938,7 +1938,7 @@
 		return;
 	}
 
-	account = purple_connection_get_account(gc);
+	account = zephyr->account;
 	for (buddies = purple_find_buddies(account, NULL); buddies;
 			buddies = g_slist_delete_link(buddies, buddies)) {
 		PurpleBuddy *b = buddies->data;
@@ -1966,10 +1966,10 @@
 	g_list_free(zephyr->pending_zloc_names);
 
 	if (purple_account_get_bool(gc->account, "write_anyone", FALSE))
-		write_anyone(gc);
+		write_anyone(zephyr);
 
 	if (purple_account_get_bool(gc->account, "write_zsubs", FALSE))
-		write_zsubs(gc->proto_data);
+		write_zsubs(zephyr);
 
 	s = zephyr->subscrips;
 	while (s) {
@@ -2032,7 +2032,7 @@
 	char *recipient;
 	zephyr_account *zephyr = gc->proto_data;
 
-	zt = find_sub_by_id(gc->proto_data,id);
+	zt = find_sub_by_id(zephyr,id);
 	if (!zt)
 		/* this should never happen. */
 		return -EINVAL;
@@ -2432,8 +2432,8 @@
 	if (!g_ascii_strcasecmp(recip, "%me%"))
 		recip = zephyr->username;
 
-	zt1 = new_triple(gc->proto_data,classname, instname, recip);
-	zt2 = find_sub_by_triple(gc->proto_data,zt1);
+	zt1 = new_triple(zephyr,classname, instname, recip);
+	zt2 = find_sub_by_triple(zephyr,zt1);
 	if (zt2) {
 		free_triple(zt1);
 		if (!zt2->open) {
@@ -2563,7 +2563,7 @@
 	zephyr_account* zephyr = gc->proto_data;
 	char *sender = (char *)zephyr->username;
 
-	zt = find_sub_by_id(gc->proto_data,id);
+	zt = find_sub_by_id(zephyr,id);
 	/* find_sub_by_id can return NULL */
 	if (!zt)
 		return;
--- a/libpurple/tests/Makefile.am	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/tests/Makefile.am	Wed Feb 02 23:26:42 2011 +0000
@@ -11,6 +11,7 @@
 	    tests.h \
 		test_cipher.c \
 		test_jabber_caps.c \
+		test_jabber_digest_md5.c \
 		test_jabber_jutil.c \
 		test_jabber_scram.c \
 		test_qq.c \
--- a/libpurple/tests/check_libpurple.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/tests/check_libpurple.c	Wed Feb 02 23:26:42 2011 +0000
@@ -85,6 +85,7 @@
 
 	srunner_add_suite(sr, cipher_suite());
 	srunner_add_suite(sr, jabber_caps_suite());
+	srunner_add_suite(sr, jabber_digest_md5_suite());
 	srunner_add_suite(sr, jabber_jutil_suite());
 	srunner_add_suite(sr, jabber_scram_suite());
 	srunner_add_suite(sr, qq_suite());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/test_jabber_digest_md5.c	Wed Feb 02 23:26:42 2011 +0000
@@ -0,0 +1,59 @@
+#include <string.h>
+
+#include "tests.h"
+#include "../util.h"
+#include "../protocols/jabber/auth_digest_md5.h"
+#include "../protocols/jabber/jutil.h"
+
+START_TEST(test_parsing)
+{
+	GHashTable *table;
+
+	table = jabber_auth_digest_md5_parse("r=\"realm\",token=   \"   asdf\"");
+	fail_if(g_hash_table_lookup(table, "r") == NULL);
+	assert_string_equal("realm", g_hash_table_lookup(table, "r"));
+	fail_if(g_hash_table_lookup(table, "token") == NULL);
+	assert_string_equal("asdf", g_hash_table_lookup(table, "token"));
+	g_hash_table_destroy(table);
+
+	table = jabber_auth_digest_md5_parse("r=\"a\", token=   \"   asdf\"");
+	fail_if(g_hash_table_lookup(table, "r") == NULL);
+	assert_string_equal("a", g_hash_table_lookup(table, "r"));
+	fail_if(g_hash_table_lookup(table, "token") == NULL);
+	assert_string_equal("asdf", g_hash_table_lookup(table, "token"));
+	g_hash_table_destroy(table);
+
+	table = jabber_auth_digest_md5_parse("r=\"\", token=   \"   asdf\"");
+	fail_if(g_hash_table_lookup(table, "r") == NULL);
+	assert_string_equal("", g_hash_table_lookup(table, "r"));
+	fail_if(g_hash_table_lookup(table, "token") == NULL);
+	assert_string_equal("asdf", g_hash_table_lookup(table, "token"));
+	g_hash_table_destroy(table);
+
+	table = jabber_auth_digest_md5_parse("realm=\"somerealm\",nonce=\"OA6MG9tEQGm2hh\",qop=\"auth\",charset=utf-8,algorithm=md5-sess");
+	fail_if(g_hash_table_lookup(table, "realm") == NULL);
+	assert_string_equal("somerealm", g_hash_table_lookup(table, "realm"));
+	fail_if(g_hash_table_lookup(table, "nonce") == NULL);
+	assert_string_equal("OA6MG9tEQGm2hh", g_hash_table_lookup(table, "nonce"));
+	fail_if(g_hash_table_lookup(table, "qop") == NULL);
+	assert_string_equal("auth", g_hash_table_lookup(table, "qop"));
+	fail_if(g_hash_table_lookup(table, "charset") == NULL);
+	assert_string_equal("utf-8", g_hash_table_lookup(table, "charset"));
+	fail_if(g_hash_table_lookup(table, "algorithm") == NULL);
+	assert_string_equal("md5-sess", g_hash_table_lookup(table, "algorithm"));
+
+	g_hash_table_destroy(table);
+
+}
+END_TEST
+
+Suite *
+jabber_digest_md5_suite(void)
+{
+	Suite *s = suite_create("Jabber SASL DIGEST-MD5 functions");
+
+	TCase *tc = tcase_create("Parsing Functionality");
+	tcase_add_test(tc, test_parsing);
+	suite_add_tcase(s, tc);
+	return s;
+}
--- a/libpurple/tests/tests.h	Sun Jan 09 23:32:10 2011 +0000
+++ b/libpurple/tests/tests.h	Wed Feb 02 23:26:42 2011 +0000
@@ -10,6 +10,7 @@
 Suite * master_suite(void);
 Suite * cipher_suite(void);
 Suite * jabber_caps_suite(void);
+Suite * jabber_digest_md5_suite(void);
 Suite * jabber_jutil_suite(void);
 Suite * jabber_scram_suite(void);
 Suite * qq_suite(void);
--- a/pidgin/gtkutils.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/pidgin/gtkutils.c	Wed Feb 02 23:26:42 2011 +0000
@@ -526,35 +526,68 @@
 }
 
 static gpointer
-aop_option_menu_get_selected(GtkWidget *optmenu)
+aop_option_menu_get_selected(GtkWidget *optmenu, GtkWidget **p_item)
 {
-	gpointer data = NULL;
-	GtkTreeIter iter;
-
-	g_return_val_if_fail(optmenu != NULL, NULL);
-
-	if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(optmenu), &iter))
-		gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu)), &iter, 2, &data, -1);
-
-	return data;
+	GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu));
+	GtkWidget *item = gtk_menu_get_active(GTK_MENU(menu));
+	if (p_item)
+		(*p_item) = item;
+	return item ? g_object_get_data(G_OBJECT(item), "aop_per_item_data") : NULL;
 }
 
 static void
 aop_menu_cb(GtkWidget *optmenu, GCallback cb)
 {
+	GtkWidget *item;
+	gpointer per_item_data;
+
+	per_item_data = aop_option_menu_get_selected(optmenu, &item);
+
 	if (cb != NULL) {
-		((void (*)(GtkWidget *, gpointer, gpointer))cb)(optmenu,
-			aop_option_menu_get_selected(optmenu),
-			g_object_get_data(G_OBJECT(optmenu), "user_data"));
+		((void (*)(GtkWidget *, gpointer, gpointer))cb)(item, per_item_data, g_object_get_data(G_OBJECT(optmenu), "user_data"));
 	}
 }
 
-static void
-aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu)
+static GtkWidget *
+aop_menu_item_new(GtkSizeGroup *sg, GdkPixbuf *pixbuf, const char *lbl, gpointer per_item_data, const char *data)
 {
-	gtk_combo_box_set_model(GTK_COMBO_BOX(optmenu), new_aop_menu->model);
-	gtk_combo_box_set_active(GTK_COMBO_BOX(optmenu), new_aop_menu->default_item);
-	g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", new_aop_menu, (GDestroyNotify)g_free);
+	GtkWidget *item;
+	GtkWidget *hbox;
+	GtkWidget *image;
+	GtkWidget *label;
+
+	item = gtk_menu_item_new();
+	gtk_widget_show(item);
+
+	hbox = gtk_hbox_new(FALSE, 4);
+	gtk_widget_show(hbox);
+
+	/* Create the image */
+	if (pixbuf == NULL)
+		image = gtk_image_new();
+	else
+		image = gtk_image_new_from_pixbuf(pixbuf);
+	gtk_widget_show(image);
+
+	if (sg)
+		gtk_size_group_add_widget(sg, image);
+
+	/* Create the label */
+	label = gtk_label_new (lbl);
+	gtk_widget_show (label);
+	gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+	gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+
+	gtk_container_add(GTK_CONTAINER(item), hbox);
+	gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+
+	g_object_set_data(G_OBJECT (item), data, per_item_data);
+	g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data);
+
+	pidgin_set_accessible_label(item, label);
+
+	return item;
 }
 
 static GdkPixbuf *
@@ -595,19 +628,16 @@
 static GtkWidget *
 aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data)
 {
-	GtkWidget *optmenu = NULL;
-	GtkCellRenderer *cr = NULL;
-
-	optmenu = gtk_combo_box_new();
+	GtkWidget *optmenu;
+
+	optmenu = gtk_option_menu_new();
 	gtk_widget_show(optmenu);
-	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(optmenu), cr = gtk_cell_renderer_pixbuf_new(), FALSE);
-	gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(optmenu), cr, "pixbuf", 0);
-	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(optmenu), cr = gtk_cell_renderer_text_new(), TRUE);
-	gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(optmenu), cr, "text", 1);
-
-	aop_option_menu_replace_menu(optmenu, aop_menu);
-	if (aop_menu->default_item == -1)
-		gtk_combo_box_set_active(GTK_COMBO_BOX(optmenu), 0);
+	gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), aop_menu->menu);
+
+	if (aop_menu->default_item != -1)
+		gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), aop_menu->default_item);
+
+	g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", aop_menu, (GDestroyNotify)g_free);
 	g_object_set_data(G_OBJECT(optmenu), "user_data", user_data);
 
 	g_signal_connect(G_OBJECT(optmenu), "changed", G_CALLBACK(aop_menu_cb), cb);
@@ -616,20 +646,32 @@
 }
 
 static void
+aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu)
+{
+	if (gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))
+		gtk_option_menu_remove_menu(GTK_OPTION_MENU(optmenu));
+
+	gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), new_aop_menu->menu);
+
+	if (new_aop_menu->default_item != -1)
+		gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), new_aop_menu->default_item);
+
+	g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", new_aop_menu, (GDestroyNotify)g_free);
+}
+
+static void
 aop_option_menu_select_by_data(GtkWidget *optmenu, gpointer data)
 {
-	GtkTreeModel *model;
-	GtkTreeIter iter;
-	gpointer iter_data;
-	model = gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu));
-	if (gtk_tree_model_get_iter_first(model, &iter)) {
-		do {
-			gtk_tree_model_get(model, &iter, 2, &iter_data, -1);
-			if (iter_data == data) {
-				gtk_combo_box_set_active_iter(GTK_COMBO_BOX(optmenu), &iter);
-				return;
-			}
-		} while (gtk_tree_model_iter_next(model, &iter));
+	guint idx;
+	GList *llItr = NULL;
+
+	for (idx = 0, llItr = GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))->children;
+	     llItr != NULL;
+	     llItr = llItr->next, idx++) {
+		if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) {
+			gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx);
+			break;
+		}
 	}
 }
 
@@ -639,17 +681,16 @@
 	AopMenu *aop_menu = NULL;
 	PurplePlugin *plugin;
 	GdkPixbuf *pixbuf = NULL;
-	GtkTreeIter iter;
-	GtkListStore *ls;
+	GtkSizeGroup *sg;
 	GList *p;
 	const char *gtalk_name = NULL, *facebook_name = NULL;
 	int i;
 
-	ls = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
-
 	aop_menu = g_malloc0(sizeof(AopMenu));
 	aop_menu->default_item = -1;
-	aop_menu->model = GTK_TREE_MODEL(ls);
+	aop_menu->menu = gtk_menu_new();
+	gtk_widget_show(aop_menu->menu);
+	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
 	if (purple_find_prpl("prpl-jabber")) {
 		gtalk_name = _("Google Talk");
@@ -665,11 +706,14 @@
 		if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) {
 			char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
 			                                  "16", "google-talk.png", NULL);
+			GtkWidget *item;
+
 			pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
 			g_free(filename);
 
-			gtk_list_store_append(ls, &iter);
-			gtk_list_store_set(ls, &iter, 0, pixbuf, 1, gtalk_name, 2, "prpl-jabber", -1);
+			gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
+				item = aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber", "protocol"));
+			g_object_set_data(G_OBJECT(item), "fakegoogle", GINT_TO_POINTER(1));
 
 			if (pixbuf)
 				g_object_unref(pixbuf);
@@ -686,8 +730,9 @@
 			pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
 			g_free(filename);
 
-			gtk_list_store_append(ls, &iter);
-			gtk_list_store_set(ls, &iter, 0, pixbuf, 1, facebook_name, 2, "prpl-jabber", -1);
+			gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
+				item = aop_menu_item_new(sg, pixbuf, facebook_name, "prpl-jabber", "protocol"));
+			g_object_set_data(G_OBJECT(item), "fakefacebook", GINT_TO_POINTER(1));
 
 			if (pixbuf)
 				g_object_unref(pixbuf);
@@ -698,8 +743,8 @@
 
 		pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL);
 
-		gtk_list_store_append(ls, &iter);
-		gtk_list_store_set(ls, &iter, 0, pixbuf, 1, plugin->info->name, 2, plugin->info->id, -1);
+		gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
+			aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id, "protocol"));
 
 		if (pixbuf)
 			g_object_unref(pixbuf);
@@ -707,6 +752,9 @@
 		if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id))
 			aop_menu->default_item = i;
 	}
+
+	g_object_unref(sg);
+
 	return aop_menu;
 }
 
@@ -720,13 +768,13 @@
 const char *
 pidgin_protocol_option_menu_get_selected(GtkWidget *optmenu)
 {
-	return (const char *)aop_option_menu_get_selected(optmenu);
+	return (const char *)aop_option_menu_get_selected(optmenu, NULL);
 }
 
 PurpleAccount *
 pidgin_account_option_menu_get_selected(GtkWidget *optmenu)
 {
-	return (PurpleAccount *)aop_option_menu_get_selected(optmenu);
+	return (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL);
 }
 
 static AopMenu *
@@ -738,8 +786,7 @@
 	GdkPixbuf *pixbuf = NULL;
 	GList *list;
 	GList *p;
-	GtkListStore *ls;
-	GtkTreeIter iter;
+	GtkSizeGroup *sg;
 	int i;
 	char buf[256];
 
@@ -748,11 +795,11 @@
 	else
 		list = purple_connections_get_all();
 
-	ls = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
-
 	aop_menu = g_malloc0(sizeof(AopMenu));
 	aop_menu->default_item = -1;
-	aop_menu->model = GTK_TREE_MODEL(ls);
+	aop_menu->menu = gtk_menu_new();
+	gtk_widget_show(aop_menu->menu);
+	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
 	for (p = list, i = 0; p != NULL; p = p->next, i++) {
 		if (show_all)
@@ -787,8 +834,8 @@
 					   purple_account_get_protocol_name(account));
 		}
 
-		gtk_list_store_append(ls, &iter);
-		gtk_list_store_set(ls, &iter, 0, pixbuf, 1, buf, 2, account, -1);
+		gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
+			aop_menu_item_new(sg, pixbuf, buf, account, "account"));
 
 		if (pixbuf)
 			g_object_unref(pixbuf);
@@ -796,6 +843,9 @@
 		if (default_account && account == default_account)
 			aop_menu->default_item = i;
 	}
+
+	g_object_unref(sg);
+
 	return aop_menu;
 }
 
@@ -806,7 +856,7 @@
 	PurpleAccount *account;
 	PurpleFilterAccountFunc filter_func;
 
-	account = (PurpleAccount *)aop_option_menu_get_selected(optmenu);
+	account = (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL);
 	show_all = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(optmenu), "show_all"));
 	filter_func = g_object_get_data(G_OBJECT(optmenu), "filter_func");
 
@@ -876,6 +926,24 @@
 	return optmenu;
 }
 
+gboolean
+pidgin_check_if_dir(const char *path, GtkFileSelection *filesel)
+{
+	char *dirname = NULL;
+
+	if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
+		/* append a / if needed */
+		if (path[strlen(path) - 1] != G_DIR_SEPARATOR) {
+			dirname = g_strconcat(path, G_DIR_SEPARATOR_S, NULL);
+		}
+		gtk_file_selection_set_filename(filesel, (dirname != NULL) ? dirname : path);
+		g_free(dirname);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 void
 pidgin_setup_gtkspell(GtkTextView *textview)
 {
@@ -1394,6 +1462,7 @@
 
 static void dnd_image_ok_callback(_DndData *data, int choice)
 {
+	const gchar *shortname;
 	gchar *filedata;
 	size_t size;
 	struct stat st;
@@ -1448,7 +1517,9 @@
 
 			break;
 		}
-		id = purple_imgstore_add_with_id(filedata, size, data->filename);
+		shortname = strrchr(data->filename, G_DIR_SEPARATOR);
+		shortname = shortname ? shortname + 1 : data->filename;
+		id = purple_imgstore_add_with_id(filedata, size, shortname);
 
 		gtk_text_buffer_get_iter_at_mark(GTK_IMHTML(gtkconv->entry)->text_buffer, &iter,
 						 gtk_text_buffer_get_insert(GTK_IMHTML(gtkconv->entry)->text_buffer));
--- a/pidgin/plugins/vvconfig.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/pidgin/plugins/vvconfig.c	Wed Feb 02 23:26:42 2011 +0000
@@ -82,20 +82,11 @@
 	GstPropertyProbe *probe;
 	const GParamSpec *pspec;
 
-	if (!strcmp(element_name, "<custom>")) {
-		ret = g_list_prepend(ret, NULL);
-		ret = g_list_prepend(ret, (gpointer)_("Default"));
-		ret = g_list_prepend(ret, "");
-		return ret;
-	}
-
 	ret = g_list_prepend(ret, (gpointer)_("Default"));
 	ret = g_list_prepend(ret, "");
 
-	if (*element_name == '\0') {
-		ret = g_list_prepend(ret, NULL);
-		ret = g_list_reverse(ret);
-		return ret;
+	if (!strcmp(element_name, "<custom>") || (*element_name == '\0')) {
+		return g_list_reverse(ret);
 	}
 
 	element = gst_element_factory_make(element_name, "test");
@@ -120,9 +111,7 @@
 		array = gst_property_probe_probe_and_get_values (probe, pspec);
 		if (array == NULL) {
 			purple_debug_info("vvconfig", "'%s' has no devices\n", element_name);
-			ret = g_list_prepend(ret, NULL);
-			ret = g_list_reverse(ret);
-			return ret;
+			return g_list_reverse(ret);
 		}
 
 		for (n=0; n < array->n_values; ++n) {
@@ -153,10 +142,7 @@
 	}
 	gst_object_unref(element);
 
-	ret = g_list_prepend(ret, NULL);
-	ret = g_list_reverse(ret);
-
-	return ret;
+	return g_list_reverse(ret);
 }
 
 static GList *
@@ -173,7 +159,6 @@
 			ret = g_list_prepend(ret, (gpointer)plugins[0]);
 		}
 	}
-	ret = g_list_prepend(ret, NULL);
 	ret = g_list_reverse(ret);
 	return ret;
 }
@@ -236,7 +221,8 @@
 	pref = g_strdup(name);
 	strcpy(pref + strlen(pref) - strlen("plugin"), "device");
 	devices = get_element_devices(value);
-	if (g_list_find(devices, purple_prefs_get_string(pref)) == NULL)
+	if (g_list_find_custom(devices, purple_prefs_get_string(pref),
+			(GCompareFunc)strcmp) == NULL)
 		purple_prefs_set_string(pref, g_list_next(devices)->data);
 	widget = pidgin_prefs_dropdown_from_list(parent,
 			label, PURPLE_PREF_STRING,
--- a/pidgin/win32/nsis/pidgin-installer.nsi	Sun Jan 09 23:32:10 2011 +0000
+++ b/pidgin/win32/nsis/pidgin-installer.nsi	Wed Feb 02 23:26:42 2011 +0000
@@ -530,6 +530,7 @@
     Push "xmpp"
     Call un.UnregisterURIHandler
 
+    Delete "$INSTDIR\ca-certs\AddTrust_External_Root.pem"
     Delete "$INSTDIR\ca-certs\America_Online_Root_Certification_Authority_1.pem"
     Delete "$INSTDIR\ca-certs\AOL_Member_CA.pem"
     Delete "$INSTDIR\ca-certs\CAcert_Class3.pem"
--- a/pidgin/win32/winpidgin.c	Sun Jan 09 23:32:10 2011 +0000
+++ b/pidgin/win32/winpidgin.c	Wed Feb 02 23:26:42 2011 +0000
@@ -632,11 +632,11 @@
 			} else {
 				if (strchr(__argv[i], 'd'))
 					debug = TRUE;
-				else if (strchr(__argv[i], 'h'))
+				if (strchr(__argv[i], 'h'))
 					help = TRUE;
-				else if (strchr(__argv[i], 'v'))
+				if (strchr(__argv[i], 'v'))
 					version = TRUE;
-				else if (strchr(__argv[i], 'm'))
+				if (strchr(__argv[i], 'm'))
 					multiple = TRUE;
 			}
 		}
--- a/po/POTFILES.in	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/POTFILES.in	Wed Feb 02 23:26:42 2011 +0000
@@ -124,8 +124,8 @@
 libpurple/protocols/mxit/filexfer.c
 libpurple/protocols/mxit/http.c
 libpurple/protocols/mxit/login.c
+libpurple/protocols/mxit/multimx.c
 libpurple/protocols/mxit/mxit.c
-libpurple/protocols/mxit/multimx.c
 libpurple/protocols/mxit/profile.c
 libpurple/protocols/mxit/protocol.c
 libpurple/protocols/mxit/roster.c
@@ -148,8 +148,8 @@
 libpurple/protocols/oscar/oft.c
 libpurple/protocols/oscar/oscar.c
 libpurple/protocols/oscar/peer.c
+libpurple/protocols/oscar/userinfo.c
 libpurple/protocols/oscar/util.c
-libpurple/protocols/oscar/userinfo.c
 libpurple/protocols/oscar/visibility.c
 libpurple/protocols/qq/buddy_info.c
 libpurple/protocols/qq/buddy_list.c
--- a/po/ar.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/ar.po	Wed Feb 02 23:26:42 2011 +0000
@@ -747,9 +747,9 @@
 #, c-format
 msgid "File Transfers - %d%% of %d file"
 msgid_plural "File Transfers - %d%% of %d files"
-msgstr[0] "نقل الملفات - %d%% من %0.sصفر ملفات"
-msgstr[1] "نقل الملفات - %d%% من %0.sملف واحد"
-msgstr[2] "نقل الملفات - %d%% من %0.sملفين"
+msgstr[0] "نقل الملفات - %d%% من صفر ملفات"
+msgstr[1] "نقل الملفات - %d%% من ملف واحد"
+msgstr[2] "نقل الملفات - %d%% من ملفين"
 msgstr[3] "نقل الملفات - %d%% من %d ملفات"
 msgstr[4] "نقل الملفات - %d%% من %d ملفا"
 msgstr[5] "نقل الملفات - %d%% من %d ملف"
@@ -921,9 +921,9 @@
 #, c-format
 msgid "%s (%s) has %d new message."
 msgid_plural "%s (%s) has %d new messages."
-msgstr[0] "لا رسائل%0.s جديدة لـ ‏%s (%s)."
-msgstr[1] "‏%s (%s) لديه %0.sرسالة واحدة جديدة"
-msgstr[2] "‏%s (%s) لديه %0.sرسالتان جديدتان."
+msgstr[0] "لا رسائل جديدة لـ ‏%s ‏(%s)."
+msgstr[1] "‏%s (%s) لديه رسالة واحدة جديدة"
+msgstr[2] "‏%s (%s) لديه رسالتان جديدتان."
 msgstr[3] "‏%s (%s) لديه %d رسائل جديدة."
 msgstr[4] "‏%s (%s) لديه %d رسالة جديدة."
 msgstr[5] "‏%s (%s) لديه %d رسالة جديدة."
@@ -11231,9 +11231,9 @@
 #, c-format
 msgid "%s, %d hour"
 msgid_plural "%s, %d hours"
-msgstr[0] "%s، %0.sلا ساعات"
-msgstr[1] "‏%s، %0.sساعة واحدة"
-msgstr[2] "‏%s، %0.sساعتين"
+msgstr[0] "%s، لا ساعات"
+msgstr[1] "‏%s، ساعة واحدة"
+msgstr[2] "‏%s، ساعتين"
 msgstr[3] "‏%s، %d ساعات"
 msgstr[4] "‏%s، %d ساعة"
 msgstr[5] "‏%s، %d ساعة"
@@ -11251,9 +11251,9 @@
 #, c-format
 msgid "%s, %d minute"
 msgid_plural "%s, %d minutes"
-msgstr[0] "‏%s، %0.sلا دقائق"
-msgstr[1] "‏%s، %0.sدقيقة واحدة"
-msgstr[2] "‏%s، %0.sدقيقتين"
+msgstr[0] "‏%s، لا دقائق"
+msgstr[1] "‏%s، دقيقة واحدة"
+msgstr[2] "‏%s، دقيقتين"
 msgstr[3] "%s، %d دقائق"
 msgstr[4] "%s، %d دقيقة"
 msgstr[5] "%s، %d دقيقة"
@@ -11604,13 +11604,12 @@
 msgid "The text information for a buddy's status"
 msgstr "غيّر معلومات المستخدم لأجل %s"
 
-#, c-format
 msgid "You have %d contact named %s. Would you like to merge them?"
 msgid_plural ""
 "You currently have %d contacts named %s. Would you like to merge them?"
-msgstr[0] "لا مراسلين%0.s لديك باسم %s. أتريد دمجهم؟"
-msgstr[1] "لديك مراسل واحد%0.s باسم %s. أتريد دمجه؟"
-msgstr[2] "لديك مراسليْن%0.s باسم %s. أتريد دمجهما؟"
+msgstr[0] "%0.sلا مراسلين لديك باسم %s. أتريد دمجهم؟"
+msgstr[1] "%0.sلديك مراسل واحد باسم %s. أتريد دمجه؟"
+msgstr[2] "%0.sلديك مراسليْن باسم %s. أتريد دمجهما؟"
 msgstr[3] "لديك %d مراسلين باسم %s. أتريد دمجهم؟"
 msgstr[4] "لديك %d مراسلا باسم %s. أتريد دمجهم؟"
 msgstr[5] "لديك %d مراسل باسم %s. أتريد دمجهم؟"
@@ -11948,12 +11947,11 @@
 msgid "/Tools/Room List"
 msgstr "/الأدوات/قائمة الغرف"
 
-#, c-format
 msgid "%d unread message from %s\n"
 msgid_plural "%d unread messages from %s\n"
-msgstr[0] "لا رسائل%0.s غير مقروءة من %s\n"
-msgstr[1] "رسالة واحدة%0.s غير مقروءة من %s\n"
-msgstr[2] "رسالتان%0.s غير مقروءتان من %s\n"
+msgstr[0] "%0.sلا رسائل غير مقروءة من %s\n"
+msgstr[1] "%0.sرسالة واحدة غير مقروءة من %s\n"
+msgstr[2] "%0.sرسالتان غير مقروءتان من %s\n"
 msgstr[3] "%d رسائل غير مقروءة من %s\n"
 msgstr[4] "%d رسالة غير مقروءة من %s\n"
 msgstr[5] "%d رسالة غير مقروءة من %s\n"
@@ -12932,13 +12930,13 @@
 "You are about to remove the contact containing %s and %d other buddies from "
 "your buddy list.  Do you want to continue?"
 msgstr[0] ""
-"أنت بصدد إزالة مراسل يحتوي %s و %0.sلا أصدقاء من قائمة أصدقائك.  هل تريد "
+"أنت بصدد إزالة مراسل يحتوي %s ولا أصدقاء من قائمة أصدقائك.  هل تريد "
 "الاستمرار؟"
 msgstr[1] ""
-"أنت بصدد إزالة مراسل يحتوي %s و %0.sصديق آخر من قائمة أصدقائك.  هل تريد "
+"أنت بصدد إزالة مراسل يحتوي %s وصديق آخر من قائمة أصدقائك.  هل تريد "
 "الاستمرار؟"
 msgstr[2] ""
-"أنت بصدد إزالة مراسل يحتوي %s و %0.sصديقين آخرين من قائمة أصدقائك.  هل تريد "
+"أنت بصدد إزالة مراسل يحتوي %s وصديقين آخرين من قائمة أصدقائك.  هل تريد "
 "الاستمرار؟"
 msgstr[3] ""
 "أنت بصدد إزالة مراسل يحتوي %s و %d أصدقاء آخرين من قائمة أصدقائك.  هل تريد "
@@ -13504,12 +13502,12 @@
 #, c-format
 msgid "%s has %d new message."
 msgid_plural "%s has %d new messages."
-msgstr[0] "لا رسائل%0.s جديدة ل %s."
-msgstr[1] "رسالة%0.s جديدة ل %s."
-msgstr[2] "رسالتان%0.s جديدتان ل %s."
-msgstr[3] "%Id رسائل جديدة ل %s."
-msgstr[4] "%Id رسالة جديدة ل %s."
-msgstr[5] "%Id رسالة جديدة ل %s."
+msgstr[0] "لا رسائل جديدة ل‍ %s."
+msgstr[1] "رسالة جديدة ل‍ %s."
+msgstr[2] "رسالتان جديدتان ل‍ %s."
+msgstr[3] "%2$d رسائل جديدة ل‍ %1$s."
+msgstr[4] "%2$d رسالة جديدة ل‍ %1$s."
+msgstr[5] "%2$d رسالة جديدة ل‍ %1$s."
 
 #, c-format
 msgid "<b>%d new email.</b>"
--- a/po/az.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/az.po	Wed Feb 02 23:26:42 2011 +0000
@@ -15,7 +15,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Generator: KBabel 1.3\n"
 
 #. Translators may want to transliterate the name.
--- a/po/ca.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/ca.po	Wed Feb 02 23:26:42 2011 +0000
@@ -3,7 +3,7 @@
 # Copyright (C) unknown, Robert Millan <zeratul2@wanadoo.es>
 # Copyright (C) December 2003 (from 2003-12-12 until 2003-12-18),
 #               January (2004-01-07,12), Xan <dxpublica@telefonica.net>
-# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
 #               Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>
 #
 # This file is distributed under the same license as the Pidgin package.
@@ -33,8 +33,8 @@
 msgstr ""
 "Project-Id-Version: Pidgin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-12-23 07:57+0100\n"
-"PO-Revision-Date: 2010-12-23 08:04+0100\n"
+"POT-Creation-Date: 2011-01-30 11:04+0100\n"
+"PO-Revision-Date: 2011-01-30 11:11+0100\n"
 "Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
 "Language-Team: Catalan <tradgnome@softcatala.net>\n"
 "Language: ca\n"
@@ -2387,9 +2387,12 @@
 "Camí on desar els fitxers\n"
 "(introduïu tot el camí)"
 
-msgid "Automatically reject from users not in buddy list"
-msgstr ""
-"Rebutja automàticament dels usuaris que no estiguin a la llista d'amics"
+msgid ""
+"When a file-transfer request arrives from a user who is\n"
+"*not* on your buddy list:"
+msgstr ""
+"Quan arribi una sol·licitud de transferència d'un fitxer d'un\n"
+"usuari que *no* és a la vostra llista d'amics:"
 
 msgid ""
 "Notify with a popup when an autoaccepted file transfer is complete\n"
@@ -2402,6 +2405,10 @@
 msgid "Create a new directory for each user"
 msgstr "Crea un directori nou per a cada usuari"
 
+#, fuzzy
+msgid "Escape the filenames"
+msgstr "%s ha cancel·lat la transferència del fitxer"
+
 msgid "Notes"
 msgstr "Notes"
 
@@ -3859,7 +3866,10 @@
 msgid "Server requires plaintext authentication over an unencrypted stream"
 msgstr "El servidor requereix autenticació de text sobre un flux no xifrat"
 
-#. This should never happen!
+#. This happens when the server sends back jibberish
+#. * in the "additional data with success" case.
+#. * Seen with Wildfire 3.0.1.
+#.
 msgid "Invalid response from server"
 msgstr "La resposta del servidor no és vàlida"
 
@@ -6201,6 +6211,20 @@
 msgid "Retrieving User Information..."
 msgstr "S'està obtenint informació de l'usuari..."
 
+#. you were kicked
+msgid "You have been kicked from this MultiMX."
+msgstr "Us han fet fora d'aquest MultiMX."
+
+msgid "was kicked"
+msgstr "ha estat fet fora"
+
+msgid "_Room Name:"
+msgstr "Nom de la _Sala:"
+
+#. Display system message in chat window
+msgid "You have invited"
+msgstr "Heu convidat"
+
 msgid "Loading menu..."
 msgstr "S'està carregant el menú..."
 
@@ -6229,20 +6253,6 @@
 msgid "Enable splash-screen popup"
 msgstr "Habilita la pantalla de presentació emergent"
 
-#. you were kicked
-msgid "You have been kicked from this MultiMX."
-msgstr "Us han fet fora d'aquest MultiMX."
-
-msgid "was kicked"
-msgstr "ha estat fet fora"
-
-msgid "_Room Name:"
-msgstr "Nom de la _Sala:"
-
-#. Display system message in chat window
-msgid "You have invited"
-msgstr "Heu convidat"
-
 msgid "Last Online"
 msgstr "Darrer cop en línia"
 
@@ -7917,75 +7927,6 @@
 "necessari per poder enviar imatges instantànies. Atès que es revelarà la "
 "vostra adreça IP, això es pot considerar un risc de privadesa."
 
-msgid "Invalid SNAC"
-msgstr "SNAC invàlid"
-
-msgid "Server rate limit exceeded"
-msgstr "S'ha excedit el límit de velocitat del servidor"
-
-msgid "Client rate limit exceeded"
-msgstr "S'ha excedit el límit de velocitat del client"
-
-msgid "Service unavailable"
-msgstr "Servei no disponible"
-
-msgid "Service not defined"
-msgstr "Servei no definit"
-
-msgid "Obsolete SNAC"
-msgstr "SNAC obsolet"
-
-msgid "Not supported by host"
-msgstr "El servidor no ho permet"
-
-msgid "Not supported by client"
-msgstr "El client no ho permet"
-
-msgid "Refused by client"
-msgstr "Rebutjat pel client"
-
-msgid "Reply too big"
-msgstr "Resposta massa gran"
-
-msgid "Responses lost"
-msgstr "S'han perdut respostes"
-
-msgid "Request denied"
-msgstr "Petició denegada"
-
-msgid "Busted SNAC payload"
-msgstr "Càrrega SNAC malmesa"
-
-msgid "Insufficient rights"
-msgstr "Drets insuficients"
-
-msgid "In local permit/deny"
-msgstr "En la llista de permès/denegat local"
-
-msgid "Warning level too high (sender)"
-msgstr "Nivell d'avís massa alt (remitent)"
-
-msgid "Warning level too high (receiver)"
-msgstr "Nivell d'avís massa alt (receptor)"
-
-msgid "User temporarily unavailable"
-msgstr "Usuari no disponible temporalment"
-
-msgid "No match"
-msgstr "Cap coincidència"
-
-msgid "List overflow"
-msgstr "Sobreeiximent de la llista"
-
-msgid "Request ambiguous"
-msgstr "Petició ambigua"
-
-msgid "Queue full"
-msgstr "Cua plena"
-
-msgid "Not while on AOL"
-msgstr "No es pot fer mentre estigui a AOL"
-
 #. Label
 msgid "Buddy Icon"
 msgstr "Icona de l'amic"
@@ -8104,6 +8045,75 @@
 msgid "Capabilities"
 msgstr "Capacitats"
 
+msgid "Invalid SNAC"
+msgstr "SNAC invàlid"
+
+msgid "Server rate limit exceeded"
+msgstr "S'ha excedit el límit de velocitat del servidor"
+
+msgid "Client rate limit exceeded"
+msgstr "S'ha excedit el límit de velocitat del client"
+
+msgid "Service unavailable"
+msgstr "Servei no disponible"
+
+msgid "Service not defined"
+msgstr "Servei no definit"
+
+msgid "Obsolete SNAC"
+msgstr "SNAC obsolet"
+
+msgid "Not supported by host"
+msgstr "El servidor no ho permet"
+
+msgid "Not supported by client"
+msgstr "El client no ho permet"
+
+msgid "Refused by client"
+msgstr "Rebutjat pel client"
+
+msgid "Reply too big"
+msgstr "Resposta massa gran"
+
+msgid "Responses lost"
+msgstr "S'han perdut respostes"
+
+msgid "Request denied"
+msgstr "Petició denegada"
+
+msgid "Busted SNAC payload"
+msgstr "Càrrega SNAC malmesa"
+
+msgid "Insufficient rights"
+msgstr "Drets insuficients"
+
+msgid "In local permit/deny"
+msgstr "En la llista de permès/denegat local"
+
+msgid "Warning level too high (sender)"
+msgstr "Nivell d'avís massa alt (remitent)"
+
+msgid "Warning level too high (receiver)"
+msgstr "Nivell d'avís massa alt (receptor)"
+
+msgid "User temporarily unavailable"
+msgstr "Usuari no disponible temporalment"
+
+msgid "No match"
+msgstr "Cap coincidència"
+
+msgid "List overflow"
+msgstr "Sobreeiximent de la llista"
+
+msgid "Request ambiguous"
+msgstr "Petició ambigua"
+
+msgid "Queue full"
+msgstr "Cua plena"
+
+msgid "Not while on AOL"
+msgstr "No es pot fer mentre estigui a AOL"
+
 #. Translators: This string is a menu option that, if selected, will cause
 #. you to appear online to the chosen user even when your status is set to
 #. Invisible.
@@ -8703,14 +8713,14 @@
 msgid "Select Server"
 msgstr "Seleccioneu un servidor"
 
-msgid "QQ2005"
-msgstr "QQ2005"
+msgid "QQ2008"
+msgstr "QQ2008"
 
 msgid "QQ2007"
 msgstr "QQ2007"
 
-msgid "QQ2008"
-msgstr "QQ2008"
+msgid "QQ2005"
+msgstr "QQ2005"
 
 msgid "Connect by TCP"
 msgstr "Connecta amb TCP"
@@ -12284,10 +12294,6 @@
 msgid "Fatal Error"
 msgstr "Error fatal"
 
-# Fixme
-msgid "bug master"
-msgstr "bug master"
-
 msgid "artist"
 msgstr "artista"
 
@@ -12469,6 +12475,9 @@
 msgid "Maithili"
 msgstr "Maithili"
 
+msgid "Meadow Mari"
+msgstr "Txeremís oriental"
+
 msgid "Macedonian"
 msgstr "Macedoni"
 
@@ -15626,6 +15635,14 @@
 msgid "You do not have permission to uninstall this application."
 msgstr "No tens permís per desinstal.lar aquesta aplicació."
 
+#~ msgid "Automatically reject from users not in buddy list"
+#~ msgstr ""
+#~ "Rebutja automàticament dels usuaris que no estiguin a la llista d'amics"
+
+# Fixme
+#~ msgid "bug master"
+#~ msgstr "bug master"
+
 #~ msgid "Error requesting %s"
 #~ msgstr "S'ha produït un error en sol·licitar %s"
 
--- a/po/de.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/de.po	Wed Feb 02 23:26:42 2011 +0000
@@ -2,7 +2,7 @@
 # Pidgin German translation
 # Copyright (C) 2001, Daniel Seifert <Pidgin-translation@dseifert.de>
 # Copyright (C) 2002, Karsten Weiss <knweiss@gmx.de>
-# Copyright (C) 2002-2010, Björn Voigt <bjoern@cs.tu-berlin.de>,
+# Copyright (C) 2002-2011, Björn Voigt <bjoern@cs.tu-berlin.de>,
 #                     Jochen Kemnade <jochenkemnade@web.de>
 #
 # This file is distributed under the same license as the Pidgin package.
@@ -11,9 +11,9 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-12-22 10:12+0100\n"
-"PO-Revision-Date: 2010-12-22 10:21+0100\n"
-"Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
+"POT-Creation-Date: 2011-01-25 20:46+0100\n"
+"PO-Revision-Date: 2011-01-25 20:46+0100\n"
+"Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n"
 "Language-Team: German <de@li.org>\n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
@@ -401,7 +401,7 @@
 msgstr "Chat betreten"
 
 msgid "Please enter the name of the chat you want to join."
-msgstr "Bitte geben Sie die den Namen des Chats an, den Sie betreten möchten."
+msgstr "Bitte geben Sie den Namen des Chats an, den Sie betreten möchten."
 
 msgid "Join"
 msgstr "Betreten"
@@ -568,7 +568,7 @@
 msgstr "Konten reaktivieren"
 
 msgid "No such command."
-msgstr "Es gibt kein solches Kommando."
+msgstr "Unbekanntes Kommando."
 
 msgid "Syntax Error:  You typed the wrong number of arguments to that command."
 msgstr ""
@@ -581,7 +581,8 @@
 msgstr "Dieses Kommando funktioniert nur in Chats, nicht bei IMs."
 
 msgid "That command only works in IMs, not chats."
-msgstr "Dieses Kommando funktioniert nur bei IMs, nicht bei Chats."
+msgstr ""
+"Dieses Kommando funktioniert nur bei Sofortnachrichten, nicht bei Chats."
 
 msgid "That command doesn't work on this protocol."
 msgstr "Dieses Kommando funktioniert nicht in diesem Protokoll."
@@ -646,7 +647,7 @@
 msgstr "Einladen..."
 
 msgid "Enable Logging"
-msgstr "Mitschnitt einschalten"
+msgstr "Mitschnitt aktivieren"
 
 msgid "Enable Sounds"
 msgstr "Klänge aktivieren"
@@ -801,7 +802,7 @@
 msgstr "Status"
 
 msgid "Close this window when all transfers finish"
-msgstr "Schließe dieses Fenster, wenn alle Übertragungen abgeschlossen sind"
+msgstr "Fenster schließen, wenn alle Übertragungen abgeschlossen sind"
 
 msgid "Clear finished transfers"
 msgstr "Entferne komplette Übertragungen"
@@ -816,7 +817,7 @@
 msgstr "Abgebrochen"
 
 msgid "Failed"
-msgstr "Gescheitert"
+msgstr "Fehlgeschlagen"
 
 #, c-format
 msgid "%.2f KiB/s"
@@ -884,11 +885,11 @@
 
 #, c-format
 msgid "Conversations in %s"
-msgstr "Unterhaltung in %s"
+msgstr "Unterhaltungen in %s"
 
 #, c-format
 msgid "Conversations with %s"
-msgstr "Unterhaltung mit %s"
+msgstr "Unterhaltungen mit %s"
 
 msgid "All Conversations"
 msgstr "Alle Unterhaltungen"
@@ -910,7 +911,7 @@
 msgstr "Ablehnen"
 
 msgid "Call in progress."
-msgstr "Anruf läuft."
+msgstr "Verbindungsaufbau."
 
 msgid "The call has been terminated."
 msgstr "Der Anruf wurde beendet."
@@ -926,7 +927,7 @@
 "starten."
 
 msgid "You have rejected the call."
-msgstr "Sie haben den Anruf abgelehnt."
+msgstr "Sie haben den Anruf abgewiesen."
 
 msgid "call: Make an audio call."
 msgstr "call: Einen Audio-Anruf tätigen."
@@ -1009,7 +1010,7 @@
 msgstr "Keine Einstellungsoptionen für dieses Plugin."
 
 msgid "Error loading plugin"
-msgstr "Beim Laden des Plugins traten Fehler auf"
+msgstr "Beim Laden des Plugins ist ein Fehler aufgetreten"
 
 msgid "The selected file is not a valid plugin."
 msgstr "Die gewählte Datei ist kein gültiges Plugin."
@@ -1021,7 +1022,7 @@
 "genaue Fehlermeldung zu sehen."
 
 msgid "Select plugin to install"
-msgstr "Wählen Sie ein Plugin zum Installieren"
+msgstr "Zu installierendes Plugin auswählen"
 
 msgid "You can (un)load plugins from the following list."
 msgstr "Die können Plugins von der folgenden Liste laden bzw. entladen."
@@ -1064,10 +1065,10 @@
 msgstr "Alarm, wenn Buddy..."
 
 msgid "Signs on"
-msgstr "sich angemeldet"
+msgstr "sich anmeldet"
 
 msgid "Signs off"
-msgstr "sich abgemeldet"
+msgstr "sich abmeldet"
 
 msgid "Goes away"
 msgstr "hinausgeht"
@@ -1085,7 +1086,7 @@
 msgstr "zu tippen beginnt"
 
 msgid "Pauses while typing"
-msgstr "beim Tippen anhält"
+msgstr "das Tippen unterbricht"
 
 msgid "Stops typing"
 msgstr "aufhört zu tippen"
@@ -1119,13 +1120,13 @@
 msgstr "Wiederkehrend"
 
 msgid "Cannot create pounce"
-msgstr "Kann Alarm nicht erzeugen"
+msgstr "Alarm konnte nicht erstellt werden"
 
 msgid "You do not have any accounts."
 msgstr "Sie haben keine Kontos."
 
 msgid "You must create an account first before you can create a pounce."
-msgstr "Sie müssen ein Konto anlegen, bevor Sie einen Alarm erzeugen können."
+msgstr "Sie müssen ein Konto anlegen, bevor Sie einen Alarm einrichten können."
 
 #, c-format
 msgid "Are you sure you want to delete the pounce on %s for %s?"
@@ -1164,7 +1165,7 @@
 
 #, c-format
 msgid "%s has become idle (%s)"
-msgstr "%s wurde untätig (%s)"
+msgstr "%s ist nun untätig (%s)"
 
 #, c-format
 msgid "%s has gone away. (%s)"
@@ -1178,7 +1179,7 @@
 msgstr "Unbekanntes Alarm-Ereignis. Bitte berichten Sie dieses Problem!"
 
 msgid "Based on keyboard use"
-msgstr "Abhängig von Tastaturbenutzung"
+msgstr "Abhängig von der Tastaturbenutzung"
 
 msgid "From last sent message"
 msgstr "Von letzter gesendeter Nachricht"
@@ -1199,7 +1200,7 @@
 msgstr "Mitschnitt-Format"
 
 msgid "Log IMs"
-msgstr "IMs mitschneiden"
+msgstr "Sofortnachrichten mitschneiden"
 
 msgid "Log chats"
 msgstr "Chats mitschneiden"
@@ -1247,7 +1248,7 @@
 msgstr "Drücken Sie 'Enter', um mehr Räume dieser Kategorie zu finden."
 
 msgid "Get"
-msgstr "Holen"
+msgstr "Abrufen"
 
 #. Create the window.
 msgid "Room List"
@@ -1441,7 +1442,7 @@
 msgstr "Statusmeldungen"
 
 msgid "Error loading the plugin."
-msgstr "Beim Laden des Plugins traten Fehler auf."
+msgstr "Beim Laden des Plugins ist ein Fehler aufgetreten."
 
 msgid "Couldn't find X display"
 msgstr "Konnte X-Display nicht finden"
@@ -1519,7 +1520,7 @@
 msgstr "<b>Unterhaltung mit %s am %s:</b><br>"
 
 msgid "History Plugin Requires Logging"
-msgstr "Das Verlaufs-Plugin erfordert das Mitschneiden"
+msgstr "Für das Verlaufs-Plugin muss das Mitschneiden aktiviert sein"
 
 msgid ""
 "Logging can be enabled from Tools -> Preferences -> Logging.\n"
@@ -1543,7 +1544,7 @@
 "When a new conversation is opened this plugin will insert the last "
 "conversation into the current conversation."
 msgstr ""
-"Wenn eine neue Unterhaltung eröffnet wird, fügt dieses Plugin die letzte "
+"Wenn eine neue Unterhaltung begonnen wird, fügt dieses Plugin die letzte "
 "Unterhaltung in die aktuelle Unterhaltung ein."
 
 #, c-format
@@ -1607,7 +1608,7 @@
 msgstr "Verschachtelte Gruppen (experimentell)"
 
 msgid "Provides alternate buddylist grouping options."
-msgstr "Bietet alternative Einstellungen für die Kontaktlisten-Gruppierung."
+msgstr "Bietet alternative Einstellungen für die Gruppierung der Kontaktliste."
 
 msgid "Lastlog"
 msgstr "Verlauf"
@@ -1900,11 +1901,11 @@
 
 #, c-format
 msgid "Failed to get name: %s"
-msgstr "Kann den Namen nicht bekommen: %s"
+msgstr "Name konnte nicht abgerufen werden: %s"
 
 #, c-format
 msgid "Failed to get serv name: %s"
-msgstr "Kann den Serv-Namen nicht bekommen: %s"
+msgstr "Serv-Name konnte nicht abgerufen werden: %s"
 
 msgid "Purple's D-BUS server is not running for the reason listed below"
 msgstr "Purple's D-Bus-Server läuft aus dem folgenden Grund nicht"
@@ -2041,7 +2042,7 @@
 msgstr "Übertragung der Datei %s ist komplett"
 
 msgid "File transfer complete"
-msgstr "Dateiübertragung ist komplett"
+msgstr "Dateiübertragung abgeschlossen"
 
 #, c-format
 msgid "You cancelled the transfer of %s"
@@ -2368,8 +2369,12 @@
 "Pfad in denen die Dateien gespeichert werden sollen\n"
 "(Bitte geben Sie den vollständigen Pfad an)"
 
-msgid "Automatically reject from users not in buddy list"
-msgstr "Automatisch von Benutzern ablehnen, die nicht in der Buddy-Liste sind"
+msgid ""
+"When a file-transfer request arrives from a user who is\n"
+"*not* on your buddy list:"
+msgstr ""
+"Wenn eine Dateitransferanfrage von einem Benutzer ankommt, \n"
+"der *nicht* in Ihrer Buddy-Liste ist:"
 
 msgid ""
 "Notify with a popup when an autoaccepted file transfer is complete\n"
@@ -2382,6 +2387,9 @@
 msgid "Create a new directory for each user"
 msgstr "Für jeden Benutzer ein neues Verzeichnis anlegen"
 
+msgid "Escape the filenames"
+msgstr "Sonderzeichen in Dateinamen ersetzen"
+
 msgid "Notes"
 msgstr "Notizen"
 
@@ -3850,7 +3858,10 @@
 "Der Server erfordert eine Klartext-Authentifizierung über einen "
 "unverschlüsselten Kanal"
 
-#. This should never happen!
+#. This happens when the server sends back jibberish
+#. * in the "additional data with success" case.
+#. * Seen with Wildfire 3.0.1.
+#.
 msgid "Invalid response from server"
 msgstr "Ungültige Serverantwort"
 
@@ -8730,14 +8741,14 @@
 msgid "Select Server"
 msgstr "Server wählen"
 
-msgid "QQ2005"
-msgstr "QQ2005"
+msgid "QQ2008"
+msgstr "QQ2008"
 
 msgid "QQ2007"
 msgstr "QQ2007"
 
-msgid "QQ2008"
-msgstr "QQ2008"
+msgid "QQ2005"
+msgstr "QQ2005"
 
 msgid "Connect by TCP"
 msgstr "Über TCP verbinden"
@@ -12328,9 +12339,6 @@
 msgid "Fatal Error"
 msgstr "Schwerer Fehler"
 
-msgid "bug master"
-msgstr "Bug-Master"
-
 msgid "artist"
 msgstr "Künstler"
 
@@ -12510,6 +12518,9 @@
 msgid "Maithili"
 msgstr "Maithili"
 
+msgid "Meadow Mari"
+msgstr "Wiesen-Mari"
+
 msgid "Macedonian"
 msgstr "Makedonisch"
 
@@ -13448,10 +13459,10 @@
 msgstr "Budd_y-Name:"
 
 msgid "Si_gns on"
-msgstr "si_ch angemeldet"
+msgstr "si_ch anmeldet"
 
 msgid "Signs o_ff"
-msgstr "sich abgemel_det"
+msgstr "sich abmel_det"
 
 msgid "Goes a_way"
 msgstr "hinausgeh_t"
@@ -15662,15 +15673,3 @@
 
 msgid "You do not have permission to uninstall this application."
 msgstr "Sie haben keine Berechtigung, diese Anwendung zu deinstallieren."
-
-#~ msgid "Error requesting %s"
-#~ msgstr "Fehler beim Anfordern von %s"
-
-#~ msgid "An error occurred on the in-band bytestream transfer\n"
-#~ msgstr "Bei der In-Band-Bytestrom-Übertragung trat ein Fehler auf\n"
-
-#~ msgid "Transfer was closed."
-#~ msgstr "Übertragung wurde geschlossen."
-
-#~ msgid "Failed to open in-band bytestream"
-#~ msgstr "Öffnen des In-Band-Bytestroms fehlgeschlagen"
--- a/po/el.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/el.po	Wed Feb 02 23:26:42 2011 +0000
@@ -18,7 +18,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: Plural-Forms:  nplurals=2; plural=(n != 1)\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
 "X-Generator: Lokalize 0.3\n"
 
 #. Translators may want to transliterate the name.
--- a/po/en_AU.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/en_AU.po	Wed Feb 02 23:26:42 2011 +0000
@@ -16,7 +16,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=n>1;\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #. Translators may want to transliterate the name.
 #. It is not to be translated.
--- a/po/en_GB.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/en_GB.po	Wed Feb 02 23:26:42 2011 +0000
@@ -15,7 +15,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=n>1;\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #. Translators may want to transliterate the name.
 #. It is not to be translated.
--- a/po/eu.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/eu.po	Wed Feb 02 23:26:42 2011 +0000
@@ -16,7 +16,7 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.9.1\n"
-"Plural-Forms: Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #. Translators may want to transliterate the name.
 #. It is not to be translated.
--- a/po/fr.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/fr.po	Wed Feb 02 23:26:42 2011 +0000
@@ -4,7 +4,7 @@
 # Copyright (C) 2002, Stéphane Pontier <stephane.pontier@free.fr>
 # Copyright (C) 2002, Stéphane Wirtel <stephane.wirtel@belgacom.net>
 # Copyright (C) 2002, Loïc Jeannin <loic.jeannin@free.fr>
-# Copyright (C) 2002-2010, Éric Boumaour <zongo_fr@users.sourceforge.net>
+# Copyright (C) 2002-2011, Éric Boumaour <zongo_fr@users.sourceforge.net>
 #
 # This file is distributed under the same license as the Pidgin package.
 #
@@ -21,14 +21,14 @@
 msgstr ""
 "Project-Id-Version: Pidgin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-12-19 13:33-0500\n"
-"PO-Revision-Date: 2010-12-16 23:25+0100\n"
+"POT-Creation-Date: 2011-01-30 21:28+0100\n"
+"PO-Revision-Date: 2011-01-30 21:14+0100\n"
 "Last-Translator: Éric Boumaour <zongo_fr@users.sourceforge.net>\n"
 "Language-Team: fr <fr@li.org>\n"
-"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: \n"
 "Plural-Forms: nplurals=2; plural=n>1;\n"
 
 #. Translators may want to transliterate the name.
@@ -864,8 +864,8 @@
 "System events will only be logged if the \"Log all status changes to system "
 "log\" preference is enabled."
 msgstr ""
-"Les événements système ne seront archivés que si l'option « Archiver tous "
-"les changements d'état dans les archives système » est activée."
+"Les événements système ne seront archivés que si l'option « Archiver tous les "
+"changements d'état dans les archives système » est activée."
 
 msgid ""
 "Instant messages will only be logged if the \"Log all instant messages\" "
@@ -2372,9 +2372,12 @@
 "Dossier où placer les fichiers\n"
 "(Veuillez fournir le chemin complet)"
 
-msgid "Automatically reject from users not in buddy list"
-msgstr ""
-"Refuser automatiquement si l'utilisateur n'est pas dans ma liste de contacts"
+msgid ""
+"When a file-transfer request arrives from a user who is\n"
+"*not* on your buddy list:"
+msgstr ""
+"Quand une demande de transfert arrive de quelqu'un qui\n"
+"n'est *pas* dans la liste de contacts :"
 
 msgid ""
 "Notify with a popup when an autoaccepted file transfer is complete\n"
@@ -2387,6 +2390,9 @@
 msgid "Create a new directory for each user"
 msgstr "Créer un nouveau dossier pour chaque contact"
 
+msgid "Escape the filenames"
+msgstr "Encoder les noms des fichiers"
+
 msgid "Notes"
 msgstr "Notes"
 
@@ -2767,8 +2773,7 @@
 msgstr "Message déconnecté"
 
 msgid "You can edit/delete the pounce from the `Buddy Pounces' dialog"
-msgstr ""
-"Vous pouvez modifier ou supprimer l'alerte dans la fenêtre « Alertes »."
+msgstr "Vous pouvez modifier ou supprimer l'alerte dans la fenêtre « Alertes »."
 
 msgid "Yes"
 msgstr "Oui"
@@ -3859,7 +3864,10 @@
 "Le serveur demande une authentification en texte non chiffré au travers d'un "
 "flux crypté."
 
-#. This should never happen!
+#. This happens when the server sends back jibberish
+#. * in the "additional data with success" case.
+#. * Seen with Wildfire 3.0.1.
+#.
 msgid "Invalid response from server"
 msgstr "Réponse non valide du serveur"
 
@@ -6197,6 +6205,20 @@
 msgid "Retrieving User Information..."
 msgstr "Récupération des informations de l'utilisateur..."
 
+#. you were kicked
+msgid "You have been kicked from this MultiMX."
+msgstr "Vous avez été expulsé de ce MultiMX."
+
+msgid "was kicked"
+msgstr "a été expulsé"
+
+msgid "_Room Name:"
+msgstr "_Salon :"
+
+#. Display system message in chat window
+msgid "You have invited"
+msgstr "Vous avez été invité"
+
 msgid "Loading menu..."
 msgstr "Chargement du menu..."
 
@@ -6224,20 +6246,6 @@
 msgid "Enable splash-screen popup"
 msgstr "Activer l'affichage de la bannière"
 
-#. you were kicked
-msgid "You have been kicked from this MultiMX."
-msgstr "Vous avez été expulsé de ce MultiMX."
-
-msgid "was kicked"
-msgstr "a été expulsé"
-
-msgid "_Room Name:"
-msgstr "_Salon :"
-
-#. Display system message in chat window
-msgid "You have invited"
-msgstr "Vous avez été invité"
-
 msgid "Last Online"
 msgstr "En ligne dernièrement"
 
@@ -7908,75 +7916,6 @@
 "d'images. Votre adresse IP sera révélée et ceci peut être considéré comme "
 "une faille de sécurité."
 
-msgid "Invalid SNAC"
-msgstr "SNAC non valide"
-
-msgid "Server rate limit exceeded"
-msgstr "Vitesse du serveur dépassée"
-
-msgid "Client rate limit exceeded"
-msgstr "Vitesse du client dépassée"
-
-msgid "Service unavailable"
-msgstr "Service non disponible"
-
-msgid "Service not defined"
-msgstr "Service non défini"
-
-msgid "Obsolete SNAC"
-msgstr "SNAC obsolète"
-
-msgid "Not supported by host"
-msgstr "Non supporté par l'hôte"
-
-msgid "Not supported by client"
-msgstr "Non supporté par le client"
-
-msgid "Refused by client"
-msgstr "Refusé par le client"
-
-msgid "Reply too big"
-msgstr "Réponse trop grosse"
-
-msgid "Responses lost"
-msgstr "Réponses perdues"
-
-msgid "Request denied"
-msgstr "Requête refusée"
-
-msgid "Busted SNAC payload"
-msgstr "Charge SNAC incorrecte"
-
-msgid "Insufficient rights"
-msgstr "Droits insuffisants"
-
-msgid "In local permit/deny"
-msgstr "Dans l'autorisation/interdiction locale"
-
-msgid "Warning level too high (sender)"
-msgstr "Niveau d'avertissement trop élevé (émission)"
-
-msgid "Warning level too high (receiver)"
-msgstr "Niveau d'avertissement trop élevé (réception)"
-
-msgid "User temporarily unavailable"
-msgstr "L'utilisateur est temporairement indisponible."
-
-msgid "No match"
-msgstr "Aucun résultat"
-
-msgid "List overflow"
-msgstr "Dépassement de liste"
-
-msgid "Request ambiguous"
-msgstr "Requête ambiguë"
-
-msgid "Queue full"
-msgstr "File d'attente pleine"
-
-msgid "Not while on AOL"
-msgstr "Impossible sur AOL"
-
 #. Label
 msgid "Buddy Icon"
 msgstr "Icône du contact"
@@ -8095,6 +8034,75 @@
 msgid "Capabilities"
 msgstr "Possibilités"
 
+msgid "Invalid SNAC"
+msgstr "SNAC non valide"
+
+msgid "Server rate limit exceeded"
+msgstr "Vitesse du serveur dépassée"
+
+msgid "Client rate limit exceeded"
+msgstr "Vitesse du client dépassée"
+
+msgid "Service unavailable"
+msgstr "Service non disponible"
+
+msgid "Service not defined"
+msgstr "Service non défini"
+
+msgid "Obsolete SNAC"
+msgstr "SNAC obsolète"
+
+msgid "Not supported by host"
+msgstr "Non supporté par l'hôte"
+
+msgid "Not supported by client"
+msgstr "Non supporté par le client"
+
+msgid "Refused by client"
+msgstr "Refusé par le client"
+
+msgid "Reply too big"
+msgstr "Réponse trop grosse"
+
+msgid "Responses lost"
+msgstr "Réponses perdues"
+
+msgid "Request denied"
+msgstr "Requête refusée"
+
+msgid "Busted SNAC payload"
+msgstr "Charge SNAC incorrecte"
+
+msgid "Insufficient rights"
+msgstr "Droits insuffisants"
+
+msgid "In local permit/deny"
+msgstr "Dans l'autorisation/interdiction locale"
+
+msgid "Warning level too high (sender)"
+msgstr "Niveau d'avertissement trop élevé (émission)"
+
+msgid "Warning level too high (receiver)"
+msgstr "Niveau d'avertissement trop élevé (réception)"
+
+msgid "User temporarily unavailable"
+msgstr "L'utilisateur est temporairement indisponible."
+
+msgid "No match"
+msgstr "Aucun résultat"
+
+msgid "List overflow"
+msgstr "Dépassement de liste"
+
+msgid "Request ambiguous"
+msgstr "Requête ambiguë"
+
+msgid "Queue full"
+msgstr "File d'attente pleine"
+
+msgid "Not while on AOL"
+msgstr "Impossible sur AOL"
+
 #. Translators: This string is a menu option that, if selected, will cause
 #. you to appear online to the chosen user even when your status is set to
 #. Invisible.
@@ -8686,14 +8694,14 @@
 msgid "Select Server"
 msgstr "Choisir le serveur"
 
-msgid "QQ2005"
-msgstr "QQ2005"
+msgid "QQ2008"
+msgstr "QQ2008"
 
 msgid "QQ2007"
 msgstr "QQ2007"
 
-msgid "QQ2008"
-msgstr "QQ2008"
+msgid "QQ2005"
+msgstr "QQ2005"
 
 msgid "Connect by TCP"
 msgstr "Connexion par TCP"
@@ -10445,8 +10453,8 @@
 msgstr ""
 "Le serveur Yahoo! a demandé une méthode d'authentification non reconnue. "
 "Cette version de l'application n'arrivera probablement pas à se connecter au "
-"service Yahoo!. Vous pouvez vérifier qu'une mise à jour est disponible sur "
-"%s."
+"service Yahoo!. Vous pouvez vérifier qu'une mise à jour est disponible sur %"
+"s."
 
 msgid "Failed Yahoo! Authentication"
 msgstr "Échec de l'authentification Yahoo!"
@@ -12257,9 +12265,6 @@
 msgid "Fatal Error"
 msgstr "Erreur critique"
 
-msgid "bug master"
-msgstr "maitre des bogues"
-
 msgid "artist"
 msgstr "artiste"
 
@@ -12439,6 +12444,9 @@
 msgid "Maithili"
 msgstr "Maïhili"
 
+msgid "Meadow Mari"
+msgstr "Mari des prairies"
+
 msgid "Macedonian"
 msgstr "Macédonien"
 
@@ -12559,8 +12567,8 @@
 "to multiple messaging services at once.  %s is written in C using GTK+.  %s "
 "is released, and may be modified and redistributed,  under the terms of the "
 "GPL version 2 (or later).  A copy of the GPL is distributed with %s.  %s is "
-"copyrighted by its contributors, a list of whom is also distributed with "
-"%s.  There is no warranty for %s.<BR><BR>"
+"copyrighted by its contributors, a list of whom is also distributed with %"
+"s.  There is no warranty for %s.<BR><BR>"
 msgstr ""
 "%s est un client de messagerie basé sur libpurple capable de se connecter à "
 "de multiples services de messageries instantanées. %s est écrit en C et "
@@ -13115,16 +13123,16 @@
 
 #, c-format
 msgid ""
-"Are you sure you want to permanently delete the log of the conversation in "
-"%s which started at %s?"
+"Are you sure you want to permanently delete the log of the conversation in %"
+"s which started at %s?"
 msgstr ""
 "Êtes-vous sûr de vouloir supprimer les archives de la conversation dans %s "
 "datée du %s ?"
 
 #, c-format
 msgid ""
-"Are you sure you want to permanently delete the system log which started at "
-"%s?"
+"Are you sure you want to permanently delete the system log which started at %"
+"s?"
 msgstr "Êtes-vous sûr de vouloir supprimer les archives système datées du %s ?"
 
 msgid "Delete Log?"
@@ -14956,8 +14964,8 @@
 "'Enter' in the entry box to send. Watch the debug window."
 msgstr ""
 "Permet d'envoyer des données brutes aux protocoles en mode texte (XMPP, MSN, "
-"IRC, TOC). Tapez « Entrée » dans la boîte de saisie pour envoyer. Observez "
-"le résultat dans la fenêtre de debug."
+"IRC, TOC). Tapez « Entrée » dans la boîte de saisie pour envoyer. Observez le "
+"résultat dans la fenêtre de debug."
 
 #, c-format
 msgid "You can upgrade to %s %s today."
@@ -15485,13 +15493,13 @@
 #, no-c-format
 msgid ""
 "Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual "
-"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"installation instructions are at: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
 msgstr ""
 "Erreur lors de l'installation du correcteur orthographique ($R3).$\\rSi une "
 "nouvelle tentative échoue, veuillez suivre les instructions sur http://"
-"developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
 
 #. Installer Subsection Text
 msgid "GTK+ Runtime (required if not present)"
@@ -15570,6 +15578,14 @@
 msgid "You do not have permission to uninstall this application."
 msgstr "Vous n'avez pas les permissions pour supprimer cette application."
 
+#~ msgid "Automatically reject from users not in buddy list"
+#~ msgstr ""
+#~ "Refuser automatiquement si l'utilisateur n'est pas dans ma liste de "
+#~ "contacts"
+
+#~ msgid "bug master"
+#~ msgstr "maitre des bogues"
+
 #~ msgid "An error occurred on the in-band bytestream transfer\n"
 #~ msgstr "Erreur lors du transfert dans le flux de données in-band.\n"
 
--- a/po/gl.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/gl.po	Wed Feb 02 23:26:42 2011 +0000
@@ -18,7 +18,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Generator: KBabel 1.11.4\n"
 
 #. Translators may want to transliterate the name.
--- a/po/hu.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/hu.po	Wed Feb 02 23:26:42 2011 +0000
@@ -1,22 +1,22 @@
 # Hungarian translation of pidgin.
-# Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 # This file is distributed under the same license as the Pidgin package.
 # The Hungarian translation of Pidgin was sponsored by Novell Hungary, many thanks for it!
 #
 # Zoltan Sutto <suttozoltan@chello.hu>, 2003.
-# Gabor Kelemen <kelemeng at gnome dot hu>, 2005, 2006, 2007, 2008, 2009, 2010.
-msgid ""
-msgstr ""
-"Project-Id-Version: pidgin 2.7\n"
+# Gabor Kelemen <kelemeng at gnome dot hu>, 2005, 2006, 2007, 2008, 2009, 2010, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: pidgin 2.7.10\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-12-21 15:20+0100\n"
-"PO-Revision-Date: 2010-12-21 15:19+0100\n"
+"POT-Creation-Date: 2011-01-25 15:12+0100\n"
+"PO-Revision-Date: 2011-01-25 15:12+0100\n"
 "Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n"
 "Language-Team: Hungarian <gnome at fsf dot hu>\n"
-"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: \n"
 "Plural-Forms:  nplurals=2; plural=(n != 1);\n"
 "X-Generator: KBabel 1.11.4\n"
 
@@ -2350,9 +2350,12 @@
 "A fájlok mentési útvonala\n"
 "(Teljes elérési utat adjon meg)"
 
-msgid "Automatically reject from users not in buddy list"
-msgstr ""
-"Automatikus visszautasítás a partnerlistán nem szereplő felhasználóktól"
+msgid ""
+"When a file-transfer request arrives from a user who is\n"
+"*not* on your buddy list:"
+msgstr ""
+"Ha fájlküldési kérés érkezik egy a partnerlistán NEM szereplő\n"
+"felhasználótól:"
 
 msgid ""
 "Notify with a popup when an autoaccepted file transfer is complete\n"
@@ -2365,6 +2368,9 @@
 msgid "Create a new directory for each user"
 msgstr "Új könyvtár létrehozása minden felhasználóhoz"
 
+msgid "Escape the filenames"
+msgstr "Fájlnevek escape-elése."
+
 msgid "Notes"
 msgstr "Megjegyzések"
 
@@ -3828,7 +3834,10 @@
 msgstr ""
 "A kiszolgáló szöveges hitelesítést követel meg egy nem titkosított csatornán"
 
-#. This should never happen!
+#. This happens when the server sends back jibberish
+#. * in the "additional data with success" case.
+#. * Seen with Wildfire 3.0.1.
+#.
 msgid "Invalid response from server"
 msgstr "Érvénytelen válasz a kiszolgálótól"
 
@@ -6757,8 +6766,8 @@
 #, c-format
 msgid "Unable to send message. Could not get details for user (%s)."
 msgstr ""
-"Az üzenetet nem lehet elküldeni. A felhasználó részletei nem kérhetőek le "
-"(%s)."
+"Az üzenetet nem lehet elküldeni. A felhasználó részletei nem kérhetőek le (%"
+"s)."
 
 #, c-format
 msgid "Unable to add %s to your buddy list (%s)."
@@ -7191,8 +7200,8 @@
 "%s tried to send you a %s file, but we only allow files up to %s over Direct "
 "IM.  Try using file transfer instead.\n"
 msgstr ""
-"%s egy %s fájlt próbált küldeni, de közvetlen kapcsolatban legfeljebb csak "
-"%s méretű fájl küldhető. Próbálkozzon inkább a fájlátvitellel.\n"
+"%s egy %s fájlt próbált küldeni, de közvetlen kapcsolatban legfeljebb csak %"
+"s méretű fájl küldhető. Próbálkozzon inkább a fájlátvitellel.\n"
 
 #, c-format
 msgid "File %s is %s, which is larger than the maximum size of %s."
@@ -8628,14 +8637,14 @@
 msgid "Select Server"
 msgstr "Válassza ki a kiszolgálót"
 
-msgid "QQ2005"
-msgstr "QQ2005"
+msgid "QQ2008"
+msgstr "QQ2008"
 
 msgid "QQ2007"
 msgstr "QQ2007"
 
-msgid "QQ2008"
-msgstr "QQ2008"
+msgid "QQ2005"
+msgstr "QQ2005"
 
 msgid "Connect by TCP"
 msgstr "Kapcsolódás TCP segítségével"
@@ -10831,8 +10840,8 @@
 #, c-format
 msgid "Access denied: HTTP proxy server forbids port %d tunneling"
 msgstr ""
-"Hozzáférés megtagadva: a HTTP proxy kiszolgáló tiltja az alagutazást a(z) "
-"%d. porton"
+"Hozzáférés megtagadva: a HTTP proxy kiszolgáló tiltja az alagutazást a(z) %"
+"d. porton"
 
 #, c-format
 msgid "Error resolving %s"
@@ -11080,8 +11089,8 @@
 "An error was encountered reading your %s.  The file has not been loaded, and "
 "the old file has been renamed to %s~."
 msgstr ""
-"Hiba történt a(z) %s olvasásakor. Ez a fájl nem lett betöltve, a régi fájl "
-"%s~ néven lett elmentve."
+"Hiba történt a(z) %s olvasásakor. Ez a fájl nem lett betöltve, a régi fájl %"
+"s~ néven lett elmentve."
 
 msgid ""
 "Chat over IM.  Supports AIM, Google Talk, Jabber/XMPP, MSN, Yahoo and more"
@@ -12207,10 +12216,6 @@
 msgid "Fatal Error"
 msgstr "Végzetes hiba"
 
-# fixme: jobb ötlet?
-msgid "bug master"
-msgstr "hibaritkító"
-
 msgid "artist"
 msgstr "grafikus"
 
@@ -12390,6 +12395,9 @@
 msgid "Maithili"
 msgstr "Maithili"
 
+msgid "Meadow Mari"
+msgstr "Mari"
+
 msgid "Macedonian"
 msgstr "macedón"
 
@@ -12510,8 +12518,8 @@
 "to multiple messaging services at once.  %s is written in C using GTK+.  %s "
 "is released, and may be modified and redistributed,  under the terms of the "
 "GPL version 2 (or later).  A copy of the GPL is distributed with %s.  %s is "
-"copyrighted by its contributors, a list of whom is also distributed with "
-"%s.  There is no warranty for %s.<BR><BR>"
+"copyrighted by its contributors, a list of whom is also distributed with %"
+"s.  There is no warranty for %s.<BR><BR>"
 msgstr ""
 "A %s egy libpurple alapú moduláris üzenetküldő kliens, amely egyszerre több "
 "üzenetküldő szolgáltatáshoz is képes csatlakozni. A %s GTK+ használatával, C "
@@ -13061,16 +13069,16 @@
 
 #, c-format
 msgid ""
-"Are you sure you want to permanently delete the log of the conversation in "
-"%s which started at %s?"
+"Are you sure you want to permanently delete the log of the conversation in %"
+"s which started at %s?"
 msgstr ""
 "Biztos, hogy törölni akarja a(z) %s csatornán folytatott, %s időpontban "
 "kezdődött beszélgetés naplóját?"
 
 #, c-format
 msgid ""
-"Are you sure you want to permanently delete the system log which started at "
-"%s?"
+"Are you sure you want to permanently delete the system log which started at %"
+"s?"
 msgstr ""
 "Biztos, hogy törölni akarja a(z) %s időpontban kezdődött rendszernaplót?"
 
@@ -15421,8 +15429,8 @@
 #, no-c-format
 msgid ""
 "Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual "
-"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
-"%20Pidgin#manual_win32_spellcheck_installation"
+"installation instructions are at: http://developer.pidgin.im/wiki/Installing%"
+"20Pidgin#manual_win32_spellcheck_installation"
 msgstr ""
 "Hiba a helyesírás-ellenőrző telepítésekor. ($R3).$\\rHa az újrapróbálkozás "
 "meghiúsul, akkor saját kezűleg is telepítheti a http://developer.pidgin.im/"
--- a/po/hy.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/hy.po	Wed Feb 02 23:26:42 2011 +0000
@@ -3,7 +3,6 @@
 # This file is distributed under the same license as the PACKAGE package.
 # David Avsharyan <avsharyan@gmail.com>, 2009.
 #
-#, fuzzy
 msgid ""
 msgstr ""
 "Project-Id-Version: am\n"
@@ -16,7 +15,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
 #. Translators may want to transliterate the name.
 #. It is not to be translated.
--- a/po/mn.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/mn.po	Wed Feb 02 23:26:42 2011 +0000
@@ -15,7 +15,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
 
 #. Translators may want to transliterate the name.
 #. It is not to be translated.
--- a/po/ms_MY.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/ms_MY.po	Wed Feb 02 23:26:42 2011 +0000
@@ -15,7 +15,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Generator: KBabel 1.11.4\n"
 
 #. Translators may want to transliterate the name.
--- a/po/ta.po	Sun Jan 09 23:32:10 2011 +0000
+++ b/po/ta.po	Wed Feb 02 23:26:42 2011 +0000
@@ -19,7 +19,7 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Poedit-Country: INDIA\n"
 "X-Generator: Lokalize 1.0\n"
 "X-Poedit-Bookmarks: -1,470,-1,-1,-1,-1,-1,-1,-1,1715\n"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/ca-certs/AddTrust_External_Root.pem	Wed Feb 02 23:26:42 2011 +0000
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
+MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
+IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
+MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
+FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
+bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
+H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
+uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
+mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
+a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
+E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
+WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
+VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
+Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
+cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
+IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
+AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
+YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
+6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
+Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
+c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
+mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
+-----END CERTIFICATE-----
--- a/share/ca-certs/Makefile.am	Sun Jan 09 23:32:10 2011 +0000
+++ b/share/ca-certs/Makefile.am	Wed Feb 02 23:26:42 2011 +0000
@@ -1,4 +1,5 @@
 CERTIFICATES = \
+		AddTrust_External_Root.pem \
 		America_Online_Root_Certification_Authority_1.pem \
 		CAcert_Root.pem \
 		CAcert_Class3.pem \