changeset 31879:5cb66143ae2a

propagate from branch 'im.pidgin.pidgin' (head 8f0dbb75e0842b6df34c773ceb3a62e07819c532) to branch 'im.pidgin.pidgin.mxit' (head 58ce8d40af953c67a284a42e026ccdbfd25ffaa8)
author andrew.victor@mxit.com
date Fri, 12 Aug 2011 21:41:34 +0000
parents 88a1d883e65f (current diff) 04ff99311108 (diff)
children 66fa012633e9
files libpurple/protocols/mxit/cipher.c
diffstat 45 files changed, 488 insertions(+), 216 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Jul 09 20:10:36 2011 +0000
+++ b/ChangeLog	Fri Aug 12 21:41:34 2011 +0000
@@ -1,19 +1,52 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
-version 2.9.1 (MM/DD/YYYY):
+version 2.10.0 (MM/DD/YYYY):
 	Pidgin:
 	* Make the max size of incoming smileys a pref instead of hardcoding it.
-	  (Quentin Brandon)(#5231)
+	  (Quentin Brandon) (#5231)
+	* Added a plugin information dialog to show information for plugins
+	  that aren't otherwise visible in the plugins dialog.
+	* Fix building with GTK+ earlier than 2.14.0 (GTK+ 2.10 is still the
+	  minimum supported) (#14261)
+
+	libpurple:
+	* Fix a potential crash in the Log Reader plugin when reading QIP logs.
+	* Fix a large number of strcpy() and strcat() invocations to use
+	  strlcpy() and strlcat(), etc., forestalling an entire class of
+	  string buffer overrun bugs.
+	  (The Electronic Frontier Foundation, Dan Auerbach, Chris Palmer,
+          Jacob Appelbaum)
+	* Change some filename manipulations in filectl.c to use MAXPATHLEN
+	  instead of arbitrary length constants.  (The Electronic Frontier
+	  Foundation, Dan Auerbach, Chris Palmer, Jacob Appelbaum)
 
 	Gadu-Gadu:
 	* Fixed searching for buddies in public directory. (Tomasz Wasilczyk)
 	  (#5242)
 	* Better status message handling. (Tomasz Wasilczyk) (#14314)
 	* Merged two buddy blocking methods. (Tomasz Wasilczyk) (#5303)
+	* Fix building of the bundled libgadu library with older versions
+	  of GnuTLS. (patch plucked from upstream) (#14365)
+
+	ICQ:
+	* Fix crash selecting Tools->Set Mood when you're online with an
+	  ICQ account that is configured as an AIM account. (#14437)
+
+	IRC:
+	* Fix the handling of formatting following mIRC ^O (#14436)
+
+	MSN:
+	* Fix seemingly random crashing. (#14307)
 
 	XMPP:
 	* Do not generate malformed XML ("</>") when setting an empty mood.
 	  (#14342)
+	* Fix the /join <room> behavior.  (Broken when adding support for
+	  <room>@<server>)  (#14205)
+
+	Yahoo!/Yahoo! JAPAN:
+	* Fix coming out of idle while in an unavailable state
+	* Fix logging into Yahoo! JAPAN.  (#14259)
 
 version 2.9.0 (06/23/2011):
 	Pidgin:
--- a/ChangeLog.API	Sat Jul 09 20:10:36 2011 +0000
+++ b/ChangeLog.API	Fri Aug 12 21:41:34 2011 +0000
@@ -1,5 +1,14 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
+version 2.10.0:
+	libpurple:
+		Added:
+		* purple_srv_txt_query_destroy (accidentally left out of 2.8.0)
+
+	Pidgin:
+		Added:
+		* pidgin_dialogs_plugins_info (should not be used by anything but Pidgin)
+
 version 2.9.0:
 	libpurple:
 		Added:
--- a/configure.ac	Sat Jul 09 20:10:36 2011 +0000
+++ b/configure.ac	Fri Aug 12 21:41:34 2011 +0000
@@ -43,10 +43,10 @@
 #
 # Make sure to update finch/libgnt/configure.ac with libgnt version changes.
 #
-m4_define([purple_lt_current], [9])
+m4_define([purple_lt_current], [10])
 m4_define([purple_major_version], [2])
-m4_define([purple_minor_version], [9])
-m4_define([purple_micro_version], [1])
+m4_define([purple_minor_version], [10])
+m4_define([purple_micro_version], [0])
 m4_define([purple_version_suffix], [devel])
 m4_define([purple_version],
           [purple_major_version.purple_minor_version.purple_micro_version])
--- a/libpurple/dnsquery.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/dnsquery.c	Fri Aug 12 21:41:34 2011 +0000
@@ -154,8 +154,27 @@
 static gboolean
 resolve_ip(PurpleDnsQueryData *query_data)
 {
+#if defined(HAVE_GETADDRINFO) && defined(AI_NUMERICHOST)
+	struct addrinfo hints, *res;
+	char servname[20];
+
+	g_snprintf(servname, sizeof(servname), "%d", query_data->port);
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_UNSPEC;
+	hints.ai_flags |= AI_NUMERICHOST;
+
+	if (0 == getaddrinfo(query_data->hostname, servname, &hints, &res))
+	{
+		GSList *hosts = NULL;
+		hosts = g_slist_append(hosts, GINT_TO_POINTER(res->ai_addrlen));
+		hosts = g_slist_append(hosts, g_memdup(res->ai_addr, res->ai_addrlen));
+		purple_dnsquery_resolved(query_data, hosts);
+
+		freeaddrinfo(res);
+		return TRUE;
+	}
+#else /* defined(HAVE_GETADDRINFO) && defined(AI_NUMERICHOST) */
 	struct sockaddr_in sin;
-	/* TODO: Use inet_pton for IPv6 support */
 	if (inet_aton(query_data->hostname, &sin.sin_addr))
 	{
 		/*
@@ -171,6 +190,7 @@
 
 		return TRUE;
 	}
+#endif
 
 	return FALSE;
 }
--- a/libpurple/dnssrv.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/dnssrv.c	Fri Aug 12 21:41:34 2011 +0000
@@ -250,6 +250,52 @@
 	return list;
 }
 
+static PurpleSrvTxtQueryData *
+query_data_new(int type, gchar *query, gpointer extradata)
+{
+	PurpleSrvTxtQueryData *query_data = g_new0(PurpleSrvTxtQueryData, 1);
+	query_data->type = type;
+	query_data->extradata = extradata;
+	query_data->query = query;
+#ifndef _WIN32
+	query_data->fd_in = -1;
+	query_data->fd_out = -1;
+#endif
+	return query_data;
+}
+
+void
+purple_srv_txt_query_destroy(PurpleSrvTxtQueryData *query_data)
+{
+	PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops();
+
+	if (ops && ops->destroy)
+		ops->destroy(query_data);
+
+	if (query_data->handle > 0)
+		purple_input_remove(query_data->handle);
+#ifdef _WIN32
+	if (query_data->resolver != NULL)
+	{
+		/*
+		 * It's not really possible to kill a thread.  So instead we
+		 * just set the callback to NULL and let the DNS lookup
+		 * finish.
+		 */
+		query_data->cb.srv = NULL;
+		return;
+	}
+	g_free(query_data->error_message);
+#else
+	if (query_data->fd_out != -1)
+		close(query_data->fd_out);
+	if (query_data->fd_in != -1)
+		close(query_data->fd_in);
+#endif
+	g_free(query_data->query);
+	g_free(query_data);
+}
+
 #ifdef USE_IDN
 static gboolean
 dns_str_is_ascii(const char *name)
@@ -382,7 +428,11 @@
 			cp += size;
 
 			srvres = g_new0(PurpleSrvResponse, 1);
-			strcpy(srvres->hostname, name);
+			if (strlen(name) > sizeof(srvres->hostname) - 1) {
+				purple_debug_error("dnssrv", "hostname is longer than available buffer ('%s', %zd bytes)!",
+				                   name, strlen(name));
+			}
+			g_strlcpy(srvres->hostname, name, sizeof(srvres->hostname));
 			srvres->pref = pref;
 			srvres->port = port;
 			srvres->weight = weight;
@@ -523,7 +573,7 @@
 	}
 
 	waitpid(query_data->pid, &status, 0);
-	purple_srv_cancel(query_data);
+	purple_srv_txt_query_destroy(query_data);
 }
 
 #else /* _WIN32 */
@@ -583,7 +633,7 @@
 	query_data->resolver = NULL;
 	query_data->handle = 0;
 
-	purple_srv_cancel(query_data);
+	purple_srv_txt_query_destroy(query_data);
 
 	return FALSE;
 }
@@ -730,13 +780,10 @@
 	purple_debug_info("dnssrv","querying SRV record for %s: %s\n", domain,
 			query);
 	g_free(hostname);
-	
-	query_data = g_new0(PurpleSrvTxtQueryData, 1);
-	query_data->type = PurpleDnsTypeSrv;
+
+	query_data = query_data_new(PurpleDnsTypeSrv, query, extradata);
 	query_data->cb.srv = cb;
-	query_data->extradata = extradata;
-	query_data->query = query;
-	
+
 	if (purple_srv_txt_query_ui_resolve(query_data))
 	{
 		return query_data;
@@ -746,6 +793,7 @@
 	if(pipe(in) || pipe(out)) {
 		purple_debug_error("dnssrv", "Could not create pipe\n");
 		g_free(query);
+		g_free(query_data);
 		cb(NULL, 0, extradata);
 		return NULL;
 	}
@@ -753,8 +801,9 @@
 	pid = fork();
 	if (pid == -1) {
 		purple_debug_error("dnssrv", "Could not create process!\n");
+		g_free(query);
+		g_free(query_data);
 		cb(NULL, 0, extradata);
-		g_free(query);
 		return NULL;
 	}
 
@@ -762,6 +811,7 @@
 	if (pid == 0)
 	{
 		g_free(query);
+		g_free(query_data);
 
 		close(out[0]);
 		close(in[1]);
@@ -784,8 +834,6 @@
 	query_data->fd_in = in[1];
 	query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data);
 
-	g_free(query);
-
 	return query_data;
 #else
 	if (!initialized) {
@@ -862,13 +910,10 @@
 	purple_debug_info("dnssrv","querying TXT record for %s: %s\n", domain,
 			query);
 	g_free(hostname);
-	
-	query_data = g_new0(PurpleSrvTxtQueryData, 1);
-	query_data->type = PurpleDnsTypeTxt;
+
+	query_data = query_data_new(PurpleDnsTypeTxt, query, extradata);
 	query_data->cb.txt = cb;
-	query_data->extradata = extradata;
-	query_data->query = query;
-	
+
 	if (purple_srv_txt_query_ui_resolve(query_data)) {
 		/* query intentionally not freed
 		 */
@@ -879,6 +924,7 @@
 	if(pipe(in) || pipe(out)) {
 		purple_debug_error("dnssrv", "Could not create pipe\n");
 		g_free(query);
+		g_free(query_data);
 		cb(NULL, extradata);
 		return NULL;
 	}
@@ -886,8 +932,9 @@
 	pid = fork();
 	if (pid == -1) {
 		purple_debug_error("dnssrv", "Could not create process!\n");
+		g_free(query);
+		g_free(query_data);
 		cb(NULL, extradata);
-		g_free(query);
 		return NULL;
 	}
 
@@ -895,6 +942,7 @@
 	if (pid == 0)
 	{
 		g_free(query);
+		g_free(query_data);
 
 		close(out[0]);
 		close(in[1]);
@@ -911,14 +959,12 @@
 
 	if (write(in[1], &internal_query, sizeof(internal_query)) < 0)
 		purple_debug_error("dnssrv", "Could not write to TXT resolver\n");
-	
+
 	query_data->pid = pid;
 	query_data->fd_out = out[0];
 	query_data->fd_in = in[1];
 	query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data);
 
-	g_free(query);
-
 	return query_data;
 #else
 	if (!initialized) {
@@ -949,39 +995,15 @@
 }
 
 void
-purple_srv_cancel(PurpleSrvTxtQueryData *query_data)
+purple_txt_cancel(PurpleSrvTxtQueryData *query_data)
 {
-	PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops();
-
-	if (ops && ops->destroy)
-		ops->destroy(query_data);
-	
-	if (query_data->handle > 0)
-		purple_input_remove(query_data->handle);
-#ifdef _WIN32
-	if (query_data->resolver != NULL)
-	{
-		/*
-		 * It's not really possible to kill a thread.  So instead we
-		 * just set the callback to NULL and let the DNS lookup
-		 * finish.
-		 */
-		query_data->cb.srv = NULL;
-		return;
-	}
-	g_free(query_data->query);
-	g_free(query_data->error_message);
-#else
-	close(query_data->fd_out);
-	close(query_data->fd_in);
-#endif
-	g_free(query_data);
+	purple_srv_txt_query_destroy(query_data);
 }
 
 void
-purple_txt_cancel(PurpleSrvTxtQueryData *query_data)
+purple_srv_cancel(PurpleSrvTxtQueryData *query_data)
 {
-	purple_srv_cancel(query_data);
+	purple_srv_txt_query_destroy(query_data);
 }
 
 const gchar *
@@ -1006,12 +1028,41 @@
 static void
 purple_srv_query_resolved(PurpleSrvTxtQueryData *query_data, GList *records)
 {
+	GList *l;
+	PurpleSrvResponse *records_array;
+	int i = 0, length;
+
 	g_return_if_fail(records != NULL);
-	
-	purple_debug_info("dnssrv", "SRV records resolved for %s, count: %d\n", query_data->query, g_list_length(records));
-	
-	if (query_data->cb.srv != NULL)
-		query_data->cb.srv(purple_srv_sort(records)->data, g_list_length(records), query_data->extradata);
+
+	if (query_data->cb.srv == NULL) {
+		purple_srv_txt_query_destroy(query_data);
+
+		while (records) {
+			g_free(records->data);
+			records = g_list_delete_link(records, records);
+		}
+		return;
+	}
+
+	records = purple_srv_sort(records);
+	length = g_list_length(records);
+
+	purple_debug_info("dnssrv", "SRV records resolved for %s, count: %d\n",
+	                            query_data->query, length);
+
+	records_array = g_new(PurpleSrvResponse, length);
+	for (l = records; l; l = l->next, i++) {
+		records_array[i] = *(PurpleSrvResponse *)l->data;
+	}
+
+	query_data->cb.srv(records_array, length, query_data->extradata);
+
+	purple_srv_txt_query_destroy(query_data);
+
+	while (records) {
+		g_free(records->data);
+		records = g_list_delete_link(records, records);
+	}
 }
 
 /*
@@ -1024,19 +1075,29 @@
 
 	purple_debug_info("dnssrv", "TXT entries resolved for %s, count: %d\n", query_data->query, g_list_length(entries));
 
+	/* the callback should g_free the entries.
+	 */
 	if (query_data->cb.txt != NULL)
 		query_data->cb.txt(entries, query_data->extradata);
+	else {
+		while (entries) {
+			g_free(entries->data);
+			entries = g_list_delete_link(entries, entries);
+		}
+	}
+
+	purple_srv_txt_query_destroy(query_data);
 }
 
 static void
 purple_srv_query_failed(PurpleSrvTxtQueryData *query_data, const gchar *error_message)
 {
 	purple_debug_error("dnssrv", "%s\n", error_message);
-	
+
 	if (query_data->cb.srv != NULL)
 		query_data->cb.srv(NULL, 0, query_data->extradata);
-		
-	purple_srv_cancel(query_data);
+
+	purple_srv_txt_query_destroy(query_data);
 }
 
 static gboolean
@@ -1069,7 +1130,7 @@
 purple_srv_txt_query_get_query(PurpleSrvTxtQueryData *query_data)
 {
 	g_return_val_if_fail(query_data != NULL, NULL);
-	
+
 	return query_data->query;
 }
 
@@ -1078,6 +1139,6 @@
 purple_srv_txt_query_get_type(PurpleSrvTxtQueryData *query_data)
 {
 	g_return_val_if_fail(query_data != NULL, 0);
-	
+
 	return query_data->type;
 }
--- a/libpurple/dnssrv.h	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/dnssrv.h	Fri Aug 12 21:41:34 2011 +0000
@@ -133,6 +133,8 @@
  * Cancel an SRV or DNS query.
  *
  * @param query_data The request to cancel.
+ *
+ * @deprecated Use purple_srv_txt_query_destroy instead
  */
 void purple_srv_cancel(PurpleSrvTxtQueryData *query_data);
 
@@ -170,6 +172,8 @@
  *
  * @param query_data The request to cancel.
  * @since 2.6.0
+ *
+ * @deprecated Use purple_srv_txt_query_destroy instead
  */
 void purple_txt_cancel(PurpleSrvTxtQueryData *query_data);
 
--- a/libpurple/log.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/log.c	Fri Aug 12 21:41:34 2011 +0000
@@ -1838,7 +1838,7 @@
 
 			g_snprintf(convostart, length, "%s", temp);
 			memset(&tm, 0, sizeof(tm));
-			sscanf(convostart, "%*s %s %d %d:%d:%d %d",
+			sscanf(convostart, "%*s %3s %d %d:%d:%d %d",
 			       month, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &tm.tm_year);
 			/* Ugly hack, in case current locale is not English */
 			if (purple_strequal(month, "Jan")) {
--- a/libpurple/plugins/filectl.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/plugins/filectl.c	Fri Aug 12 21:41:34 2011 +0000
@@ -40,12 +40,12 @@
 run_commands()
 {
 	struct stat finfo;
-	char filename[256];
+	char filename[MAXPATHLEN];
 	char buffer[1024];
 	char *command, *arg1, *arg2;
 	FILE *file;
 
-	sprintf(filename, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
+	snprintf(filename, MAXPATHLEN, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
 
 	file = g_fopen(filename, "r+");
 	while (fgets(buffer, sizeof(buffer), file)) {
@@ -144,9 +144,9 @@
 {
 	/* most of this was taken from Bash v2.04 by the FSF */
 	struct stat finfo;
-	char filename[256];
+	char filename[MAXPATHLEN];
 
-	sprintf(filename, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
+	snprintf(filename, MAXPATHLEN, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
 
 	if ((g_stat(filename, &finfo) == 0) && (finfo.st_size > 0))
 		run_commands();
@@ -160,9 +160,9 @@
 {
 	/* most of this was taken from Bash v2.04 by the FSF */
 	struct stat finfo;
-	char filename[256];
+	char filename[MAXPATHLEN];
 
-	sprintf(filename, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
+	snprintf(filename, MAXPATHLEN, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
 
 	if ((g_stat(filename, &finfo) == 0) && (finfo.st_size > 0))
 	{
--- a/libpurple/plugins/log_reader.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/plugins/log_reader.c	Fri Aug 12 21:41:34 2011 +0000
@@ -1454,11 +1454,15 @@
 		const char *footer = NULL;
 		GString *temp = NULL;
 
-		if ((c = strstr(c, "\n")))
-		{
-			*c = '\0';
-			c++;
-		}
+		/* There's always a trailing '\n' at the end of the file (see above), so
+		 * just quit out if we don't find another, because we're at the end.
+		 */
+		c = strchr(c, '\n');
+		if (!c)
+			break;
+
+		*c = '\0';
+		c++;
 
 		/* Convert links.
 		 *
@@ -1482,14 +1486,14 @@
 				char *end_paren;
 				char *space;
 
-				if (!(end_paren = strstr(link, ")")))
+				if (!(end_paren = strchr(link, ')')))
 				{
 					/* Something is not as we expect.  Bail out. */
 					break;
 				}
 
 				if (!temp)
-					temp = g_string_sized_new(c ? (c - 1 - line) : strlen(line));
+					temp = g_string_sized_new(strlen(line));
 
 				g_string_append_len(temp, line, (tmp - line));
 
@@ -1504,7 +1508,7 @@
 
 				/* The \r is a bit of a hack to keep there from being a \r in
 				 * the link text, which may not matter. */
-				if ((space = strstr(end_paren, " ")) || (space = strstr(end_paren, "\r")))
+				if ((space = strchr(end_paren, ' ')) || (space = strchr(end_paren, '\r')))
 				{
 					g_string_append_len(temp, end_paren + 1, space - end_paren - 1);
 
@@ -1539,7 +1543,7 @@
 		if (*line == '[') {
 			const char *timestamp;
 
-			if ((timestamp = strstr(line, "]"))) {
+			if ((timestamp = strchr(line, ']'))) {
 				line++;
 				/* TODO: Parse the timestamp and convert it to Purple's format. */
 				g_string_append(formatted, "<font size=\"2\">(");
@@ -1658,7 +1662,7 @@
 					}
 				}
 			} else {
-				const char *line2 = strstr(line, ":");
+				const char *line2 = strchr(line, ':');
 				if (line2) {
 					const char *acct_name;
 					line2++;
@@ -1819,7 +1823,7 @@
 
 		gboolean add_new_log = FALSE;
 
-		if (*c) {
+		if (c && *c) {
 			if (purple_str_has_prefix(c, QIP_LOG_IN_MESSAGE) ||
 				purple_str_has_prefix(c, QIP_LOG_OUT_MESSAGE)) {
 
@@ -1828,11 +1832,11 @@
 				new_line = c;
 
 				/* find EOL */
-				c = strstr(c, "\n");
+				c = strchr(c, '\n');
 				c++;
 
 				/* Find the last '(' character. */
-				if ((tmp = strstr(c, "\n")) != NULL) {
+				if ((tmp = strchr(c, '\n')) != NULL) {
 					while (*tmp && *tmp != '(') --tmp;
 					c = tmp;
 				} else {
@@ -1902,10 +1906,10 @@
 			start_log = new_line;
 		}
 
-		if (*c) {
+		if (c && *c) {
 			/* find EOF */
-			c = strstr(c, "\n");
-			c++;
+			if ((c = strchr(c, '\n')))
+				c++;
 		}
 	}
 
@@ -1983,13 +1987,13 @@
 			is_in_message = purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC);
 
 			/* find EOL */
-			c = strstr(c, "\n");
+			c = strchr(c, '\n');
 
 			/* XXX: Do we need buddy_name when we have buddy->alias? */
 			buddy_name = ++c;
 
 			/* Find the last '(' character. */
-			if ((tmp = strstr(c, "\n")) != NULL) {
+			if ((tmp = strchr(c, '\n')) != NULL) {
 				while (*tmp && *tmp != '(') --tmp;
 				c = tmp;
 			} else {
@@ -2042,12 +2046,12 @@
 					}
 
 					/* find EOF */
-					c = strstr(c, "\n");
+					c = strchr(c, '\n');
 					line = ++c;
 				}
 			}
 		} else {
-			if ((c = strstr(c, "\n")))
+			if ((c = strchr(c, '\n')))
 				*c = '\0';
 
 			if (line[0] != '\n' && line[0] != '\r') {
@@ -2186,7 +2190,7 @@
 				                  " length = (%d)\n",
 				                  sn, data->path, data->offset, data->length);
 			}
-			c = strstr(c, "\n");
+			c = strchr(c, '\n');
 			c++;
 		}
 
@@ -2342,7 +2346,7 @@
 		char *end;
 		char *old_tag;
 		char *tag;
-		end = strstr(start, "\n");
+		end = strchr(start, '\n');
 		if (!end)
 			break;
 		*end = '\0';
--- a/libpurple/plugins/tcl/tcl_ref.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/plugins/tcl/tcl_ref.c	Fri Aug 12 21:41:34 2011 +0000
@@ -92,6 +92,7 @@
 
 static void purple_tcl_ref_update(Tcl_Obj *obj)
 {
+	size_t len;
 	/* This is ugly on memory, but we pretty much have to either
 	 * do this or guesstimate lengths or introduce a varargs
 	 * function in here ... ugh. */
@@ -100,8 +101,9 @@
 				      OBJ_REF_VALUE(obj));
 
 	obj->length = strlen(bytes);
-	obj->bytes = ckalloc(obj->length + 1);
-	strcpy(obj->bytes, bytes);
+	len = obj->length + 1;
+	obj->bytes = ckalloc(len);
+	g_strlcpy(obj->bytes, bytes, len);
 	g_free(bytes);
 }
 
--- a/libpurple/plugins/tcl/tcl_signals.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/plugins/tcl/tcl_signals.c	Fri Aug 12 21:41:34 2011 +0000
@@ -259,8 +259,9 @@
 					vals[i] = ckalloc(1);
 					*(char *)vals[i] = '\0';
 				} else {
-					vals[i] = ckalloc(strlen(*strs[i]) + 1);
-					strcpy(vals[i], *strs[i]);
+					size_t len = strlen(*strs[i]) + 1;
+					vals[i] = ckalloc(len);
+					g_strlcpy(vals[i], *strs[i], len);
 				}
 				Tcl_LinkVar(handler->interp, name->str,
 					    (char *)&vals[i], TCL_LINK_STRING);
--- a/libpurple/prefs.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/prefs.c	Fri Aug 12 21:41:34 2011 +0000
@@ -277,6 +277,12 @@
 		}
 	}
 
+	if ((pref_type == PURPLE_PREF_BOOLEAN || pref_type == PURPLE_PREF_INT) &&
+			pref_value == NULL) {
+		/* Missing a value attribute */
+		return;
+	}
+
 	if(purple_strequal(element_name, "item")) {
 		struct purple_pref *pref;
 
--- a/libpurple/protocols/gg/gg.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/gg/gg.c	Fri Aug 12 21:41:34 2011 +0000
@@ -918,6 +918,9 @@
 	PurpleBuddy *buddy;
 	gpointer buddy_icon_data;
 
+	purple_debug_info("gg", "gg_fetch_avatar_cb: got avatar image for %s\n",
+		d->uin);
+
 	/* FIXME: This shouldn't be necessary */
 	if (!PURPLE_CONNECTION_IS_VALID(d->gc)) {
 		g_free(d->uin);
@@ -936,7 +939,8 @@
 
 	purple_buddy_icons_set_for_user(account, purple_buddy_get_name(buddy),
 			buddy_icon_data, len, d->avatar_url);
-	purple_debug_info("gg", "UIN: %s should have avatar now\n", d->uin);
+	purple_debug_info("gg", "gg_fetch_avatar_cb: UIN %s should have avatar "
+		"now\n", d->uin);
 
 out:
 	g_free(d->uin);
@@ -1018,6 +1022,8 @@
 				data->uin = g_strdup(uin);
 				data->avatar_url = g_strdup(bigavatar);
 
+				purple_debug_info("gg", "gg_get_avatar_url_cb: "
+					"requesting avatar for %s\n", uin);
 				url_data = purple_util_fetch_url_request_len_with_account(account,
 						bigavatar, TRUE, "Mozilla/4.0 (compatible; MSIE 5.0)",
 						FALSE, NULL, FALSE, -1, gg_fetch_avatar_cb, data);
--- a/libpurple/protocols/gg/lib/libgadu.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/gg/lib/libgadu.c	Fri Aug 12 21:41:34 2011 +0000
@@ -893,8 +893,7 @@
 		gnutls_global_init();
 		gnutls_certificate_allocate_credentials(&tmp->xcred);
 		gnutls_init(&tmp->session, GNUTLS_CLIENT);
-		gnutls_priority_set_direct(tmp->session, "NORMAL:-VERS-TLS", NULL);
-//		gnutls_priority_set_direct(tmp->session, "NONE:+VERS-SSL3.0:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
+		gnutls_set_default_priority(tmp->session);
 		gnutls_credentials_set(tmp->session, GNUTLS_CRD_CERTIFICATE, tmp->xcred);
 #elif defined(GG_CONFIG_HAVE_OPENSSL)
 		char buf[1024];
--- a/libpurple/protocols/irc/irc.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/irc/irc.c	Fri Aug 12 21:41:34 2011 +0000
@@ -251,7 +251,9 @@
 
 static void irc_who_channel(PurpleConversation *conv, struct irc_conn *irc)
 {
-	if (purple_conversation_get_account(conv) == irc->account && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
+	if (purple_conversation_get_account(conv) == irc->account
+	    && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT
+	    && !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) {
 		char *buf = irc_format(irc, "vc", "WHO", purple_conversation_get_name(conv));
 		
 		purple_debug(PURPLE_DEBUG_INFO, "irc",
--- a/libpurple/protocols/irc/parse.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/irc/parse.c	Fri Aug 12 21:41:34 2011 +0000
@@ -459,6 +459,7 @@
 				decoded = g_string_append(decoded, "</U>");
 			if (font)
 				decoded = g_string_append(decoded, "</FONT>");
+			bold = italic = underline = font = FALSE;
 			break;
 		default:
 			purple_debug(PURPLE_DEBUG_ERROR, "irc", "Unexpected mIRC formatting character %d\n", *cur);
--- a/libpurple/protocols/jabber/jabber.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Fri Aug 12 21:41:34 2011 +0000
@@ -199,7 +199,7 @@
 		   hostname, so maybe we want to detect that and use it
 		   instead
 		*/
-		strcpy(hostname, "localhost");
+		g_strlcpy(hostname, "localhost", sizeof(hostname));
 	}
 	hostname[sizeof(hostname) - 1] = '\0';
 
@@ -3009,7 +3009,7 @@
 {
 	JabberChat *chat = jabber_chat_find_by_conv(conv);
 	GHashTable *components;
-	JabberID *jid;
+	JabberID *jid = NULL;
 	const char *room = NULL, *server = NULL, *handle = NULL;
 
 	if (!chat || !args || !args[0])
@@ -3017,7 +3017,8 @@
 
 	components = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
 
-	jid = jabber_id_new(args[0]);
+	if (strchr(args[0], '@'))
+		jid = jabber_id_new(args[0]);
 	if (jid) {
 		room   = jid->node;
 		server = jid->domain;
@@ -3673,8 +3674,7 @@
 	                  PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
 	                  PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
 	                  jabber_cmd_chat_join,
-	                  _("join: &lt;room&gt; [password]:  Join a chat on this server."),
-	                  /* _("join: &lt;room[@server]&gt; [password]:  Join a chat."), */
+	                  _("join: &lt;room[@server]&gt; [password]:  Join a chat."),
 	                  NULL);
 	commands = g_slist_prepend(commands, GUINT_TO_POINTER(id));
 
--- a/libpurple/protocols/jabber/win32/posix.uname.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/jabber/win32/posix.uname.c	Fri Aug 12 21:41:34 2011 +0000
@@ -54,32 +54,32 @@
   GetVersionEx ( &OS_version );
   GetSystemInfo ( &System_Info );
 
-  strcpy( uts->sysname, "WIN32_" );
+  g_strlcpy( uts->sysname, "WIN32_" , sizeof(uts->sysname));
   switch( OS_version.dwPlatformId )
   {
     case VER_PLATFORM_WIN32_NT:
-      strcat( uts->sysname, "WinNT" );
+      g_strlcat( uts->sysname, "WinNT", sizeof(uts->sysname) );
       MingwOS = WinNT;
       break;
     case VER_PLATFORM_WIN32_WINDOWS:
       switch ( OS_version.dwMinorVersion )
       {
         case 0:
-          strcat( uts->sysname, "Win95" );
+          g_strlcat( uts->sysname, "Win95", sizeof(uts->sysname) );
 	  MingwOS = Win95;
           break;
         case 10:
-          strcat( uts->sysname, "Win98" );
+          g_strlcat( uts->sysname, "Win98", sizeof(uts->sysname) );
 	  MingwOS = Win98;
           break;
         default:
-          strcat( uts->sysname, "Win??" );
+          g_strlcat( uts->sysname, "Win??", sizeof(uts->sysname) );
 	  MingwOS = unknown;
           break;
       }
       break;
     default:
-      strcat( uts->sysname, "Win??" );
+      g_strlcat( uts->sysname, "Win??", sizeof(uts->sysname) );
       MingwOS = unknown;
       break;
   }
@@ -92,13 +92,13 @@
   switch( System_Info.wProcessorArchitecture )
   {
     case PROCESSOR_ARCHITECTURE_PPC:
-      strcpy( uts->machine, "ppc" );
+      g_strlcpy( uts->machine, "ppc" , sizeof( uts->machine ) );
       break;
     case PROCESSOR_ARCHITECTURE_ALPHA:
-      strcpy( uts->machine, "alpha" );
+      g_strlcpy( uts->machine, "alpha" , sizeof( uts->machine ) );
       break;
     case PROCESSOR_ARCHITECTURE_MIPS:
-      strcpy( uts->machine, "mips" );
+      g_strlcpy( uts->machine, "mips" , sizeof( uts->machine ) );
       break;
     case PROCESSOR_ARCHITECTURE_INTEL:
       /* dwProcessorType is only valid in Win95 and Win98
@@ -115,7 +115,7 @@
               sprintf( uts->machine, "i%ld", System_Info.dwProcessorType );
               break;
             default:
-              strcpy( uts->machine, "i386" );
+              g_strlcpy( uts->machine, "i386" , sizeof( uts->machine ) );
               break;
           }
           break;
@@ -123,12 +123,12 @@
 	  sprintf( uts->machine, "i%d86", System_Info.wProcessorLevel );
 	  break;
 	default:
-	  strcpy( uts->machine, "unknown" );
+	  g_strlcpy( uts->machine, "unknown" , sizeof( uts->machine ) );
 	  break;
       }
       break;
     default:
-      strcpy( uts->machine, "unknown" );
+      g_strlcpy( uts->machine, "unknown" , sizeof( uts->machine ) );
       break;
   }
 
--- a/libpurple/protocols/msn/contact.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/msn/contact.c	Fri Aug 12 21:41:34 2011 +0000
@@ -474,7 +474,7 @@
 }
 
 /*parse contact list*/
-static void
+static gboolean
 msn_parse_contact_list(MsnSession *session, xmlnode *node)
 {
 	xmlnode *fault, *faultnode;
@@ -499,13 +499,14 @@
 			if (g_str_equal(errorcode, "ABDoesNotExist")) {
 				msn_create_address_book(session);
 				g_free(errorcode);
-				return;
+				return FALSE;
 			}
 
 			g_free(errorcode);
 		}
 
 		msn_get_contact_list(session, MSN_PS_INITIAL, NULL);
+		return FALSE;
 	} else {
 		xmlnode *service;
 
@@ -514,6 +515,7 @@
 			 service; service = xmlnode_get_next_twin(service)) {
 			msn_parse_each_service(session, service);
 		}
+		return TRUE;
 	}
 }
 
@@ -534,23 +536,24 @@
 
 		purple_debug_misc("msn", "Got the contact list!\n");
 
-		msn_parse_contact_list(session, resp->xml);
+		if (msn_parse_contact_list(session, resp->xml)) {
 #ifdef MSN_PARTIAL_LISTS
-		abLastChange = purple_account_get_string(session->account,
-			"ablastChange", NULL);
-		dynamicItemLastChange = purple_account_get_string(session->account,
-			"DynamicItemLastChanged", NULL);
+			abLastChange = purple_account_get_string(session->account,
+				"ablastChange", NULL);
+			dynamicItemLastChange = purple_account_get_string(session->account,
+				"DynamicItemLastChanged", NULL);
 #endif
 
-		if (state->partner_scenario == MSN_PS_INITIAL) {
+			if (state->partner_scenario == MSN_PS_INITIAL) {
 #ifdef MSN_PARTIAL_LISTS
-			/* XXX: this should be enabled when we can correctly do partial
-			   syncs with the server. Currently we need to retrieve the whole
-			   list to detect sync issues */
-			msn_get_address_book(session, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange);
+				/* XXX: this should be enabled when we can correctly do partial
+				   syncs with the server. Currently we need to retrieve the whole
+				   list to detect sync issues */
+				msn_get_address_book(session, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange);
 #else
-			msn_get_address_book(session, MSN_PS_INITIAL, NULL, NULL);
+				msn_get_address_book(session, MSN_PS_INITIAL, NULL, NULL);
 #endif
+			}
 		}
 	}
 }
--- a/libpurple/protocols/msn/msn.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/msn/msn.c	Fri Aug 12 21:41:34 2011 +0000
@@ -265,9 +265,9 @@
 		}
 
 		if (real_alias[0] == '\0')
-			strcpy(real_alias, purple_account_get_username(account));
+			g_strlcpy(real_alias, purple_account_get_username(account), sizeof(real_alias));
 	} else
-		strcpy(real_alias, purple_account_get_username(account));
+		g_strlcpy(real_alias, purple_account_get_username(account), sizeof(real_alias));
 
 	closure = g_new0(struct public_alias_closure, 1);
 	closure->account = account;
--- a/libpurple/protocols/msn/notification.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/msn/notification.c	Fri Aug 12 21:41:34 2011 +0000
@@ -198,6 +198,9 @@
 	{
 		/* RPS authentication */
 
+		if (session->nexus)
+			msn_nexus_destroy(session->nexus);
+
 		session->nexus = msn_nexus_new(session);
 
 		session->nexus->policy = g_strdup(cmd->params[3]);
--- a/libpurple/protocols/msn/session.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/msn/session.c	Fri Aug 12 21:41:34 2011 +0000
@@ -288,6 +288,8 @@
 msn_session_activate_login_timeout(MsnSession *session)
 {
 	if (!session->logged_in && session->connected) {
+		if (session->login_timeout)
+			purple_timeout_remove(session->login_timeout);
 		session->login_timeout =
 			purple_timeout_add_seconds(MSN_LOGIN_FQY_TIMEOUT,
 			                           msn_login_timeout_cb, session);
--- a/libpurple/protocols/msn/slp.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/msn/slp.c	Fri Aug 12 21:41:34 2011 +0000
@@ -284,7 +284,6 @@
 	purple_xfer_unref(xfer);
 
 	slpmsg = msn_slpmsg_file_new(slpcall, purple_xfer_get_size(xfer));
-	msn_slpmsg_set_slplink(slpmsg, slpcall->slplink);
 
 	msn_slplink_send_slpmsg(slpcall->slplink, slpmsg);
 }
--- a/libpurple/protocols/msn/slpcall.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Fri Aug 12 21:41:34 2011 +0000
@@ -490,12 +490,10 @@
 		if (img != NULL) {
 			/* DATA PREP */
 			slpmsg = msn_slpmsg_dataprep_new(slpcall);
-			msn_slpmsg_set_slplink(slpmsg, slplink);
 			msn_slplink_queue_slpmsg(slplink, slpmsg);
 
 			/* DATA */
 			slpmsg = msn_slpmsg_obj_new(slpcall, img);
-			msn_slpmsg_set_slplink(slpmsg, slplink);
 			msn_slplink_queue_slpmsg(slplink, slpmsg);
 			purple_imgstore_unref(img);
 
--- a/libpurple/protocols/mxit/cipher.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.c	Fri Aug 12 21:41:34 2011 +0000
@@ -85,12 +85,12 @@
 	pass[sizeof( pass ) - 1] = '\0';
 
 	/* build the custom AES encryption key */
-	strcpy( key, INITIAL_KEY );
+	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
 	memcpy( key, session->clientkey, strlen( session->clientkey ) );
 	ExpandKey( (unsigned char*) key, (unsigned char*) exkey );
 
 	/* build the custom data to be encrypted */
-	strcpy( pass, SECRET_HEADER );
+	g_strlcpy( pass, SECRET_HEADER, sizeof( pass ) );
 	strcat( pass, session->acc->password );
 
 	/* pad the secret data */
--- a/libpurple/protocols/oscar/oscar.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Fri Aug 12 21:41:34 2011 +0000
@@ -743,11 +743,15 @@
 	gc->flags |= PURPLE_CONNECTION_HTML;
 	if (oscar_util_valid_name_icq((purple_account_get_username(account)))) {
 		od->icq = TRUE;
-		gc->flags |= PURPLE_CONNECTION_SUPPORT_MOODS;
 	} else {
 		gc->flags |= PURPLE_CONNECTION_AUTO_RESP;
 	}
 
+	/* Set this flag based on the protocol_id rather than the username,
+	   because that is what's tied to the get_moods prpl callback. */
+	if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq"))
+		gc->flags |= PURPLE_CONNECTION_SUPPORT_MOODS;
+
 	od->default_port = purple_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT);
 
 	encryption_type = purple_account_get_string(account, "encryption", OSCAR_DEFAULT_ENCRYPTION);
@@ -5647,7 +5651,10 @@
 
 	tmp1 = g_utf8_strdown(buf, -1);
 	tmp2 = g_utf8_normalize(tmp1, -1, G_NORMALIZE_DEFAULT);
-	strcpy(buf, tmp2);
+	if (strlen(tmp2) > sizeof(buf) - 1) {
+		purple_debug_error("oscar", "normalized string exceeds buffer length!\n");
+	}
+	g_strlcpy(buf, tmp2, sizeof(buf));
 	g_free(tmp2);
 	g_free(tmp1);
 
--- a/libpurple/protocols/sametime/sametime.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Fri Aug 12 21:41:34 2011 +0000
@@ -922,6 +922,11 @@
   alias = mwSametimeGroup_getAlias(stgroup);
   type = mwSametimeGroup_getType(stgroup);
 
+  if (!name) {
+    DEBUG_WARN("Can't ensure a null group\n");
+    return NULL;
+  }
+
   DEBUG_INFO("attempting to ensure group %s, called %s\n",
 	     NSTR(name), NSTR(alias));
 
--- a/libpurple/protocols/simple/simple.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/simple/simple.c	Fri Aug 12 21:41:34 2011 +0000
@@ -1932,6 +1932,8 @@
 
 	gc->proto_data = sip = g_new0(struct simple_account_data, 1);
 	sip->gc = gc;
+	sip->fd = -1;
+	sip->listenfd = -1;
 	sip->account = account;
 	sip->registerexpire = 900;
 	sip->udp = purple_account_get_bool(account, "udp", FALSE);
--- a/libpurple/protocols/yahoo/libymsg.h	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/yahoo/libymsg.h	Fri Aug 12 21:41:34 2011 +0000
@@ -48,7 +48,7 @@
 #define YAHOO_ROOMLIST_LOCALE "us"
 
 /* Yahoo! JAPAN stuff */
-#define YAHOOJP_PAGER_HOST_REQ_URL "http://cs1.msg.vip.ogk.yahoo.co.jp/capacity"
+#define YAHOOJP_PAGER_HOST_REQ_URL "http://cs1.yahoo.co.jp/capacity"
 #define YAHOOJP_TOKEN_URL "https://login.yahoo.co.jp/config/pwtoken_get?src=ymsgr&ts=&login=%s&passwd=%s&chal=%s"
 #define YAHOOJP_LOGIN_URL "https://login.yahoo.co.jp/config/pwtoken_login?src=ymsgr&ts=&token=%s"
 #define YAHOOJP_PROFILE_URL "http://profiles.yahoo.co.jp/"
--- a/libpurple/protocols/yahoo/yahoo_filexfer.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c	Fri Aug 12 21:41:34 2011 +0000
@@ -1428,7 +1428,7 @@
 
 	unix_time = time(NULL);
 	time_str = ctime(&unix_time);
-	strcpy(time_str + strlen(time_str) - 1, "\0");
+	time_str[strlen(time_str) - 1] = '\0';
 
 	if (xd->txbuflen == 0)	{
 		xd->txbuf = g_strdup_printf("HTTP/1.0 200 OK\r\n"
--- a/libpurple/protocols/zephyr/ZAsyncLocate.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/zephyr/ZAsyncLocate.c	Fri Aug 12 21:41:34 2011 +0000
@@ -18,6 +18,7 @@
 {
     int retval;
     ZNotice_t notice;
+    size_t userlen, versionlen;
 
     if (ZGetFD() < 0)
 	if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE)
@@ -37,16 +38,18 @@
     if ((retval = ZSendNotice(&notice, auth)) != ZERR_NONE)
 	return(retval);
 
-    if ((zald->user = (char *) malloc(strlen(user)+1)) == NULL) {
+    userlen = strlen(user) + 1;
+    versionlen = strlen(notice.z_version) + 1;
+    if ((zald->user = (char *) malloc(userlen)) == NULL) {
 	return(ENOMEM);
     }
-    if ((zald->version = (char *) malloc(strlen(notice.z_version)+1)) == NULL) {
+    if ((zald->version = (char *) malloc(versionlen)) == NULL) {
 	free(zald->user);
 	return(ENOMEM);
     }
     zald->uid = notice.z_multiuid;
-    strcpy(zald->user,user);
-    strcpy(zald->version,notice.z_version);
+    g_strlcpy(zald->user,user,userlen);
+    g_strlcpy(zald->version,notice.z_version,versionlen);
 
     return(ZERR_NONE);
 }
@@ -109,35 +112,38 @@
        __locate_list[i].host = (char *) malloc(len);
        if (!__locate_list[i].host)
 	  return (ENOMEM);
-       (void) strcpy(__locate_list[i].host, ptr);
+       g_strlcpy(__locate_list[i].host, ptr,len);
        ptr += len;
 
        len = strlen (ptr) + 1;
        __locate_list[i].time = (char *) malloc(len);
        if (!__locate_list[i].time)
 	  return (ENOMEM);
-       (void) strcpy(__locate_list[i].time, ptr);
+       g_strlcpy(__locate_list[i].time, ptr,len);
        ptr += len;
 
        len = strlen (ptr) + 1;
        __locate_list[i].tty = (char *) malloc(len);
        if (!__locate_list[i].tty)
 	  return (ENOMEM);
-       (void) strcpy(__locate_list[i].tty, ptr);
+       g_strlcpy(__locate_list[i].tty, ptr,len);
        ptr += len;
     }
 
     __locate_next = 0;
     *nlocs = __locate_num;
     if (user) {
+	size_t len;    
 	if (zald) {
-	    if ((*user = (char *) malloc(strlen(zald->user)+1)) == NULL)
+	    len = strlen(zald->user) + 1;
+	    if ((*user = (char *) malloc(len)) == NULL)
 		return(ENOMEM);
-	    strcpy(*user,zald->user);
+	    g_strlcpy(*user,zald->user,len);
 	} else {
-	    if ((*user = (char *) malloc(strlen(notice->z_class_inst)+1)) == NULL)
+	    len = strlen(notice->z_class_inst) + 1;
+	    if ((*user = (char *) malloc(len)) == NULL)
 		return(ENOMEM);
-	    strcpy(*user,notice->z_class_inst);
+	    g_strlcpy(*user,notice->z_class_inst,len);
 	}
     }
     return (ZERR_NONE);
--- a/libpurple/protocols/zephyr/ZInit.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/zephyr/ZInit.c	Fri Aug 12 21:41:34 2011 +0000
@@ -101,14 +101,14 @@
 
 #ifdef ZEPHYR_USES_KERBEROS
     if (krealm) {
-	strcpy(__Zephyr_realm, krealm);
+      g_strlcpy(__Zephyr_realm, krealm, REALM_SZ);
     } else if ((krb_get_tf_fullname(TKT_FILE, d1, d2, __Zephyr_realm)
 		!= KSUCCESS) &&
 	       ((krbval = krb_get_lrealm(__Zephyr_realm, 1)) != KSUCCESS)) {
 	return (krbval);
     }
 #else
-    strcpy(__Zephyr_realm, "local-realm");
+    g_strlcpy(__Zephyr_realm, "local-realm", 12);
 #endif
 
     __My_addr.s_addr = INADDR_NONE;
--- a/libpurple/protocols/zephyr/ZRetSubs.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/zephyr/ZRetSubs.c	Fri Aug 12 21:41:34 2011 +0000
@@ -141,32 +141,37 @@
 		}
 
 		for (ptr=retnotice.z_message,i = 0; i< __subscriptions_num; i++) {
+			size_t len;
+
+			len = strlen(ptr) + 1;
 			__subscriptions_list[i].zsub_class = (char *)
-				malloc((unsigned)strlen(ptr)+1);
+				malloc(len);
 			if (!__subscriptions_list[i].zsub_class) {
 				ZFreeNotice(&retnotice);
 				return (ENOMEM);
 			}
-			(void) strcpy(__subscriptions_list[i].zsub_class,ptr);
-			ptr += strlen(ptr)+1;
+			g_strlcpy(__subscriptions_list[i].zsub_class,ptr,len);
+			ptr += len;
+			len = strlen(ptr) + 1;
 			__subscriptions_list[i].zsub_classinst = (char *)
-				malloc((unsigned)strlen(ptr)+1);
+				malloc(len);
 			if (!__subscriptions_list[i].zsub_classinst) {
 				ZFreeNotice(&retnotice);
 				return (ENOMEM);
 			}
-			(void) strcpy(__subscriptions_list[i].zsub_classinst,ptr);
-			ptr += strlen(ptr)+1;
+			g_strlcpy(__subscriptions_list[i].zsub_classinst,ptr,len);
+			ptr += len;
 			ptr2 = ptr;
 			if (!*ptr2)
 				ptr2 = "*";
+			len = strlen(ptr2) + 1;
 			__subscriptions_list[i].zsub_recipient = (char *)
-				malloc((unsigned)strlen(ptr2)+1);
+				malloc(len);
 			if (!__subscriptions_list[i].zsub_recipient) {
 				ZFreeNotice(&retnotice);
 				return (ENOMEM);
 			}
-			(void) strcpy(__subscriptions_list[i].zsub_recipient,ptr2);
+			g_strlcpy(__subscriptions_list[i].zsub_recipient,ptr2,len);
 			ptr += strlen(ptr)+1;
 		}
 		ZFreeNotice(&retnotice);
--- a/libpurple/protocols/zephyr/Zinternal.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/zephyr/Zinternal.c	Fri Aug 12 21:41:34 2011 +0000
@@ -677,7 +677,7 @@
     if (buffer_len < strlen(notice->z_version)+1)
 	return (ZERR_HEADERLEN);
 
-    (void) strcpy(ptr, notice->z_version);
+    g_strlcpy(ptr, notice->z_version, buffer_len);
     ptr += strlen(ptr)+1;
 
     if (ZMakeAscii32(ptr, end-ptr, Z_NUMFIELDS + notice->z_num_other_fields)
@@ -767,9 +767,9 @@
     if (*ptr+len > end)
 	return 1;
     if (field)
-	(void) strcpy(*ptr, field);
+      g_strlcpy(*ptr, field, len);
     else
-	**ptr = '\0';
+      **ptr = '\0';
     *ptr += len;
 
     return 0;
--- a/libpurple/protocols/zephyr/zephyr.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/protocols/zephyr/zephyr.c	Fri Aug 12 21:41:34 2011 +0000
@@ -2235,7 +2235,7 @@
 		return NULL;
 	}
 
-	strcpy(buf, tmp);
+	g_strlcpy(buf, tmp, sizeof(buf));
 	g_free(tmp);
 
 	return buf;
--- a/libpurple/proxy.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/proxy.c	Fri Aug 12 21:41:34 2011 +0000
@@ -981,7 +981,7 @@
 				hostname[sizeof(hostname) - 1] = '\0';
 				if (ret < 0 || hostname[0] == '\0') {
 					purple_debug_warning("proxy", "gethostname() failed -- is your hostname set?");
-					strcpy(hostname, "localhost");
+					g_strlcpy(hostname, "localhost", sizeof(hostname));
 				}
 
 				if (domain != NULL)
@@ -1115,7 +1115,7 @@
 		hostname[sizeof(hostname) - 1] = '\0';
 		if (ret < 0 || hostname[0] == '\0') {
 			purple_debug_warning("proxy", "gethostname() failed -- is your hostname set?");
-			strcpy(hostname, "localhost");
+			g_strlcpy(hostname, "localhost", sizeof(hostname));
 		}
 
 		t1 = g_strdup_printf("%s:%s",
--- a/libpurple/stun.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/stun.c	Fri Aug 12 21:41:34 2011 +0000
@@ -226,7 +226,7 @@
 				memcpy(&in.s_addr, tmp + 4, 4);
 				ip = inet_ntoa(in);
 				if(ip)
-					strcpy(nattype.publicip, ip);
+					g_strlcpy(nattype.publicip, ip, sizeof(nattype.publicip));
 			}
 
 			tmp += ntohs(attrib->len);
--- a/libpurple/upnp.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/upnp.c	Fri Aug 12 21:41:34 2011 +0000
@@ -535,7 +535,7 @@
 		dd->retry_count++;
 		purple_upnp_discover_send_broadcast(dd);
 	} else {
-		if (dd->fd)
+		if (dd->fd != -1)
 			close(dd->fd);
 
 		control_info.status = PURPLE_UPNP_STATUS_UNABLE_TO_DISCOVER;
@@ -662,7 +662,7 @@
 	}
 
 	/* Set up the sockets */
-	sock = socket(AF_INET, SOCK_DGRAM, 0);
+	dd->fd = sock = socket(AF_INET, SOCK_DGRAM, 0);
 	if(sock == -1) {
 		purple_debug_error("upnp",
 			"purple_upnp_discover(): Failed In sock creation\n");
@@ -672,8 +672,6 @@
 		return;
 	}
 
-	dd->fd = sock;
-
 	/* TODO: Non-blocking! */
 	if((hp = gethostbyname(HTTPMU_HOST_ADDRESS)) == NULL) {
 		purple_debug_error("upnp",
@@ -820,7 +818,7 @@
 static void
 looked_up_internal_ip_cb(gpointer data, gint source, const gchar *error_message)
 {
-	if (source) {
+	if (source != -1) {
 		strncpy(control_info.internalip,
 			purple_network_get_local_system_ip(source),
 			sizeof(control_info.internalip));
--- a/libpurple/win32/libc_interface.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/libpurple/win32/libc_interface.c	Fri Aug 12 21:41:34 2011 +0000
@@ -982,7 +982,7 @@
 		if (strcmp(tzname, zonename) == 0)
 		{
 			/* Matched zone */
-			strcpy(localtzname, keyname);
+			g_strlcpy(localtzname, keyname, sizeof(localtzname));
 			RegCloseKey(key);
 			break;
 		}
@@ -997,7 +997,7 @@
 		if (strcmp(tzname, zonename) == 0)
 		{
 			/* Matched DST zone */
-			strcpy(localtzname, keyname);
+			g_strlcpy(localtzname, keyname, sizeof(localtzname));
 			RegCloseKey(key);
 			break;
 		}
--- a/pidgin/gtkblist.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/pidgin/gtkblist.c	Fri Aug 12 21:41:34 2011 +0000
@@ -3647,6 +3647,7 @@
 	{ N_("/Help/_Build Information"), NULL, pidgin_dialogs_buildinfo, 0, "<Item>", NULL },
 	{ N_("/Help/_Debug Window"), NULL, toggle_debug, 0, "<Item>", NULL },
 	{ N_("/Help/De_veloper Information"), NULL, pidgin_dialogs_developers, 0, "<Item>", NULL },
+	{ N_("/Help/_Plugin Information"), NULL, pidgin_dialogs_plugins_info, 0, "<Item>", NULL },
 	{ N_("/Help/_Translator Information"), NULL, pidgin_dialogs_translators, 0, "<Item>", NULL },
 	{ "/Help/sep2", NULL, NULL, 0, "<Separator>", NULL },
 	{ N_("/Help/_About"), NULL, pidgin_dialogs_about, 4,  "<StockItem>", GTK_STOCK_ABOUT },
--- a/pidgin/gtkdialogs.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/pidgin/gtkdialogs.c	Fri Aug 12 21:41:34 2011 +0000
@@ -31,6 +31,7 @@
 
 #include "debug.h"
 #include "notify.h"
+#include "plugin.h"
 #include "prpl.h"
 #include "request.h"
 #include "util.h"
@@ -787,6 +788,52 @@
 	g_free(tmp);
 }
 
+void pidgin_dialogs_plugins_info(void)
+{
+	GString *str;
+	GList *l = NULL;
+	PurplePlugin *plugin = NULL;
+	char *title = g_strdup_printf(_("%s Plugin Information"), PIDGIN_NAME);
+	char *pname = NULL, *pauthor = NULL;
+	const char *pver, *pwebsite, *pid;
+	gboolean ploaded, punloadable;
+	static GtkWidget *plugins_info = NULL;
+
+	str = g_string_sized_new(4096);
+
+	g_string_append_printf(str, "<FONT SIZE=\"4\">%s</FONT><BR/>",
+			_("Plugin Information"));
+
+	for(l = purple_plugins_get_all(); l; l = l->next) {
+		plugin = (PurplePlugin *)l->data;
+
+		pname = g_markup_escape_text(purple_plugin_get_name(plugin), -1);
+		pauthor = g_markup_escape_text(purple_plugin_get_author(plugin), -1);
+		pver = purple_plugin_get_version(plugin);
+		pwebsite = purple_plugin_get_homepage(plugin);
+		pid = purple_plugin_get_id(plugin);
+		punloadable = purple_plugin_is_unloadable(plugin);
+		ploaded = purple_plugin_is_loaded(plugin);
+
+		g_string_append_printf(str,
+				"<FONT SIZE=\"3\"><B>%s</B></FONT><BR/><FONT SIZE=\"2\">"
+				"\t<B>Author:</B> %s<BR/>\t<B>Version:</B> %s<BR/>"
+				"\t<B>Website:</B> %s<BR/>\t<B>ID String:</B> %s<BR/>"
+				"\t<B>Loadable:</B> %s<BR/>\t<B>Loaded:</B> %s<BR/>"
+				"<BR/></FONT>", pname, pauthor ? pauthor : "(null)",
+				pver, pwebsite, pid,
+				punloadable ? "<FONT COLOR=\"#FF0000\"><B>No</B></FONT>" : "Yes",
+				ploaded ? "Yes" : "No");
+	}
+
+	plugins_info = pidgin_build_help_dialog(title, "plugins_info", str);
+	g_signal_connect(G_OBJECT(plugins_info), "destroy",
+			G_CALLBACK(gtk_widget_destroyed), &plugins_info);
+	g_free(title);
+	g_free(pname);
+	g_free(pauthor);
+}
+
 static void
 pidgin_dialogs_im_cb(gpointer data, PurpleRequestFields *fields)
 {
--- a/pidgin/gtkdialogs.h	Sat Jul 09 20:10:36 2011 +0000
+++ b/pidgin/gtkdialogs.h	Fri Aug 12 21:41:34 2011 +0000
@@ -36,6 +36,7 @@
 void pidgin_dialogs_buildinfo(void);
 void pidgin_dialogs_developers(void);
 void pidgin_dialogs_translators(void);
+void pidgin_dialogs_plugins_info(void);
 void pidgin_dialogs_im(void);
 void pidgin_dialogs_im_with_user(PurpleAccount *, const char *);
 void pidgin_dialogs_info(void);
--- a/pidgin/gtkmedia.c	Sat Jul 09 20:10:36 2011 +0000
+++ b/pidgin/gtkmedia.c	Fri Aug 12 21:41:34 2011 +0000
@@ -538,12 +538,20 @@
 	GdkWindow *window = NULL;
 
 	if (data->participant == NULL)
+#if GTK_CHECK_VERSION(2, 14, 0)
 		window = gtk_widget_get_window(priv->local_video);
+#else
+		window = (priv->local_video)->window;
+#endif
 	else {
 		GtkWidget *widget = pidgin_media_get_widget(data->gtkmedia,
 				data->session_id, data->participant);
 		if (widget)
+#if GTK_CHECK_VERSION(2, 14, 0)
 			window = gtk_widget_get_window(widget);
+#else
+			window = widget->window;
+#endif
 	}
 
 	if (window) {
--- a/po/ca.po	Sat Jul 09 20:10:36 2011 +0000
+++ b/po/ca.po	Fri Aug 12 21:41:34 2011 +0000
@@ -9,32 +9,30 @@
 # This file is distributed under the same license as the Pidgin package.
 #
 # There were translation notes here by Xan, (look in older CVS revisions),
-# those notes have been replaced by the guidelines of Softcatalà:
-# http://www.softcatala.org/projectes/eines/guiaestil/guiaestil.htm
-# And the translation of related terms is here:
-# http://www.softcatala.org/projectes/eines/recull/recull.htm
-# We also use the officialy accepted neologisms from Termcat:
-# http://www.termcat.net/cercaterm/
+# those notes have been replaced by the guidelines [1] and the list of
+# computer related terms [2] of Softcatalà. We also use the officialy
+# accepted neologisms from Termcat [3].
 #
 # En Xan havia escrit uns apunts quant a la traducció (mireu versions antigues
-# al CVS), els apunts s'han substituït per la guia d'estil de Softcatalà:
-# http://www.softcatala.org/projectes/eines/guiaestil/guiaestil.htm
-# També es fa servir el recull de termes de softcatalà per a la terminologia:
-# http://www.softcatala.org/projectes/eines/recull/recull.htm
-# així com les resolucions del Termcat quant als neologismes (que tenen
-# preferència en cas de contradicció amb el recull de Softcatalà):
-# http://www.termcat.net/cercaterm/
+# al CVS), els apunts s'han substituït per la guia d'estil [1] i el recull de
+# termes [2] de Softcatalà, així com les resolucions del Termcat [3] quant als
+# neologismes (que tenen preferència en cas de contradicció amb el recull de
+# Softcatalà).
 #
 # NOTE: adjectives in catalan go [almost] always to the end, for instance:
 # NOTA: els adjectius en català acostumen a anar al final, per exemple:
 #  "New file" --> "Fitxer nou"
 #
+# [1] http://www.softcatala.org/wiki/Guia_d'estil/Guia_2010
+# [2] http://www.softcatala.org/recull.html
+# [3] http://www.termcat.net/cercaterm/
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: Pidgin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-05-07 10:31+0200\n"
-"PO-Revision-Date: 2011-05-07 10:48+0200\n"
+"POT-Creation-Date: 2011-08-11 20:14+0200\n"
+"PO-Revision-Date: 2011-08-11 20:26+0200\n"
 "Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
 "Language-Team: Catalan <tradgnome@softcatala.net>\n"
 "Language: ca\n"
@@ -1707,6 +1705,7 @@
 msgid "Unknown"
 msgstr "Desconegut"
 
+#. Changing this string?  Look in add_purple_buddy_to_groups
 msgid "Buddies"
 msgstr "Amics"
 
@@ -4778,8 +4777,8 @@
 msgid "invite &lt;user&gt; [message]:  Invite a user to the room."
 msgstr "invite &lt;usuari&gt; [sala]:  convida un usuari a la sala."
 
-msgid "join: &lt;room&gt; [password]:  Join a chat on this server."
-msgstr "join: &lt;sala&gt; [contrasenya]:  entra en un xat d'aquest servidor."
+msgid "join: &lt;room[@server]&gt; [password]:  Join a chat."
+msgstr "join: &lt;sala[@servidor]&gt; [contrasenya]:  entra en un xat."
 
 msgid "kick &lt;user&gt; [reason]:  Kick a user from the room."
 msgstr "kick &lt;usuari&gt; [motiu]:  fa fora de la sala un usuari."
@@ -6344,12 +6343,16 @@
 msgstr "On visc"
 
 #, c-format
-msgid "You have %i suggested friends."
-msgstr "Teniu %i suggeriments d'amics."
-
-#, c-format
-msgid "We found %i contacts that match your search."
-msgstr "Hem trobat %i contactes que coincideixen amb la cerca."
+msgid "You have %i suggested friend."
+msgid_plural "You have %i suggested friends."
+msgstr[0] "Se us ha suggerit %i amic."
+msgstr[1] "Se us han suggerit %i amics."
+
+#, c-format
+msgid "We found %i contact that matches your search."
+msgid_plural "We found %i contacts that match your search."
+msgstr[0] "S'ha trobat %i contacte que coincideix amb la cerca."
+msgstr[1] "S'han trobat %i contactes que coincideixen amb la cerca."
 
 #. we must have lost the connection, so terminate it so that we can reconnect
 msgid "We have lost the connection to MXit. Please reconnect."
@@ -11076,6 +11079,9 @@
 msgid "/Help/De_veloper Information"
 msgstr "/Ajuda/Informació sobre els d_esenvolupadors"
 
+msgid "/Help/_Plugin Information"
+msgstr "/Ajuda/Informació sobre els _controladors"
+
 msgid "/Help/_Translator Information"
 msgstr "/Ajuda/Informació sobre els _traductors"
 
@@ -11367,7 +11373,7 @@
 msgstr "Aconsegueix el missatge d'absència"
 
 msgid "Last Said"
-msgstr "El darrer que es digué"
+msgstr "El darrer que digué"
 
 msgid "Unable to save icon file to disk."
 msgstr "No s'ha pogut desar el fitxer de la icona al disc."
@@ -11702,10 +11708,6 @@
 msgid "artist"
 msgstr "artista"
 
-#. feel free to not translate this
-msgid "Ka-Hing Cheung"
-msgstr "Ka-Hing Cheung"
-
 msgid "voice and video"
 msgstr "veu i vídeo"
 
@@ -11718,6 +11720,10 @@
 msgid "win32 port"
 msgstr "adaptació a win32"
 
+#. feel free to not translate this
+msgid "Ka-Hing Cheung"
+msgstr "Ka-Hing Cheung"
+
 msgid "maintainer"
 msgstr "mantenidor"
 
@@ -11838,6 +11844,9 @@
 msgid "Hindi"
 msgstr "Hindi"
 
+msgid "Croatian"
+msgstr "Croat"
+
 msgid "Hungarian"
 msgstr "Hongarès"
 
@@ -12085,6 +12094,13 @@
 msgid "%s Translator Information"
 msgstr "Informació sobre els traductors del %s"
 
+#, c-format
+msgid "%s Plugin Information"
+msgstr "Informació sobre el connector %s"
+
+msgid "Plugin Information"
+msgstr "Informació sobre el connector"
+
 msgid "_Name"
 msgstr "_Nom"
 
@@ -13062,6 +13078,13 @@
 msgid "F_lash window when IMs are received"
 msgstr "_Fes que la finestra faci un flaix quan hi arribin missatges"
 
+msgid "Resize incoming custom smileys"
+msgstr "Redimensiona les emoticones personalitzades rebudes"
+
+# He hagut de ser una mica flexible per mantenir-ho "curt"
+msgid "Maximum size:"
+msgstr "Mida màxima:"
+
 msgid "Minimum input area height in lines:"
 msgstr "Alçada mínima en línies de l'àrea d'entrada:"
 
@@ -13132,6 +13155,9 @@
 msgid "_UDP Port:"
 msgstr "Port _UDP:"
 
+msgid "T_CP Port:"
+msgstr "Port _TCP:"
+
 msgid "Use_rname:"
 msgstr "Nom d'_usuari:"
 
@@ -15514,9 +15540,6 @@
 #~ msgid "<b>IP</b>: %s<br>\n"
 #~ msgstr "<b>IP</b>: %s<br>\n"
 
-#~ msgid "Login Information"
-#~ msgstr "Informació de la connexió"
-
 #~ msgid "<p><b>Original Author</b>:<br>\n"
 #~ msgstr "<p><b>Autor original</b>:<br>\n"
 
--- a/po/de.po	Sat Jul 09 20:10:36 2011 +0000
+++ b/po/de.po	Fri Aug 12 21:41:34 2011 +0000
@@ -11,8 +11,8 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-06-21 09:12+0200\n"
-"PO-Revision-Date: 2011-06-21 09:11+0200\n"
+"POT-Creation-Date: 2011-08-11 10:27+0200\n"
+"PO-Revision-Date: 2011-08-11 10:12+0200\n"
 "Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
 "Language-Team: German <de@li.org>\n"
 "Language: de\n"
@@ -1959,7 +1959,7 @@
 msgstr "Unbekannter Grund"
 
 msgid "Aborting DNS lookup in Tor Proxy mode."
-msgstr "DNS-Anfrage im Tor-Proxy-Modus abgebrochen"
+msgstr "DNS-Anfrage im Tor-Proxy-Modus abgebrochen."
 
 #, c-format
 msgid ""
@@ -4778,8 +4778,8 @@
 msgstr ""
 "invite &lt;Benutzer&gt; [Nachricht]:  Lade einen Benutzer in den Raum ein."
 
-msgid "join: &lt;room&gt; [password]:  Join a chat on this server."
-msgstr "join: &lt;Raum&gt; [Passwort]:  Betrete einen Chat auf diesem Server."
+msgid "join: &lt;room[@server]&gt; [password]:  Join a chat."
+msgstr "join: &lt;Raum[@Server]&gt; [Passwort]:  Betrete einen Chat."
 
 msgid "kick &lt;user&gt; [reason]:  Kick a user from the room."
 msgstr "kick &lt;Benutzer&gt; [Grund]:  Kickt einen Benutzer aus dem Raum."
@@ -11134,6 +11134,9 @@
 msgid "/Help/De_veloper Information"
 msgstr "/Hilfe/_Entwickler-Informationen"
 
+msgid "/Help/_Plugin Information"
+msgstr "/Hilfe/_Plugin-Informationen"
+
 msgid "/Help/_Translator Information"
 msgstr "/Hilfe/Über_setzer-Informationen"
 
@@ -12149,6 +12152,13 @@
 msgid "%s Translator Information"
 msgstr "%s-Übersetzer-Informationen"
 
+#, c-format
+msgid "%s Plugin Information"
+msgstr "%s Plugin-Informationen"
+
+msgid "Plugin Information"
+msgstr "Plugin-Informationen"
+
 msgid "_Name"
 msgstr "_Name"
 
@@ -12750,7 +12760,7 @@
 
 #, c-format
 msgid "Exiting because another libpurple client is already running.\n"
-msgstr "Wird geschlossen, da bereits ein anderer libpurple-Client läuft\n"
+msgstr "Wird geschlossen, da bereits ein anderer libpurple-Client läuft.\n"
 
 msgid "_Media"
 msgstr "_Medien"
@@ -13116,6 +13126,12 @@
 msgid "F_lash window when IMs are received"
 msgstr "Fenster b_linkt, wenn IM-Nachrichten empfangen werden"
 
+msgid "Resize incoming custom smileys"
+msgstr "Erhaltene benutzerdefinierte Smileys skalieren"
+
+msgid "Maximum size:"
+msgstr "Maximale Größe:"
+
 msgid "Minimum input area height in lines:"
 msgstr "Minimale Höhe des Eingabefeldes in Zeilen:"