# HG changeset patch # User Elliott Sales de Andrade # Date 1280020278 0 # Node ID fdc865966b0126cd509ec6aad441a2e6d7cb3bd1 # Parent 47fc498fc34bcc8c8e955fdabd96e8c850dedf73# Parent 8e2da15b17cd996eaaa64e50adc6bf19c1ea463c propagate from branch 'im.pidgin.pidgin' (head e64578dc53c96709f20cb9416d507a4d448a4ee3) to branch 'im.pidgin.cpw.qulogic.gtk3' (head 74eaa11818b4a33e61322235c2b30753e31405d0) diff -r 47fc498fc34b -r fdc865966b01 ChangeLog --- a/ChangeLog Tue Jul 20 02:48:15 2010 +0000 +++ b/ChangeLog Sun Jul 25 01:11:18 2010 +0000 @@ -1,6 +1,6 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul -version 2.7.2 (??/??/????): +version 2.7.3 (??/??/????): General: * Use silent build rules for automake >1.11. You can enable verbose builds with the --disable-silent-rules configure option, or using @@ -46,6 +46,18 @@ * Fix file transfers that get stuck with "Waiting for transfer to begin". +version 2.7.2 (07/21/2010): + AIM and ICQ: + * Fix a crash bug related to X-Status messages that can be triggered by + remove users. This is CVE-2010-2528. + * Fix a rare crash bug caused by certain incoming SMS messages + (discovered by Jan Kaluza--thanks Jan!). + * Change HTML sent from ICQ accounts so that official ICQ clients + hopefully display it correctly. + + MSN: + * Fix a crash related to fast buddy icon transfers. + version 2.7.1 (05/29/2010): General: * Build fixes on OpenSolaris. (Brian Lu) diff -r 47fc498fc34b -r fdc865966b01 ChangeLog.API --- a/ChangeLog.API Tue Jul 20 02:48:15 2010 +0000 +++ b/ChangeLog.API Sun Jul 25 01:11:18 2010 +0000 @@ -1,6 +1,6 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul -version 2.7.2 (??/??/????): +version 2.7.3 (??/??/????): libpurple: Fixed: * purple_account_[gs]et_public_alias no longer crash when @@ -24,6 +24,9 @@ gnt_tree_row_get_prev, gnt_tree_row_get_child and gnt_tree_row_get_parent. +version 2.7.2 (07/21/2010): + * No changes + version 2.7.1 (05/29/2010): * No changes diff -r 47fc498fc34b -r fdc865966b01 ChangeLog.win32 --- a/ChangeLog.win32 Tue Jul 20 02:48:15 2010 +0000 +++ b/ChangeLog.win32 Sun Jul 25 01:11:18 2010 +0000 @@ -1,6 +1,9 @@ Starting with Pidgin version 2.7.1, this ChangeLog file will no longer be updated. It will be kept in the source tree for historical reasons only. +version 2.7.1 (05/29/2010): + * No changes + version 2.7.0 (05/12/2010): * Updated GTK+ to 2.16.6 * Private GTK+ Runtime now used (GTK+ Installer no longer supported) diff -r 47fc498fc34b -r fdc865966b01 NEWS --- a/NEWS Tue Jul 20 02:48:15 2010 +0000 +++ b/NEWS Sun Jul 25 01:11:18 2010 +0000 @@ -2,6 +2,11 @@ Our development blog is available at: http://planet.pidgin.im +2.7.2 (07/21/2010): + Mark: We discovered a security issue in Pidgin 2.7.0 and 2.7.1 and + decided to release a patched version quickly. This release contains + the fix for that crash, and a few other minor fixes. + 2.7.1 (05/29/2010): Elliott: Hey, I'm first! How did that happen?! Maybe because of the interesting changes in this release. Sure there were quite a few bug @@ -12,7 +17,7 @@ previous release! This fixes a number of bugs that you've all been reporting a ton of duplicate tickets about and even gives you the new direct connection file transfer support for MSN. Enjoy! - + Marcus: Quite a bit quicker to get this release out, compared with the previous one :). Fixes a number of bugs, and I'm sure the MSN direct connections will please many users. Enjoy! diff -r 47fc498fc34b -r fdc865966b01 configure.ac --- a/configure.ac Tue Jul 20 02:48:15 2010 +0000 +++ b/configure.ac Sun Jul 25 01:11:18 2010 +0000 @@ -46,7 +46,7 @@ m4_define([purple_lt_current], [7]) m4_define([purple_major_version], [2]) m4_define([purple_minor_version], [7]) -m4_define([purple_micro_version], [2]) +m4_define([purple_micro_version], [3]) m4_define([purple_version_suffix], [devel]) m4_define([purple_version], [purple_major_version.purple_minor_version.purple_micro_version]) diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/actions.c --- a/libpurple/protocols/mxit/actions.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/actions.c Sun Jul 25 01:11:18 2010 +0000 @@ -113,26 +113,26 @@ /* update name */ g_strlcpy( profile->nickname, name, sizeof( profile->nickname ) ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_FULLNAME, CP_PROF_TYPE_UTF8, profile->nickname ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_FULLNAME, CP_PROFILE_TYPE_UTF8, profile->nickname ); g_string_append( attributes, attrib ); acount++; /* update hidden */ field = purple_request_fields_get_field( fields, "hidden" ); profile->hidden = purple_request_field_bool_get_value( field ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_HIDENUMBER, CP_PROF_TYPE_BOOL, ( profile->hidden ) ? "1" : "0" ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_HIDENUMBER, CP_PROFILE_TYPE_BOOL, ( profile->hidden ) ? "1" : "0" ); g_string_append( attributes, attrib ); acount++; /* update birthday */ - strcpy( profile->birthday, bday ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_BIRTHDATE, CP_PROF_TYPE_UTF8, profile->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 ); g_string_append( attributes, attrib ); acount++; /* update gender */ profile->male = ( purple_request_fields_get_choice( fields, "male" ) != 0 ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_GENDER, CP_PROF_TYPE_BOOL, ( profile->male ) ? "1" : "0" ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_GENDER, CP_PROFILE_TYPE_BOOL, ( profile->male ) ? "1" : "0" ); g_string_append( attributes, attrib ); acount++; @@ -141,8 +141,8 @@ if ( !name ) profile->title[0] = '\0'; else - strcpy( profile->title, name ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_TITLE, CP_PROF_TYPE_UTF8, profile->title ); + g_strlcpy( profile->title, name, sizeof( profile->title ) ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_TITLE, CP_PROFILE_TYPE_UTF8, profile->title ); g_string_append( attributes, attrib ); acount++; @@ -151,8 +151,8 @@ if ( !name ) profile->firstname[0] = '\0'; else - strcpy( profile->firstname, name ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_FIRSTNAME, CP_PROF_TYPE_UTF8, profile->firstname ); + g_strlcpy( profile->firstname, name, sizeof( profile->firstname ) ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_FIRSTNAME, CP_PROFILE_TYPE_UTF8, profile->firstname ); g_string_append( attributes, attrib ); acount++; @@ -161,8 +161,8 @@ if ( !name ) profile->lastname[0] = '\0'; else - strcpy( profile->lastname, name ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_LASTNAME, CP_PROF_TYPE_UTF8, profile->lastname ); + g_strlcpy( profile->lastname, name, sizeof( profile->lastname ) ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_LASTNAME, CP_PROFILE_TYPE_UTF8, profile->lastname ); g_string_append( attributes, attrib ); acount++; @@ -171,8 +171,8 @@ if ( !name ) profile->email[0] = '\0'; else - strcpy( profile->email, name ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_EMAIL, CP_PROF_TYPE_UTF8, profile->email ); + g_strlcpy( profile->email, name, sizeof( profile->email ) ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_EMAIL, CP_PROFILE_TYPE_UTF8, profile->email ); g_string_append( attributes, attrib ); acount++; @@ -181,8 +181,8 @@ if ( !name ) profile->mobilenr[0] = '\0'; else - strcpy( profile->mobilenr, name ); - g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_MOBILENR, CP_PROF_TYPE_UTF8, profile->mobilenr ); + g_strlcpy( profile->mobilenr, name, sizeof( profile->mobilenr ) ); + g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_MOBILENR, CP_PROFILE_TYPE_UTF8, profile->mobilenr ); g_string_append( attributes, attrib ); acount++; @@ -225,12 +225,14 @@ group = purple_request_field_group_new( NULL ); purple_request_fields_add_group( fields, group ); - /* mxitId (read-only) */ - if ( session->mxitId ) { - field = purple_request_field_string_new( "mxitid", _( "Your MXitId" ), session->mxitId, FALSE ); +#if 0 + /* UID (read-only) */ + if ( session->uid ) { + field = purple_request_field_string_new( "mxitid", _( "Your UID" ), session->uid, FALSE ); purple_request_field_string_set_editable( field, FALSE ); purple_request_field_group_add_field( group, field ); } +#endif /* pin */ field = purple_request_field_string_new( "pin", _( "PIN" ), session->acc->password, FALSE ); @@ -247,6 +249,8 @@ /* birthday */ field = purple_request_field_string_new( "bday", _( "Birthday" ), profile->birthday, FALSE ); purple_request_field_group_add_field( group, field ); + if ( profile->flags & CP_PROF_DOBLOCKED ) + purple_request_field_string_set_editable( field, FALSE ); /* gender */ field = purple_request_field_choice_new( "male", _( "Gender" ), ( profile->male ) ? 1 : 0 ); diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/http.c --- a/libpurple/protocols/mxit/http.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/http.c Sun Jul 25 01:11:18 2010 +0000 @@ -118,7 +118,7 @@ /* read bytes from the socket */ len = read( session->fd, buf + buflen, sizeof( buf ) - buflen ); if ( len <= 0 ) { - /* connection has been terminated, or error occured */ + /* connection has been terminated, or error occurred */ goto done; } @@ -139,7 +139,7 @@ } buflen += len; - /* we have the header's end now skip over the http seperator to get the body offset */ + /* we have the header's end now skip over the http separator to get the body offset */ ch += strlen( HTTP_11_SEPERATOR ); *(ch - 1) = '\0'; body = ch; @@ -206,7 +206,7 @@ /* read bytes from the socket */ len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res ); if ( len <= 0 ) { - /* connection has been terminated, or error occured */ + /* connection has been terminated, or error occurred */ goto done; } diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/login.c --- a/libpurple/protocols/mxit/login.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/login.c Sun Jul 25 01:11:18 2010 +0000 @@ -238,7 +238,7 @@ /* nickname */ str = purple_request_fields_get_string( fields, "nickname" ); if ( ( !str ) || ( strlen( str ) < 3 ) ) { - err = _( "The nick name you entered is invalid." ); + err = _( "The Display Name you entered is invalid." ); goto out; } g_strlcpy( profile->nickname, str, sizeof( profile->nickname ) ); @@ -329,12 +329,12 @@ purple_request_fields_add_group( fields, group ); /* mxit login name */ - field = purple_request_field_string_new( "loginname", _( "MXit Login Name" ), purple_account_get_username( session->acc ), FALSE ); + field = purple_request_field_string_new( "loginname", _( "MXit ID" ), purple_account_get_username( session->acc ), FALSE ); purple_request_field_string_set_editable( field, FALSE ); purple_request_field_group_add_field( group, field ); /* nick name (required) */ - field = purple_request_field_string_new( "nickname", _( "Nick Name" ), profile->nickname, FALSE ); + field = purple_request_field_string_new( "nickname", _( "Display Name" ), profile->nickname, FALSE ); purple_request_field_set_required( field, TRUE ); purple_request_field_group_add_field( group, field ); @@ -418,10 +418,10 @@ purple_connection_error( session->con, _( "Invalid country selected. Please try again." ) ); return; case '6' : - purple_connection_error( session->con, _( "Username is not registered. Please register first." ) ); + purple_connection_error( session->con, _( "The MXit ID you entered is not registered. Please register first." ) ); return; case '7' : - purple_connection_error( session->con, _( "Username is already registered. Please choose another username." ) ); + purple_connection_error( session->con, _( "The MXit ID you entered is already registered. Please choose another." ) ); /* this user's account already exists, so we need to change the registration login flag to be login */ purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN ); return; @@ -637,7 +637,7 @@ /* add the captcha */ logindata->captcha = purple_base64_decode( parts[3], &logindata->captcha_size ); - field = purple_request_field_image_new( "capcha", _( "Security Code" ), (gchar*) logindata->captcha, logindata->captcha_size ); + field = purple_request_field_image_new( "captcha", _( "Security Code" ), (gchar*) logindata->captcha, logindata->captcha_size ); purple_request_field_group_add_field( group, field ); /* ask for input (required) */ @@ -659,7 +659,7 @@ } purple_request_field_list_add( field, country[1], g_strdup( country[0] ) ); if ( strcmp( country[1], parts[6] ) == 0 ) { - /* based on the user's ip, this is his current country code, so we default to it */ + /* based on the user's IP, this is his current country code, so we default to it */ purple_request_field_list_add_selected( field, country[1] ); } g_strfreev( country ); diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/markup.c --- a/libpurple/protocols/mxit/markup.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/markup.c Sun Jul 25 01:11:18 2010 +0000 @@ -257,7 +257,7 @@ * all the text as is to the conversation window. this message dump is very * confusing and makes it totally unusable. to work around this we will count * the amount of tags and if its more than the pidgin threshold, we will just - * break the message up into smaller parts and send them seperately to pidgin. + * break the message up into smaller parts and send them separately to pidgin. * to the user it will look like multiple messages, but at least he will be able * to use and understand it. */ diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/multimx.c --- a/libpurple/protocols/mxit/multimx.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/multimx.c Sun Jul 25 01:11:18 2010 +0000 @@ -557,6 +557,9 @@ { struct MXitSession* session = (struct MXitSession*) gc->proto_data; struct multimx* multimx = NULL; + PurpleBuddy* buddy; + PurpleConversation *convo; + char* tmp; purple_debug_info(MXIT_PLUGIN_ID, "Groupchat invite to '%s'\n", username); @@ -569,6 +572,24 @@ /* Send invite to MXit */ mxit_send_groupchat_invite(session, multimx->roomid, 1, &username); + + /* Find the buddy information for this contact (reference: "libpurple/blist.h") */ + buddy = purple_find_buddy(session->acc, username); + if (!buddy) { + purple_debug_warning(MXIT_PLUGIN_ID, "mxit_chat_invite: unable to find the buddy '%s'\n", username); + return; + } + + convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc); + if (convo == NULL) { + purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname); + return; + } + + /* Display system message in chat window */ + tmp = g_strdup_printf("%s: %s", _("You have invited"), purple_buddy_get_alias(buddy)); + purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "MXit", tmp, PURPLE_MESSAGE_SYSTEM, time(NULL)); + g_free(tmp); } diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/mxit.c --- a/libpurple/protocols/mxit/mxit.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/mxit.c Sun Jul 25 01:11:18 2010 +0000 @@ -91,6 +91,8 @@ if ( !account ) goto skip; con = purple_account_get_connection( account ); + if ( !con ) + goto skip; /* determine if it's a command-response to send */ is_command = g_str_has_prefix( parts[4], "::type=reply|" ); @@ -145,7 +147,7 @@ /*------------------------------------------------------------------------ - * Unegister MXit from receiving URI click notifications from the UI + * Unregister MXit from receiving URI click notifications from the UI */ static void mxit_unregister_uri_handler() { @@ -203,7 +205,7 @@ if ( find_active_chat( session->active_chats, who ) ) return; - /* determite if this buddy is a MXit service */ + /* determine if this buddy is a MXit service */ switch ( contact->type ) { case MXIT_TYPE_BOT : case MXIT_TYPE_CHATROOM : @@ -559,7 +561,8 @@ { struct MXitSession* session = (struct MXitSession*) gc->proto_data; const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, - CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY }; + CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_LASTSEEN, + CP_PROFILE_STATUS, CP_PROFILE_AVATAR }; purple_debug_info( MXIT_PLUGIN_ID, "mxit_get_info: '%s'\n", who ); @@ -578,11 +581,34 @@ table = g_hash_table_new( g_str_hash, g_str_equal ); - g_hash_table_insert( table, "login_label", (gpointer)_( "Your Mobile Number..." ) ); + g_hash_table_insert( table, "login_label", (gpointer)_( "Your MXit ID..." ) ); return table; } + +/*------------------------------------------------------------------------ + * Buddy list menu. + * + * @param node The entry in the buddy list. + */ +static GList* mxit_blist_menu( PurpleBlistNode *node ) +{ + PurpleBuddy* buddy; + struct contact* contact; + GList* m = NULL; + + if ( !PURPLE_BLIST_NODE_IS_BUDDY( node ) ) + return NULL; + + buddy = (PurpleBuddy *) node; + contact = purple_buddy_get_protocol_data( buddy ); + if ( !contact ) + return NULL; + + return m; +} + /*========================================================================================================================*/ static PurplePluginProtocolInfo proto_info = { @@ -594,7 +620,7 @@ 32, 32, /* min width & height */ MXIT_AVATAR_SIZE, /* max width */ MXIT_AVATAR_SIZE, /* max height */ - 100000, /* max filezize */ + 100000, /* max filesize */ PURPLE_ICON_SCALE_SEND | PURPLE_ICON_SCALE_DISPLAY /* scaling rules */ }, mxit_list_icon, /* list_icon */ @@ -602,7 +628,7 @@ mxit_status_text, /* status_text */ mxit_tooltip, /* tooltip_text */ mxit_status_types, /* status types [roster.c] */ - NULL, /* blist_node_menu */ + mxit_blist_menu, /* blist_node_menu */ mxit_chat_info, /* chat_info [multimx.c] */ NULL, /* chat_info_defaults */ mxit_login, /* login [login.c] */ diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/mxit.h --- a/libpurple/protocols/mxit/mxit.h Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/mxit.h Sun Jul 25 01:11:18 2010 +0000 @@ -105,7 +105,7 @@ /* Client session flags */ #define MXIT_FLAG_CONNECTED 0x01 /* established connection to the server */ #define MXIT_FLAG_LOGGEDIN 0x02 /* user currently logged in */ -#define MXIT_FLAG_FIRSTROSTER 0x04 /* set to true once the first roster update has been recevied and processed */ +#define MXIT_FLAG_FIRSTROSTER 0x04 /* set to true once the first roster update has been received and processed */ /* define this to enable the link clicking support */ @@ -151,7 +151,7 @@ /* personal (profile) */ struct MXitProfile* profile; /* user's profile information */ - char* mxitId; /* the user's MXitId */ + char* uid; /* the user's UID */ /* libpurple */ PurpleAccount* acc; /* pointer to the libpurple internal account struct */ diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/profile.c --- a/libpurple/protocols/mxit/profile.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/profile.c Sun Jul 25 01:11:18 2010 +0000 @@ -101,6 +101,23 @@ /*------------------------------------------------------------------------ + * Returns timestamp field in date & time format (DD-MM-YYYY HH:MM:SS) + * + * @param msecs The timestamps (milliseconds since epoch) + * @return Date & Time in a display'able format. + */ +static const char* datetime( int64_t msecs ) +{ + time_t secs = msecs / 1000; + + struct tm t; + localtime_r( &secs, &t ); + + return purple_utf8_strftime( "%d-%m-%Y %H:%M:%S", &t ); +} + + +/*------------------------------------------------------------------------ * Display the profile information. * * @param session The MXit session object @@ -120,7 +137,7 @@ contact = purple_buddy_get_protocol_data(buddy); } - purple_notify_user_info_add_pair( info, _( "Nick Name" ), profile->nickname ); + purple_notify_user_info_add_pair( info, _( "Display Name" ), profile->nickname ); purple_notify_user_info_add_pair( info, _( "Birthday" ), profile->birthday ); purple_notify_user_info_add_pair( info, _( "Gender" ), profile->male ? _( "Male" ) : _( "Female" ) ); // purple_notify_user_info_add_pair( info, _( "Hidden Number" ), profile->hidden ? _( "Yes" ) : _( "No" ) ); @@ -138,6 +155,10 @@ /* presence */ purple_notify_user_info_add_pair( info, _( "Status" ), mxit_convert_presence_to_name( contact->presence ) ); + /* last online */ + if ( contact->presence == MXIT_PRESENCE_OFFLINE ) + purple_notify_user_info_add_pair( info, _( "Last Online" ), ( profile->lastonline == 0 ) ? _( "Unknown" ) : datetime( profile->lastonline ) ); + /* mood */ if ( contact->mood != MXIT_MOOD_NONE ) purple_notify_user_info_add_pair( info, _( "Mood" ), mxit_convert_mood_to_name( contact->mood ) ); @@ -153,7 +174,6 @@ /* hidden number */ purple_notify_user_info_add_pair( info, _( "Hidden Number" ), ( contact->flags & MXIT_CFLAG_HIDDEN ) ? _( "Yes" ) : _( "No" ) ); - } purple_notify_userinfo( session->con, username, info, NULL, NULL ); diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/profile.h --- a/libpurple/protocols/mxit/profile.h Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/profile.h Sun Jul 25 01:11:18 2010 +0000 @@ -44,6 +44,8 @@ char email[64]; /* user's email address */ char mobilenr[21]; /* user's mobile number */ char regcountry[3]; /* user's registered country code */ + int64_t flags; /* user's profile flags */ + int64_t lastonline; /* user's last-online timestamp */ gboolean hidden; /* set if the user's msisdn should remain hidden */ }; diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/protocol.c --- a/libpurple/protocols/mxit/protocol.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/protocol.c Sun Jul 25 01:11:18 2010 +0000 @@ -445,7 +445,7 @@ packet->headerlen = 0; /* create generic packet header */ - hlen = sprintf( header, "id=%s%c", session->acc->username, CP_REC_TERM ); /* client msisdn */ + hlen = snprintf( header, sizeof( header ), "id=%s%c", session->acc->username, CP_REC_TERM ); /* client msisdn */ if ( session->http ) { /* http connection only */ @@ -520,7 +520,7 @@ /* we are still waiting for an outstanding ACK from the MXit server */ if ( session->last_tx <= time( NULL ) - MXIT_ACK_TIMEOUT ) { /* ack timeout! so we close the connection here */ - purple_debug_info( MXIT_PLUGIN_ID, "mxit_manage_queue: Timeout awaiting ACK for command '%X'\n", session->outack ); + purple_debug_info( MXIT_PLUGIN_ID, "mxit_manage_queue: Timeout awaiting ACK for command '%i'\n", session->outack ); purple_connection_error( session->con, _( "Timeout while waiting for a response from the MXit server." ) ); } return TRUE; @@ -642,7 +642,8 @@ locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%s%c%i%c%s%c" /* "ms"=password\1version\1maxreplyLen\1name\1 */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%s%c%i%c%s%c" /* "ms"=password\1version\1maxreplyLen\1name\1 */ "%s%c%i%c%s%c%s%c" /* dateOfBirth\1gender\1location\1capabilities\1 */ "%s%c%i%c%s%c%s", /* dc\1features\1dialingcode\1locale */ session->encpwd, CP_FLD_TERM, MXIT_CP_VERSION, CP_FLD_TERM, CP_MAX_FILESIZE, CP_FLD_TERM, profile->nickname, CP_FLD_TERM, @@ -670,7 +671,8 @@ locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%s%c%i%c" /* "ms"=password\1version\1getContacts\1 */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%s%c%i%c" /* "ms"=password\1version\1getContacts\1 */ "%s%c%s%c%i%c" /* capabilities\1dc\1features\1 */ "%s%c%s%c" /* dialingcode\1locale\1 */ "%i%c%i%c%i", /* maxReplyLen\1protocolVer\1lastRosterUpdate */ @@ -711,7 +713,8 @@ markuped_msg = g_strdup( msg ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%s%c%i%c%i", /* "ms"=jid\1msg\1type\1flags */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%s%c%i%c%i", /* "ms"=jid\1msg\1type\1flags */ to, CP_FLD_TERM, markuped_msg, CP_FLD_TERM, msgtype, CP_FLD_TERM, CP_MSG_MARKUP | CP_MSG_EMOTICON ); @@ -737,7 +740,8 @@ int datalen; unsigned int i; - datalen = sprintf( data, "ms=%s%c%i", /* "ms="mxitid\1nr_attributes */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%i", /* "ms="mxitid\1nr_attributes */ (username ? username : ""), CP_FLD_TERM, nr_attrib); /* add attributes */ @@ -767,7 +771,8 @@ parts = g_strsplit( attributes, "\01", ( MXIT_MAX_ATTRIBS * 3 ) ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%i", /* "ms"=password\1nr_attibutes */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%i", /* "ms"=password\1nr_attibutes */ ( password ) ? password : "", CP_FLD_TERM, nr_attrib ); @@ -797,7 +802,8 @@ int datalen; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%i%c", /* "ms"=show\1status */ + datalen = snprintf( data, sizeof( data ), + "ms=%i%c", /* "ms"=show\1status */ presence, CP_FLD_TERM ); @@ -822,7 +828,8 @@ int datalen; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%i", /* "ms"=mood */ + datalen = snprintf( data, sizeof( data ), + "ms=%i", /* "ms"=mood */ mood ); @@ -845,7 +852,8 @@ int datalen; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%s%c%s%c%i%c%s", /* "ms"=group\1username\1alias\1type\1msg */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%s%c%s%c%i%c%s", /* "ms"=group\1username\1alias\1type\1msg */ groupname, CP_FLD_TERM, username, CP_FLD_TERM, alias, CP_FLD_TERM, MXIT_TYPE_MXIT, CP_FLD_TERM, "" ); @@ -867,7 +875,8 @@ int datalen; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s", /* "ms"=username */ + datalen = snprintf( data, sizeof( data ), + "ms=%s", /* "ms"=username */ username ); @@ -889,7 +898,8 @@ int datalen; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%s%c%s", /* "ms"=username\1group\1alias */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%s%c%s", /* "ms"=username\1group\1alias */ username, CP_FLD_TERM, "", CP_FLD_TERM, alias ); @@ -910,7 +920,8 @@ int datalen; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s", /* "ms"=username */ + datalen = snprintf( data, sizeof( data ), + "ms=%s", /* "ms"=username */ username ); @@ -933,7 +944,8 @@ int datalen; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%s%c%s", /* "ms"=groupname\1username\1alias */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%s%c%s", /* "ms"=groupname\1username\1alias */ groupname, CP_FLD_TERM, username, CP_FLD_TERM, alias ); @@ -954,7 +966,8 @@ int datalen; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s", /* "ms"=splashId */ + datalen = snprintf( data, sizeof( data ), + "ms=%s", /* "ms"=splashId */ splashid ); @@ -979,7 +992,8 @@ purple_debug_info( MXIT_PLUGIN_ID, "mxit_send_msgevent: to=%s id=%s event=%i\n", to, id, event ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%s%c%i", /* "ms"=contactAddress \1 id \1 event */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%s%c%i", /* "ms"=contactAddress \1 id \1 event */ to, CP_FLD_TERM, id, CP_FLD_TERM, event ); @@ -1003,7 +1017,8 @@ int i; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%i", /* "ms"=roomname\1nr_jids\1jid0\1..\1jidN */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%i", /* "ms"=roomname\1nr_jids\1jid0\1..\1jidN */ groupname, CP_FLD_TERM, nr_usernames ); @@ -1032,7 +1047,8 @@ int i; /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=%s%c%i", /* "ms"=roomid\1nr_jids\1jid0\1..\1jidN */ + datalen = snprintf( data, sizeof( data ), + "ms=%s%c%i", /* "ms"=roomid\1nr_jids\1jid0\1..\1jidN */ roomid, CP_FLD_TERM, nr_usernames ); @@ -1284,7 +1300,7 @@ const char* statusmsg; const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_HIDENUMBER, CP_PROFILE_FULLNAME, CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL, - CP_PROFILE_MOBILENR }; + CP_PROFILE_MOBILENR, CP_PROFILE_FLAGS }; purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN ); @@ -1304,7 +1320,7 @@ /* extract MXitId (from protocol 5.9) */ if ( records[1]->fcount >= 9 ) - session->mxitId = g_strdup( records[1]->fields[8]->data ); + session->uid = g_strdup( records[1]->fields[8]->data ); /* display the current splash-screen */ if ( splash_popup_enabled( session ) ) @@ -1456,9 +1472,9 @@ /* build up a new contact info struct */ contact = g_new0( struct contact, 1 ); - strcpy( contact->username, rec->fields[0]->data ); + g_strlcpy( contact->username, rec->fields[0]->data, sizeof( contact->username ) ); mxit_strip_domain( contact->username ); /* remove dummy domain */ - strcpy( contact->alias, rec->fields[1]->data ); + g_strlcpy( contact->alias, rec->fields[1]->data, sizeof( contact->alias ) ); contact->type = atoi( rec->fields[2]->data ); if ( rec->fcount >= 5 ) { @@ -1509,10 +1525,10 @@ /* build up a new contact info struct */ contact = g_new0( struct contact, 1 ); - strcpy( contact->groupname, rec->fields[0]->data ); - strcpy( contact->username, rec->fields[1]->data ); + g_strlcpy( contact->groupname, rec->fields[0]->data, sizeof( contact->groupname ) ); + g_strlcpy( contact->username, rec->fields[1]->data, sizeof( contact->username ) ); mxit_strip_domain( contact->username ); /* remove dummy domain */ - strcpy( contact->alias, rec->fields[2]->data ); + g_strlcpy( contact->alias, rec->fields[2]->data, sizeof( contact->alias ) ); contact->presence = atoi( rec->fields[3]->data ); contact->type = atoi( rec->fields[4]->data ); @@ -1566,12 +1582,13 @@ /* * The format of the record is: - * contactAddressN\1presenceN\1\moodN\1customMoodN\1statusMsgN\1avatarIdN + * contactAddressN\1presenceN\1moodN\1customMoodN\1statusMsgN\1avatarIdN */ mxit_strip_domain( rec->fields[0]->data ); /* contactAddress */ mxit_update_buddy_presence( session, rec->fields[0]->data, atoi( rec->fields[1]->data ), atoi( rec->fields[2]->data ), - rec->fields[3]->data, rec->fields[4]->data, rec->fields[5]->data ); + rec->fields[3]->data, rec->fields[4]->data ); + mxit_update_buddy_avatar( session, rec->fields[0]->data, rec->fields[5]->data ); } } @@ -1589,11 +1606,13 @@ struct MXitProfile* profile = NULL; int count; int i; + const char* avatarId = NULL; + const char* statusMsg = NULL; purple_debug_info( MXIT_PLUGIN_ID, "mxit_parse_cmd_extprofile: profile for '%s'\n", mxitId ); - if ( records[0]->fields[0]->len == 0 ) { - /* no MXitId provided, so this must be our own profile information */ + if ( ( records[0]->fields[0]->len == 0 ) || ( session->uid && ( strcmp( session->uid, records[0]->fields[0]->data ) == 0 ) ) ) { + /* No UserId or Our UserId provided, so this must be our own profile information */ if ( session->profile == NULL ) session->profile = g_new0( struct MXitProfile, 1 ); profile = session->profile; @@ -1643,8 +1662,13 @@ /* nickname */ g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) ); } + else if ( strcmp( CP_PROFILE_STATUS, fname ) == 0 ) { + /* status message - just keep a reference to the value */ + statusMsg = fvalue; + } else if ( strcmp( CP_PROFILE_AVATAR, fname ) == 0 ) { - /* avatar id, we just ingore it cause we dont need it */ + /* avatar id - just keep a reference to the value */ + avatarId = fvalue; } else if ( strcmp( CP_PROFILE_TITLE, fname ) == 0 ) { /* title */ @@ -1670,14 +1694,26 @@ /* registered country */ g_strlcpy( profile->regcountry, fvalue, sizeof( profile->regcountry ) ); } + else if ( strcmp( CP_PROFILE_FLAGS, fname ) == 0 ) { + /* profile flags */ + profile->flags = strtoll( fvalue, NULL, 10 ); + } + else if ( strcmp( CP_PROFILE_LASTSEEN, fname ) == 0 ) { + /* last seen online */ + profile->lastonline = strtoll( fvalue, NULL, 10 ); + } else { /* invalid profile attribute */ purple_debug_error( MXIT_PLUGIN_ID, "Invalid profile attribute received '%s' \n", fname ); } } - /* if this is not our profile, just display it */ if ( profile != session->profile ) { + /* update avatar (if necessary) */ + if ( avatarId ) + mxit_update_buddy_avatar( session, mxitId, avatarId ); + + /* if this is not our profile, just display it */ mxit_show_profile( session, mxitId, profile ); g_free( profile ); } @@ -2010,12 +2046,12 @@ return 0; } else { - sprintf( errmsg, _( "Login error: %s (%i)" ), errdesc, packet->errcode ); + snprintf( errmsg, sizeof( errmsg ), _( "Login error: %s (%i)" ), errdesc, packet->errcode ); purple_connection_error( session->con, errmsg ); return -1; } case CP_CMD_LOGOUT : - sprintf( errmsg, _( "Logout error: %s (%i)" ), errdesc, packet->errcode ); + snprintf( errmsg, sizeof( errmsg ), _( "Logout error: %s (%i)" ), errdesc, packet->errcode ); purple_connection_error_reason( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) ); return -1; case CP_CMD_CONTACT : @@ -2487,8 +2523,8 @@ mxit_free_emoticon_cache( session ); /* free allocated memory */ - if ( session->mxitId ) - g_free( session->mxitId ); + if ( session->uid ) + g_free( session->uid ); g_free( session->encpwd ); session->encpwd = NULL; diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/protocol.h --- a/libpurple/protocols/mxit/protocol.h Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/protocol.h Sun Jul 25 01:11:18 2010 +0000 @@ -190,13 +190,17 @@ #define CP_PROFILE_EMAIL "email" /* Email address (UTF8 String) */ #define CP_PROFILE_MOBILENR "mobilenumber" /* Mobile Number (UTF8 String) */ #define CP_PROFILE_REGCOUNTRY "registeredcountry" /* Registered Country Code (UTF8 String) */ +#define CP_PROFILE_FLAGS "flags" /* Profile flags (Bitset) */ +#define CP_PROFILE_LASTSEEN "lastseen" /* Last-Online timestamp */ /* extended profile field types */ -#define CP_PROF_TYPE_BOOL 0x02 /* boolean profile attribute type */ -#define CP_PROF_TYPE_INT 0x05 /* integer profile attribute type */ -#define CP_PROF_TYPE_UTF8 0x0A /* UTF8 string profile attribute type */ -#define CP_PROF_TYPE_DATE 0x0B /* date-time profile attribute type */ +#define CP_PROFILE_TYPE_BOOL 0x02 /* boolean profile attribute type */ +#define CP_PROFILE_TYPE_INT 0x05 /* integer profile attribute type */ +#define CP_PROFILE_TYPE_UTF8 0x0A /* UTF8 string profile attribute type */ +#define CP_PROFILE_TYPE_DATE 0x0B /* date-time profile attribute type */ +/* profile flags */ +#define CP_PROF_DOBLOCKED 0x40 /* date-of-birth cannot be changed */ /* define this to enable protocol debugging (very verbose logging) */ #define DEBUG_PROTOCOL diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/roster.c --- a/libpurple/protocols/mxit/roster.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/roster.c Sun Jul 25 01:11:18 2010 +0000 @@ -44,12 +44,12 @@ /* statuses (reference: libpurple/status.h) */ static struct status { - PurpleStatusPrimitive primative; + PurpleStatusPrimitive primitive; int mxit; const char* id; const char* name; } const mxit_statuses[] = { - /* primative, no, id, name */ + /* primitive, no, id, name */ { PURPLE_STATUS_OFFLINE, MXIT_PRESENCE_OFFLINE, "offline", N_( "Offline" ) }, /* 0 */ { PURPLE_STATUS_AVAILABLE, MXIT_PRESENCE_ONLINE, "online", N_( "Available" ) }, /* 1 */ { PURPLE_STATUS_AWAY, MXIT_PRESENCE_AWAY, "away", N_( "Away" ) }, /* 2 */ @@ -74,7 +74,7 @@ const struct status* status = &mxit_statuses[i]; /* add mxit status (reference: "libpurple/status.h") */ - type = purple_status_type_new_with_attrs( status->primative, status->id, _( status->name ), TRUE, TRUE, FALSE, + type = purple_status_type_new_with_attrs( status->primitive, status->id, _( status->name ), TRUE, TRUE, FALSE, "message", _( "Message" ), purple_value_new( PURPLE_TYPE_STRING ), NULL ); @@ -292,7 +292,7 @@ * XXX: libPurple does not currently provide an API to change or rename the group name * for a specific buddy. One option is to remove the buddy from the list and re-adding * him in the new group, but by doing that makes the buddy go offline and then online - * again. This is really not ideal and very iretating, but how else then? + * again. This is really not ideal and very irritating, but how else then? */ /* create new buddy */ @@ -358,7 +358,7 @@ * So if this MXit contact isn't in a group, pretend it is. */ if ( *contact->groupname == '\0' ) { - strcpy( contact->groupname, MXIT_DEFAULT_GROUP ); + g_strlcpy( contact->groupname, MXIT_DEFAULT_GROUP, sizeof( contact->groupname ) ); } /* find or create a group for this contact */ @@ -428,15 +428,14 @@ * @param mood The new mood for the contact * @param customMood The custom mood identifier * @param statusMsg This is the contact's status message - * @param avatarId This is the contact's avatar id */ -void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg, const char* avatarId ) +void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg ) { PurpleBuddy* buddy = NULL; struct contact* contact = NULL; - purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: user='%s' presence=%i mood=%i customMood='%s' statusMsg='%s' avatar='%s'\n", - username, presence, mood, customMood, statusMsg, avatarId ); + purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: user='%s' presence=%i mood=%i customMood='%s' statusMsg='%s'\n", + username, presence, mood, customMood, statusMsg ); if ( ( presence < MXIT_PRESENCE_OFFLINE ) || ( presence > MXIT_PRESENCE_DND ) ) { purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: invalid presence state %i\n", presence ); @@ -472,7 +471,46 @@ if ( statusMsg[0] != '\0' ) contact->statusMsg = g_markup_escape_text( statusMsg, -1 ); - /* update avatarId */ + /* update the buddy's status (reference: "libpurple/prpl.h") */ + if ( contact->statusMsg ) + purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, "message", contact->statusMsg, NULL ); + else + purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, NULL ); + + /* update the buddy's mood */ + if ( contact->mood == MXIT_MOOD_NONE ) + purple_prpl_got_user_status_deactive( session->acc, username, "mood" ); + else + purple_prpl_got_user_status( session->acc, username, "mood", PURPLE_MOOD_NAME, mxit_moods[contact->mood-1].mood, NULL ); +} + + +/*------------------------------------------------------------------------ + * Update the buddy's avatar. + * Either a presence update packet was received from the MXit server, or a profile response. + * + * @param session The MXit session object + * @param username The contact which presence to update + * @param avatarId This is the contact's avatar id + */ +void mxit_update_buddy_avatar( struct MXitSession* session, const char* username, const char* avatarId ) +{ + PurpleBuddy* buddy = NULL; + struct contact* contact = NULL; + + purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_avatar: user='%s' avatar='%s'\n", username, avatarId ); + + /* find the buddy information for this contact (reference: "libpurple/blist.h") */ + buddy = purple_find_buddy( session->acc, username ); + if ( !buddy ) { + purple_debug_warning( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: unable to find the buddy '%s'\n", username ); + return; + } + + contact = purple_buddy_get_protocol_data( buddy ); + if ( !contact ) + return; + if ( ( contact->avatarId ) && ( g_ascii_strcasecmp( contact->avatarId, avatarId ) == 0 ) ) { /* avatar has not changed - do nothing */ } @@ -486,18 +524,6 @@ } else /* clear current avatar */ purple_buddy_icons_set_for_user( session->acc, username, NULL, 0, NULL ); - - /* update the buddy's status (reference: "libpurple/prpl.h") */ - if ( contact->statusMsg ) - purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, "message", contact->statusMsg, NULL ); - else - purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, NULL ); - - /* update the buddy's mood */ - if ( contact->mood == MXIT_MOOD_NONE ) - purple_prpl_got_user_status_deactive( session->acc, username, "mood" ); - else - purple_prpl_got_user_status( session->acc, username, "mood", PURPLE_MOOD_NAME, mxit_moods[contact->mood-1].mood, NULL ); } diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/mxit/roster.h --- a/libpurple/protocols/mxit/roster.h Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/mxit/roster.h Sun Jul 25 01:11:18 2010 +0000 @@ -124,7 +124,8 @@ /* MXit Protocol callbacks */ void mxit_update_contact( struct MXitSession* session, struct contact* contact ); -void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg, const char* avatarId ); +void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg ); +void mxit_update_buddy_avatar( struct MXitSession* session, const char* username, const char* avatarId ); void mxit_new_subscription( struct MXitSession* session, struct contact* contact ); void mxit_update_blist( struct MXitSession* session ); gboolean is_mxit_chatroom_contact( struct MXitSession* session, const char* username ); diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/oscar/family_icbm.c --- a/libpurple/protocols/oscar/family_icbm.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Sun Jul 25 01:11:18 2010 +0000 @@ -249,9 +249,6 @@ } g_free(buf); - - - g_free(snac2->data); g_free(snac2); @@ -2687,7 +2684,6 @@ guint16 hdrlen; int curpos; guint16 num1, num2; - char *desc, *title, *temp; PurpleAccount *account; PurpleBuddy *buddy; PurplePresence *presence; @@ -2714,33 +2710,41 @@ xml = byte_stream_getstr(bs, bs->len - curpos); purple_debug_misc("oscar", "X-Status: Received XML reply\n"); if (xml) { - /* purple_debug_misc("oscar", "X-Status: XML reply: %s\n", xml); */ - desc = strstr(xml, "<desc>"); - if (desc != NULL) { - temp = strstr(xml, "</desc>"); - temp[0] = 0; - desc = desc + 12; + GString *xstatus; + char *tmp1, *tmp2; + + /* purple_debug_misc("oscar", "X-Status: XML reply: %s\n", xml); */ + + xstatus = g_string_new(NULL); + + tmp1 = strstr(xml, "<title>"); + if (tmp1 != NULL) { + tmp1 += 13; + tmp2 = strstr(tmp1, "</title>"); + if (tmp2 != NULL) + g_string_append_len(xstatus, tmp1, tmp2 - tmp1); } - title = strstr(xml, "<title>"); - if (title != NULL) { - temp = strstr(xml, "</title>"); - temp[0] = 0; - title = title + 13; - } else { - title = ""; + tmp1 = strstr(xml, "<desc>"); + if (tmp1 != NULL) { + tmp1 += 12; + tmp2 = strstr(tmp1, "</desc>"); + if (tmp2 != NULL) { + if (xstatus->len > 0) + g_string_append(xstatus, " - "); + g_string_append_len(xstatus, tmp1, tmp2 - tmp1); + } } - strcpy(xml,title); - if (desc) { - strcat(xml, " - "); - strcat(xml, desc); + if (xstatus->len > 0) { + purple_debug_misc("oscar", "X-Status reply: %s\n", xstatus->str); + account = purple_connection_get_account(od->gc); + buddy = purple_find_buddy(account, bn); + presence = purple_buddy_get_presence(buddy); + status = purple_presence_get_active_status(presence); + purple_prpl_got_user_status(account, bn, + purple_status_get_id(status), + "message", xstatus->str, NULL); } - purple_debug_misc("oscar", "X-Status reply: %s\n", xml); - account = purple_connection_get_account(od->gc); - buddy = purple_find_buddy(account, bn); - presence = purple_buddy_get_presence(buddy); - status = purple_presence_get_active_status(presence); - purple_prpl_got_user_status(account, bn, - purple_status_get_id(status), "message", xml, NULL); + g_string_free(xstatus, TRUE); } else { purple_debug_misc("oscar", "X-Status: Can't get XML reply string\n"); } diff -r 47fc498fc34b -r fdc865966b01 libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.c Sun Jul 25 01:11:18 2010 +0000 @@ -3028,12 +3028,23 @@ if (smstype != 0) break; taglen = byte_stream_getle32(&qbs); + if (taglen > 2000) { + /* Avoid trying to allocate large amounts of memory, in + case we get something unexpected. */ + break; + } tagstr = byte_stream_getstr(&qbs, taglen); if (tagstr == NULL) break; byte_stream_advance(&qbs, 3); byte_stream_advance(&qbs, 4); smslen = byte_stream_getle32(&qbs); + if (smslen > 2000) { + /* Avoid trying to allocate large amounts of memory, in + case we get something unexpected. */ + g_free(tagstr); + break; + } smsmsg = byte_stream_getstr(&qbs, smslen); /* Check if this is an SMS being sent from server */ diff -r 47fc498fc34b -r fdc865966b01 libpurple/purple-url-handler --- a/libpurple/purple-url-handler Tue Jul 20 02:48:15 2010 +0000 +++ b/libpurple/purple-url-handler Sun Jul 25 01:11:18 2010 +0000 @@ -73,7 +73,8 @@ def findaccount(protocolname, accountname="", matcher=None): if matcher: for account in cpurple.PurpleAccountsGetAll(): - if accountname != "" and accountname != cpurple.PurpleAccountGetUsername(a): + if (protocolname != cpurple.PurpleAccountGetProtocolID(account)) or \ + (accountname != "" and accountname != cpurple.PurpleAccountGetUsername(account)): continue if matcher(account): bring_account_online(account) @@ -182,7 +183,7 @@ def irc(uri): protocol = "prpl-irc" - match = re.match(r"^irc:(//([^/]*)/)?([^?]*)(\?(.*))?", uri) + match = re.match(r"^irc:(//([^/]*))?/?([^?]*)(\?(.*))?", uri) if not match: print "Invalid irc URI: %s" % uri return @@ -207,7 +208,7 @@ def correct_server(account): username = cpurple.PurpleAccountGetUsername(account) - return ("@" in username) and (server == (username.split("@"))[1]) + return ((server == "") or ("@" in username) and (server == (username.split("@"))[1])) account = findaccount(protocol, matcher=correct_server) diff -r 47fc498fc34b -r fdc865966b01 pidgin/pixmaps/emotes/default/24/default.theme.in --- a/pidgin/pixmaps/emotes/default/24/default.theme.in Tue Jul 20 02:48:15 2010 +0000 +++ b/pidgin/pixmaps/emotes/default/24/default.theme.in Sun Jul 25 01:11:18 2010 +0000 @@ -459,7 +459,7 @@ wink.png ;-) ;) excited.png :-D :D :-> :> neutral.png :-| :| -shock.png :-O :O +shocked.png :-O :O tongue.png :-P :P embarrassed.png :-$ :$ glasses-cool.png 8-) diff -r 47fc498fc34b -r fdc865966b01 po/ChangeLog --- a/po/ChangeLog Tue Jul 20 02:48:15 2010 +0000 +++ b/po/ChangeLog Sun Jul 25 01:11:18 2010 +0000 @@ -1,5 +1,8 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.7.2 + * No changes + version 2.7.1 * Chinese (Hong Kong) translation updated (Ambrose C. Li, Paladin R. Liu) diff -r 47fc498fc34b -r fdc865966b01 po/de.po --- a/po/de.po Tue Jul 20 02:48:15 2010 +0000 +++ b/po/de.po Sun Jul 25 01:11:18 2010 +0000 @@ -11,14 +11,14 @@ msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-05-30 23:15-0400\n" -"PO-Revision-Date: 2010-05-29 17:30+0200\n" +"POT-Creation-Date: 2010-07-20 19:00+0200\n" +"PO-Revision-Date: 2010-07-20 18:52+0200\n" "Last-Translator: Björn Voigt \n" "Language-Team: Deutsch \n" -"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Translators may want to transliterate the name. @@ -65,12 +65,27 @@ msgid "Error" msgstr "Fehler" +msgid "Account was not modified" +msgstr "Konto wurde nicht modifiziert" + msgid "Account was not added" msgstr "Konto wurde nicht hinzugefügt" msgid "Username of an account must be non-empty." msgstr "Benutzername eines Kontos darf nicht leer sein." +msgid "" +"The account's protocol cannot be changed while it is connected to the server." +msgstr "" +"Das Protokoll des Kontos kann nicht geändert werden solange das Konto mit " +"dem Server verbunden ist." + +msgid "" +"The account's username cannot be changed while it is connected to the server." +msgstr "" +"Der Benutzername des Kontos kann nicht geändert werden solange das Konto mit " +"dem Server verbunden ist." + msgid "New mail notifications" msgstr "Benachrichtigung über neue Mails" @@ -1269,6 +1284,9 @@ msgid "Someone says your username in chat" msgstr "Jemand nennt Ihren Benutzernamen im Chat" +msgid "Attention received" +msgstr "Aufmerksamkeitsgesuch erhalten" + msgid "GStreamer Failure" msgstr "GStreamer-Fehler" @@ -1685,8 +1703,12 @@ "Diesem Zertifikat wird nicht vertraut, da kein Zertifikat bestätigen kann, " "dass ihm aktuell vertraut wird." -msgid "The certificate is not valid yet." -msgstr "Das Zertifikat ist noch nicht gültig." +msgid "" +"The certificate is not valid yet. Check that your computer's date and time " +"are accurate." +msgstr "" +"Das Zertifikat ist nicht mehr gültig. Überprüfen Sie, ob Datum und Zeit " +"Ihres Computers stimmen." msgid "The certificate has expired and should not be considered valid." msgstr "" @@ -3857,6 +3879,19 @@ "Der Server ist der Meinung, dass die Authentifizierung vollständig ist, der " "Client aber nicht" +msgid "Server may require plaintext authentication over an unencrypted stream" +msgstr "" +"Der Server könnte eine Klartext-Authentifizierung über einen " +"unverschlüsselten Kanal anfordern" + +#, c-format +msgid "" +"%s may require plaintext authentication over an unencrypted connection. " +"Allow this and continue authentication?" +msgstr "" +"%s könnte eine Klartext-Authentifizierung über einen unverschlüsselten Kanal " +"anfordern. Wollen Sie dies erlauben und mit der Authentifikation fortfahren?" + msgid "SASL authentication failed" msgstr "SASL-Authentifizierung fehlgeschlagen" @@ -6175,17 +6210,14 @@ msgstr "Startbildschirm-Popup aktivieren" #. you were kicked -#, fuzzy msgid "You have been kicked from this MultiMX." -msgstr "Sie wurden hinausgeworfen: (%s)" - -#, fuzzy +msgstr "Sie wurden von MultiMX hinausgeworfen." + msgid "was kicked" -msgstr "Falsches Ticket" - -#, fuzzy +msgstr "wurde hinausgeworfen" + msgid "_Room Name:" -msgstr "_Raum:" +msgstr "_Raumname:" #. we must have lost the connection, so terminate it so that we can reconnect msgid "We have lost the connection to MXit. Please reconnect." @@ -6767,8 +6799,8 @@ #, c-format msgid "Unable to send message. Could not get details for user (%s)." msgstr "" -"Kann die Nachricht nicht senden. Kann die Details vom Benutzer nicht holen " -"(%s)." +"Kann die Nachricht nicht senden. Kann die Details vom Benutzer nicht holen (%" +"s)." #, c-format msgid "Unable to add %s to your buddy list (%s)." @@ -6786,8 +6818,8 @@ #, c-format msgid "Unable to send message to %s. Could not create the conference (%s)." msgstr "" -"Kann die Nachricht nicht an %s senden. Kann die Konferenz nicht erstellen " -"(%s)." +"Kann die Nachricht nicht an %s senden. Kann die Konferenz nicht erstellen (%" +"s)." #, c-format msgid "Unable to send message. Could not create the conference (%s)." @@ -7200,8 +7232,8 @@ "(There was an error receiving this message. Either you and %s have " "different encodings selected, or %s has a buggy client.)" msgstr "" -"(Es gab einen Fehler beim Empfang dieser Nachricht. Entweder haben Sie und " -"%s unterschiedliche Kodierungen gesetzt oder %s hat einen fehlerhaften " +"(Es gab einen Fehler beim Empfang dieser Nachricht. Entweder haben Sie und %" +"s unterschiedliche Kodierungen gesetzt oder %s hat einen fehlerhaften " "Client.)" #. Label @@ -7512,10 +7544,10 @@ msgid_plural "" "You missed %hu messages from %s because the rate limit has been exceeded." msgstr[0] "" -"Sie haben %hu Nachricht von %s nicht erhalten, da die Senderate " +"Sie haben %hu Nachricht von %s nicht erhalten, da die Datenrate " "überschritten wurde." msgstr[1] "" -"Sie haben %hu Nachrichten von %s nicht erhalten, da die Senderate " +"Sie haben %hu Nachrichten von %s nicht erhalten, da die Datenrate " "überschritten wurde." #, c-format @@ -7989,11 +8021,11 @@ msgid "Invalid SNAC" msgstr "Ungültiger SNAC" -msgid "Rate to host" -msgstr "Bewertung zum Host" - -msgid "Rate to client" -msgstr "Bewertung zum Client" +msgid "Server rate limit exceeded" +msgstr "Server-Datenrate überschritten" + +msgid "Client rate limit exceeded" +msgstr "Client-Datenrate überschritten" msgid "Service unavailable" msgstr "Dienst nicht verfügbar" @@ -8428,8 +8460,8 @@ #, c-format msgid "Joining Qun %u is approved by admin %u for %s" msgstr "" -"Das Betreten des Qun %u wurde vom Admin bestätigt wegen by admin %u for " -"%s" +"Das Betreten des Qun %u wurde vom Admin bestätigt wegen by admin %u for %" +"s" #, c-format msgid "Removed buddy %u." @@ -10283,8 +10315,8 @@ msgid "Ignore conference and chatroom invitations" msgstr "Konferenz- und Chateinladungen ignorieren" -msgid "Use account proxy for SSL connections" -msgstr "Proxy-Zugang für SSL-Verbindungen benutzen" +msgid "Use account proxy for HTTP and HTTPS connections" +msgstr "Proxy-Zugang für HTTP- und HTTPS-Verbindungen benutzen" msgid "Chat room list URL" msgstr "Chatraumliste (URL)" @@ -12501,8 +12533,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.

" +"copyrighted by its contributors, a list of whom is also distributed with %" +"s. There is no warranty for %s.

" msgstr "" "%s ist ein Nachrichtendienst, basierend auf libpurple, der die Verbindung zu " "mehreren Nachrichtendiensten gleichzeitig unterstützt. %s wird in C " @@ -13074,16 +13106,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 "" "Wollen Sie wirklich den Mitschnitt der Unterhaltung in %s, gestartet am %s, " "permanent löschen?" #, 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 "" "Wollen Sie wirklich den Systemmitschnitt, gestartet am %s, permanent löschen?" @@ -14003,9 +14035,6 @@ msgid "Custom Smiley Manager" msgstr "Verwaltung für benutzerdefinierte Smileys" -msgid "Attention received" -msgstr "Aufmerksamkeitsgesuch erhalten" - msgid "Select Buddy Icon" msgstr "Buddy-Icon auswählen" @@ -15429,13 +15458,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 "" "Fehler beim Installieren der Rechtschreibkontrolle ($R3).$\\rFalls ein " "erneuter Versuch fehlschlägt, finden Sie Anweisungen zur manuellen " -"Installation unter: http://developer.pidgin.im/wiki/Installing" -"%20Pidgin#manual_win32_spellcheck_installation" +"Installation unter: http://developer.pidgin.im/wiki/Installing%" +"20Pidgin#manual_win32_spellcheck_installation" #. Installer Subsection Text msgid "GTK+ Runtime (required if not present)" @@ -15515,6 +15544,15 @@ msgid "You do not have permission to uninstall this application." msgstr "Sie haben keine Berechtigung, diese Anwendung zu deinstallieren." +#~ msgid "The certificate is not valid yet." +#~ msgstr "Das Zertifikat ist noch nicht gültig." + +#~ msgid "Rate to host" +#~ msgstr "Bewertung zum Host" + +#~ msgid "Rate to client" +#~ msgstr "Bewertung zum Client" + #~ msgid "Unknown reason." #~ msgstr "Unbekannter Grund."