changeset 31892:a330d1187fa7

merge of 'abe467cd836e25b339d81461c056f6289d88b2f0' and 'c13c35c07888cc787731bd388eb99734c41f67ef'
author pieter.loubser@mxit.com
date Tue, 16 Aug 2011 05:38:01 +0000
parents 98ae4b8b592f (current diff) 437a45076bf3 (diff)
children 04ce276d941a
files libpurple/protocols/mxit/cipher.c
diffstat 23 files changed, 204 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Aug 11 15:01:34 2011 +0000
+++ b/ChangeLog	Tue Aug 16 05:38:01 2011 +0000
@@ -16,6 +16,9 @@
 	  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)
--- a/libpurple/dnssrv.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/dnssrv.c	Tue Aug 16 05:38:01 2011 +0000
@@ -428,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;
--- a/libpurple/log.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/log.c	Tue Aug 16 05:38:01 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	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/plugins/filectl.c	Tue Aug 16 05:38:01 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/protocols/mxit/actions.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/actions.c	Tue Aug 16 05:38:01 2011 +0000
@@ -84,13 +84,6 @@
 		g_string_append( attributes, attrib );
 		acount++;
 
-		/* force hidden if disabled */
-		if ( profile->hidden == FALSE ) {
-			g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_HIDENUMBER, CP_PROFILE_TYPE_BOOL, "1" );
-			g_string_append( attributes, attrib );
-			acount++;
-		}
-
 		/* update birthday */
 		g_strlcpy( profile->birthday, bday, sizeof( profile->birthday ) );
 		g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_BIRTHDATE, CP_PROFILE_TYPE_UTF8, profile->birthday );
--- a/libpurple/protocols/mxit/cipher.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.c	Tue Aug 16 05:38:01 2011 +0000
@@ -1,7 +1,7 @@
 /*
  *					MXit Protocol libPurple Plugin
  *
- *					-- user password encryption --
+ *						-- encryption --
  *
  *				Pieter Loubser	<libpurple@mxit.com>
  *
@@ -31,31 +31,69 @@
 #include	"aes.h"
 
 
-/* password encryption */
+/* encryption */
 #define		INITIAL_KEY		"6170383452343567"
 #define		SECRET_HEADER	"<mxit/>"
 #define		ENCRYPT_HEADER	"<mxitencrypted ver=\"5.2\"/>"
 
 
 /*------------------------------------------------------------------------
- * Pad the secret data using ISO10126 Padding.
+ * Add ISO10126 Padding to the data.
  *
- *  @param secret	The data to pad (caller must ensure buffer has enough space for padding)
- *  @return			The total number of 128-bit blocks used
+ *  @param data		The data to pad.
  */
-static int pad_secret_data( char* secret )
+static void padding_add( GString* data )
+{
+	unsigned int blocks = ( data->len / 16 ) + 1;
+	unsigned int padding = ( blocks * 16 ) - data->len;
+
+	g_string_set_size( data, blocks * 16 );
+	data->str[data->len - 1] = padding;
+}
+
+
+/*------------------------------------------------------------------------
+ * Remove ISO10126 Padding from the data.
+ *
+ *  @param data		The data from which to remove padding.
+ */
+static void padding_remove( GString* data )
 {
-	int		blocks	= 0;
-	int		passlen;
-	int		padding;
+	unsigned int padding;
+
+	if ( data->len == 0 )
+		return;
+
+	padding = data->str[data->len - 1];
+	g_string_truncate( data, data->len - padding );
+}
+
 
-	passlen = strlen( secret );
-	blocks = ( passlen / 16 ) + 1;
-	padding = ( blocks * 16 ) - passlen;
-	secret[passlen] = 0x50;
-	secret[(blocks * 16) - 1] = padding;
+/*------------------------------------------------------------------------
+ * Generate the Transport-Layer crypto key.
+ *  (Note: this function is not-thread safe)
+ *
+ *  @param session	The MXit Session object
+ *	@return			The transport-layer crypto key.
+ */
+static char* transport_layer_key( struct MXitSession* session )
+{
+	static char	key[16 + 1];
+	int			passlen			= strlen( session->acc->password );
 
-	return blocks;
+	/* initialize with initial key */
+	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
+
+	/* client key (8 bytes) */
+	memcpy( key, session->clientkey, strlen( session->clientkey ) );
+
+	/* add last 8 characters of the PIN (no padding if less characters) */
+	if ( passlen <= 8 )
+		memcpy( key + 8, session->acc->password, passlen );
+	else
+		memcpy( key + 8, session->acc->password + ( passlen - 8 ), 8 );
+
+	return key;
 }
 
 
@@ -68,21 +106,16 @@
  */
 char* mxit_encrypt_password( struct MXitSession* session )
 {
-	char		key[64];
+	char		key[16 + 1];
 	char		exkey[512];
-	char		pass[64];
+	GString*	pass			= NULL;
 	char		encrypted[64];
 	char*		base64;
-	int			blocks;
-	int			size;
 	int			i;
 
 	purple_debug_info( MXIT_PLUGIN_ID, "mxit_encrypt_password\n" );
 
 	memset( encrypted, 0x00, sizeof( encrypted ) );
-	memset( exkey, 0x00, sizeof( exkey ) );
-	memset( pass, 0x58, sizeof( pass ) );
-	pass[sizeof( pass ) - 1] = '\0';
 
 	/* build the custom AES encryption key */
 	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
@@ -102,7 +135,9 @@
 		Encrypt( (unsigned char*) pass + i, (unsigned char*) exkey, (unsigned char*) encrypted + i );
 
 	/* now base64 encode the encrypted password */
-	base64 = purple_base64_encode( (unsigned char*) encrypted, size );
+	base64 = purple_base64_encode( (unsigned char*) encrypted, pass->len );
+
+	g_string_free( pass, TRUE );
 
 	return base64;
 }
--- a/libpurple/protocols/mxit/cipher.h	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.h	Tue Aug 16 05:38:01 2011 +0000
@@ -1,7 +1,7 @@
 /*
  *					MXit Protocol libPurple Plugin
  *
- *					-- user password encryption --
+ *						-- encryption --
  *
  *				Pieter Loubser	<libpurple@mxit.com>
  *
@@ -33,6 +33,6 @@
 char* mxit_encrypt_password( struct MXitSession* session );
 
 char* mxit_decrypt_message( struct MXitSession* session, char* message );
-
+char* mxit_encrypt_message( struct MXitSession* session, char* message );
 
 #endif		/* _MXIT_CIPHER_H_ */
--- a/libpurple/protocols/mxit/formcmds.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/formcmds.c	Tue Aug 16 05:38:01 2011 +0000
@@ -253,8 +253,8 @@
 
 /*------------------------------------------------------------------------
  * Process a Reply MXit command.
- *  [::op=cmd|type=reply|replymsg=back|selmsg=b) Back|id=12345:]
- *  [::op=cmd|nm=rep|type=reply|replymsg=back|selmsg=b) Back|id=12345:]
+ *  [::op=cmd|type=reply|replymsg=back|selmsg=b) Back|displaymsg=Processing|id=12345:]
+ *  [::op=cmd|nm=rep|type=reply|replymsg=back|selmsg=b) Back|displaymsg=Processing|id=12345:]
  *
  *  @param mx			The received message data object
  *  @param hash			The MXit command <key,value> map
@@ -265,22 +265,26 @@
 	char* selmsg;
 	char* nm;
 
-	selmsg = g_hash_table_lookup(hash, "selmsg");			/* find the selection message */
-	replymsg = g_hash_table_lookup(hash, "replymsg");		/* find the reply message */
+	selmsg = g_hash_table_lookup(hash, "selmsg");			/* selection message */
+	replymsg = g_hash_table_lookup(hash, "replymsg");		/* reply message */
 	nm = g_hash_table_lookup(hash, "nm");					/* name parameter */
-	if ((selmsg) && (replymsg) && (nm)) {
+
+	if ((selmsg == NULL) || (replymsg == NULL))
+		return;		/* these parameters are required */
+
+	if (nm) {		/* indicates response must be a structured response */
 		gchar*	seltext = g_markup_escape_text(purple_url_decode(selmsg), -1);
-		gchar*	replycmd = g_strdup_printf("::type=reply|nm=%s|res=%s|err=0:", nm, replymsg);
+		gchar*	replycmd = g_strdup_printf("type=reply|nm=%s|res=%s|err=0", nm, replymsg);
 
-		mxit_add_html_link( mx, replycmd, seltext );
+		mxit_add_html_link( mx, replycmd, TRUE, seltext );
 
 		g_free(seltext);
 		g_free(replycmd);
 	}
-	else if ((selmsg) && (replymsg)) {
+	else {
 		gchar*	seltext = g_markup_escape_text(purple_url_decode(selmsg), -1);
 
-		mxit_add_html_link( mx, purple_url_decode(replymsg), seltext );
+		mxit_add_html_link( mx, purple_url_decode(replymsg), FALSE, seltext );
 
 		g_free(seltext);
 	}
@@ -317,6 +321,7 @@
 
 /*------------------------------------------------------------------------
  * Process an inline image MXit command.
+ *  [::op=img|dat=ASDF23408asdflkj2309flkjsadf%3d%3d|algn=1|w=120|h=12|t=100|replymsg=text:]
  *
  *  @param mx			The received message data object
  *  @param hash			The MXit command <key,value> map
@@ -372,7 +377,7 @@
 	reply = g_hash_table_lookup(hash, "replymsg");
 	if (reply) {
 		g_string_append_printf(msg, "\n");
-		mxit_add_html_link(mx, reply, _( "click here" ));
+		mxit_add_html_link(mx, reply, FALSE, _( "click here" ));
 	}
 }
 
--- a/libpurple/protocols/mxit/markup.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/markup.c	Tue Aug 16 05:38:01 2011 +0000
@@ -124,10 +124,11 @@
  * Adds a link to a message
  *
  *  @param mx				The Markup message object
- *	@param linkname			This is the what will be returned when the link gets clicked
- *	@param displayname		This is the name for the link which will be displayed in the UI
+ *	@param replydata		This is the what will be returned when the link gets clicked
+ *	@param isStructured		Indicates that the reply is a structured reply
+ *	@param displaytext		This is the text for the link which will be displayed in the UI
  */
-void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char* displayname )
+void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext )
 {
 #ifdef	MXIT_LINK_CLICK
 	char	retstr[256];
@@ -135,15 +136,24 @@
 	char	link[256];
 	int		len;
 
-	len = g_snprintf( retstr, sizeof( retstr ), "%s|%s|%s|%s|%s", MXIT_LINK_KEY, purple_account_get_username( mx->session->acc ),
-											purple_account_get_protocol_id( mx->session->acc ), mx->from, linkname );
+	/*
+	 * The link content is encoded as follows:
+	 *  MXIT_LINK_KEY | ACCOUNT_USER | ACCOUNT_PROTO | REPLY_TO | REPLY_FORMAT | REPLY_DATA
+	 */
+	len = g_snprintf( retstr, sizeof( retstr ), "%s|%s|%s|%s|%i|%s",
+			MXIT_LINK_KEY,
+			purple_account_get_username( mx->session->acc ),
+			purple_account_get_protocol_id( mx->session->acc ),
+			mx->from,
+			isStructured ? 1 : 0,
+			replydata );
 	retstr64 = purple_base64_encode( (const unsigned char*) retstr, len );
 	g_snprintf( link, sizeof( link ), "%s%s", MXIT_LINK_PREFIX, retstr64 );
 	g_free( retstr64 );
 
-	g_string_append_printf( mx->msg, "<a href=\"%s\">%s</a>", link, displayname );
+	g_string_append_printf( mx->msg, "<a href=\"%s\">%s</a>", link, displaytext );
 #else
-	g_string_append_printf( mx->msg, "<b>%s</b>", linkname );
+	g_string_append_printf( mx->msg, "<b>%s</b>", replydata );
 #endif
 }
 
@@ -824,7 +834,7 @@
 					if ( ch ) {
 						/* end found */
 						*ch = '\0';
-						mxit_add_html_link( mx, &message[i + 1], &message[i + 1] );
+						mxit_add_html_link( mx, &message[i + 1], FALSE, &message[i + 1] );
 						*ch = '$';
 						i += ( ch - &message[i + 1] ) + 1;
 					}
--- a/libpurple/protocols/mxit/markup.h	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/markup.h	Tue Aug 16 05:38:01 2011 +0000
@@ -31,7 +31,7 @@
 
 void mxit_parse_markup( struct RXMsgData* mx, char* message, int len, short msgtype, int msgflags );
 char* mxit_convert_markup_tx( const char* message, int* msgtype );
-void mxit_add_html_link( struct RXMsgData* mx, const char* linkname, const char* displayname );
+void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext );
 void mxit_show_message( struct RXMsgData* mx );
 
 void mxit_free_emoticon_cache( struct MXitSession* session );
--- a/libpurple/protocols/mxit/multimx.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/multimx.c	Tue Aug 16 05:38:01 2011 +0000
@@ -277,7 +277,11 @@
 	GHashTable *components;
 	struct multimx* multimx = NULL;
 
-	purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s' by '%s'\n", contact->alias, creator);
+	purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s' (roomid='%s') by '%s'\n", contact->alias, contact->username, creator);
+
+	/* Check if the room already exists (ie, already joined or invite pending) */
+	if (find_room_by_username(session, contact->username) != NULL)
+		return;
 
 	/* Create a new room */
 	multimx = room_create(session, contact->username, contact->alias, STATE_INVITED);
@@ -307,7 +311,7 @@
 	multimx = find_room_by_username(session, contact->username);
 	if (multimx == NULL) {
 		multimx = room_create(session, contact->username, contact->alias, TRUE);
-		}
+	}
 	else if (multimx->state == STATE_INVITED) {
 		/* After successfully accepting an invitation */
 		multimx->state = STATE_JOINED;
--- a/libpurple/protocols/mxit/mxit.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/mxit.c	Tue Aug 16 05:38:01 2011 +0000
@@ -75,10 +75,10 @@
 	link = (gchar*) purple_base64_decode( link64 + strlen( MXIT_LINK_PREFIX ), &len );
 	purple_debug_info( MXIT_PLUGIN_ID, "Clicked Link: '%s'\n", link );
 
-	parts = g_strsplit( link, "|", 5 );
+	parts = g_strsplit( link, "|", 6 );
 
 	/* check if this is a valid mxit link */
-	if ( ( !parts ) || ( !parts[0] ) || ( !parts[1] ) || ( !parts[2] ) || ( !parts[3] ) || ( !parts[4] ) ) {
+	if ( ( !parts ) || ( !parts[0] ) || ( !parts[1] ) || ( !parts[2] ) || ( !parts[3] ) || ( !parts[4] ) || ( !parts[5] ) ) {
 		/* this is not for us */
 		goto skip;
 	}
@@ -96,10 +96,10 @@
 		goto skip;
 
 	/* determine if it's a command-response to send */
-	is_command = g_str_has_prefix( parts[4], "::type=reply|" );
+	is_command = ( atoi( parts[4] ) == 1 );
 
 	/* send click message back to MXit */
-	mxit_send_message( con->proto_data, parts[3], parts[4], FALSE, is_command );
+	mxit_send_message( con->proto_data, parts[3], parts[5], FALSE, is_command );
 
 	g_free( link );
 	link = NULL;
@@ -309,19 +309,18 @@
  */
 char* mxit_status_text( PurpleBuddy* buddy )
 {
+	char* text = NULL;
 	struct contact*	contact = purple_buddy_get_protocol_data(buddy);
 
 	if ( !contact )
 		return NULL;
 
-	if ( contact->statusMsg ) {
-		/* status message */
-		return g_strdup( contact-> statusMsg );
-	}
-	else {
-		/* mood */
-		return g_strdup( mxit_convert_mood_to_name( contact->mood ) );
-	}
+	if ( contact->statusMsg )							/* status message */
+		text = g_strdup( contact-> statusMsg );
+	else if ( contact->mood != MXIT_MOOD_NONE )			/* mood */
+		text = g_strdup( mxit_convert_mood_to_name( contact->mood ) );
+
+	return text;
 }
 
 
@@ -358,10 +357,6 @@
 	/* rejection message */
 	if ( ( contact->subtype == MXIT_SUBTYPE_REJECTED ) && ( contact->msg != NULL ) )
 		purple_notify_user_info_add_pair( info, _( "Rejection Message" ), contact->msg );
-
-	/* hidden number */
-	if ( contact->flags & MXIT_CFLAG_HIDDEN )
-		purple_notify_user_info_add_pair( info, _( "Hidden Number" ), _( "Yes" ) );
 }
 
 
@@ -659,6 +654,18 @@
 	return m;
 }
 
+
+/*------------------------------------------------------------------------
+ * Return Chat-room default settings.
+ *
+ *  @return		Chat defaults list
+ */
+static GHashTable *mxit_chat_info_defaults(PurpleConnection *gc, const char *chat_name)
+{
+    return g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
+}
+
+
 /*========================================================================================================================*/
 
 static PurplePluginProtocolInfo proto_info = {
@@ -680,7 +687,7 @@
 	mxit_status_types,		/* status types				[roster.c] */
 	mxit_blist_menu,		/* blist_node_menu */
 	mxit_chat_info,			/* chat_info				[multimx.c] */
-	NULL,					/* chat_info_defaults */
+	mxit_chat_info_defaults,/* chat_info_defaults */
 	mxit_login,				/* login					[login.c] */
 	mxit_close,				/* close */
 	mxit_send_im,			/* send_im */
--- a/libpurple/protocols/mxit/profile.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/profile.c	Tue Aug 16 05:38:01 2011 +0000
@@ -215,9 +215,6 @@
 
 		/* subscription type */
 		purple_notify_user_info_add_pair( info, _( "Subscription" ), mxit_convert_subtype_to_name( contact->subtype ) );
-
-		/* hidden number */
-		purple_notify_user_info_add_pair( info, _( "Hidden Number" ), ( contact->flags & MXIT_CFLAG_HIDDEN ) ? _( "Yes" ) : _( "No" ) );
 	}
 	else {
 		/* this is an invite */
--- a/libpurple/protocols/mxit/profile.h	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/profile.h	Tue Aug 16 05:38:01 2011 +0000
@@ -50,7 +50,6 @@
 
 	int			flags;								/* user's profile flags */
 	gint64		lastonline;							/* user's last-online timestamp */
-	gboolean	hidden;								/* set if the user's mxitid should remain hidden */
 };
 
 struct MXitSession;
--- a/libpurple/protocols/mxit/protocol.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/protocol.c	Tue Aug 16 05:38:01 2011 +0000
@@ -1448,7 +1448,7 @@
 	PurpleStatus*	status;
 	int				presence;
 	const char*		statusmsg;
-	const char*		profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_HIDENUMBER, CP_PROFILE_FULLNAME,
+	const char*		profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME,
 									CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL,
 									CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_FLAGS };
 
@@ -1825,10 +1825,6 @@
 			/* gender */
 			profile->male = ( fvalue[0] == '1' );
 		}
-		else if ( strcmp( CP_PROFILE_HIDENUMBER, fname ) == 0 ) {
-			/* hide number */
-			profile->hidden = ( fvalue[0] == '1' );
-		}
 		else if ( strcmp( CP_PROFILE_FULLNAME, fname ) == 0 ) {
 			/* nickname */
 			g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) );
--- a/libpurple/protocols/mxit/protocol.h	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/protocol.h	Tue Aug 16 05:38:01 2011 +0000
@@ -182,7 +182,7 @@
 /* extended profile attribute fields */
 #define		CP_PROFILE_BIRTHDATE	"birthdate"				/* Birthdate (String - ISO 8601 format) */
 #define		CP_PROFILE_GENDER		"gender"				/* Gender (Boolean - 0=female, 1=male) */
-#define		CP_PROFILE_HIDENUMBER	"hidenumber"			/* Hide Number (Boolean - 0=false, 1=true) */
+// #define		CP_PROFILE_HIDENUMBER	"hidenumber"			/* Hide Number (Boolean - 0=false, 1=true) (DEPRECATED) */
 #define		CP_PROFILE_FULLNAME		"fullname"				/* Fullname (UTF8 String) */
 #define		CP_PROFILE_STATUS		"statusmsg"				/* Status Message (UTF8 String) */
 #define		CP_PROFILE_PREVSTATUS	"prevstatusmsgs"		/* Previous Status Messages (UTF8 String) */
--- a/libpurple/protocols/mxit/roster.h	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/roster.h	Tue Aug 16 05:38:01 2011 +0000
@@ -74,7 +74,7 @@
 
 
 /* MXit contact flags */
-#define		MXIT_CFLAG_HIDDEN			0x02
+//#define		MXIT_CFLAG_HIDDEN			0x02		/* (DEPRECATED) */
 #define		MXIT_CFLAG_GATEWAY			0x04
 #define		MXIT_CFLAG_FOCUS_SEND_BLANK	0x20000
 
--- a/libpurple/protocols/mxit/voicevideo.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/mxit/voicevideo.c	Tue Aug 16 05:38:01 2011 +0000
@@ -95,7 +95,7 @@
 
 	/* and only when they're online */
 	if (contact->presence == MXIT_PRESENCE_OFFLINE)
-		return MXIT_PRESENCE_OFFLINE;
+		return PURPLE_MEDIA_CAPS_NONE;
 
 	/* they support voice-only */
 	if (contact->capabilities & MXIT_PFLAG_VOICE)
--- a/libpurple/protocols/oscar/oscar.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Tue Aug 16 05:38:01 2011 +0000
@@ -5651,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/yahoo/yahoo_filexfer.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/protocols/yahoo/yahoo_filexfer.c	Tue Aug 16 05:38:01 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/stun.c	Thu Aug 11 15:01:34 2011 +0000
+++ b/libpurple/stun.c	Tue Aug 16 05:38:01 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/pidgin/pixmaps/Makefile.am	Thu Aug 11 15:01:34 2011 +0000
+++ b/pidgin/pixmaps/Makefile.am	Tue Aug 16 05:38:01 2011 +0000
@@ -285,6 +285,7 @@
 		protocols/22/jabber.png \
 		protocols/22/meanwhile.png \
 		protocols/22/msn.png \
+		protocols/22/mxit.png \
 		protocols/22/myspace.png \
 		protocols/22/silc.png \
 		protocols/22/simple.png \
--- a/po/ca.po	Thu Aug 11 15:01:34 2011 +0000
+++ b/po/ca.po	Tue Aug 16 05:38:01 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"