comparison libpurple/protocols/mxit/protocol.c @ 32819:2c6510167895 default tip

propagate from branch 'im.pidgin.pidgin.2.x.y' (head 3315c5dfbd0ad16511bdcf865e5b07c02d07df24) to branch 'im.pidgin.pidgin' (head cbd1eda6bcbf0565ae7766396bb8f6f419cb6a9a)
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sat, 02 Jun 2012 02:30:49 +0000
parents 930820b18a8d
children
comparison
equal deleted inserted replaced
32818:01ff09d4a463 32819:2c6510167895
84 * @param username The username of the contact 84 * @param username The username of the contact
85 */ 85 */
86 void mxit_strip_domain( char* username ) 86 void mxit_strip_domain( char* username )
87 { 87 {
88 if ( g_str_has_suffix( username, "@m" ) ) 88 if ( g_str_has_suffix( username, "@m" ) )
89 username[ strlen(username) - 2 ] = '\0'; 89 username[ strlen( username ) - 2 ] = '\0';
90 } 90 }
91 91
92 92
93 /*------------------------------------------------------------------------ 93 /*------------------------------------------------------------------------
94 * Dump a byte buffer to the console for debugging purposes. 94 * Dump a byte buffer to the console for debugging purposes.
309 #ifdef DEBUG_PROTOCOL 309 #ifdef DEBUG_PROTOCOL
310 purple_debug_info( MXIT_PLUGIN_ID, "HTTP GET: '%s'\n", url ); 310 purple_debug_info( MXIT_PLUGIN_ID, "HTTP GET: '%s'\n", url );
311 #endif 311 #endif
312 312
313 /* send the HTTP request */ 313 /* send the HTTP request */
314 session->http_out_req = purple_util_fetch_url_request( url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, mxit_cb_http_rx, session ); 314 session->http_out_req = purple_util_fetch_url_request( session->acc, url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, -1, mxit_cb_http_rx, session );
315 315
316 g_free( url ); 316 g_free( url );
317 if ( part ) 317 if ( part )
318 g_free( part ); 318 g_free( part );
319 } 319 }
406 datalen = packet->headerlen + packet->datalen; 406 datalen = packet->headerlen + packet->datalen;
407 407
408 res = mxit_write_sock_packet( session->fd, data, datalen ); 408 res = mxit_write_sock_packet( session->fd, data, datalen );
409 if ( res < 0 ) { 409 if ( res < 0 ) {
410 /* we must have lost the connection, so terminate it so that we can reconnect */ 410 /* we must have lost the connection, so terminate it so that we can reconnect */
411 purple_connection_error( session->con, _( "We have lost the connection to MXit. Please reconnect." ) ); 411 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "We have lost the connection to MXit. Please reconnect." ) );
412 } 412 }
413 } 413 }
414 else { 414 else {
415 /* http connection */ 415 /* http connection */
416 416
456 packet->data = g_malloc0( datalen ); 456 packet->data = g_malloc0( datalen );
457 packet->cmd = cmd; 457 packet->cmd = cmd;
458 packet->headerlen = 0; 458 packet->headerlen = 0;
459 459
460 /* create generic packet header */ 460 /* create generic packet header */
461 hlen = snprintf( header, sizeof( header ), "id=%s%c", session->acc->username, CP_REC_TERM ); /* client msisdn */ 461 hlen = snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc), CP_REC_TERM ); /* client msisdn */
462 462
463 if ( session->http ) { 463 if ( session->http ) {
464 /* http connection only */ 464 /* http connection only */
465 hlen += sprintf( header + hlen, "s=" ); 465 hlen += sprintf( header + hlen, "s=" );
466 if ( session->http_sesid > 0 ) { 466 if ( session->http_sesid > 0 ) {
528 else if ( session->outack > 0 ) { 528 else if ( session->outack > 0 ) {
529 /* we are still waiting for an outstanding ACK from the MXit server */ 529 /* we are still waiting for an outstanding ACK from the MXit server */
530 if ( session->last_tx <= mxit_now_milli() - ( MXIT_ACK_TIMEOUT * 1000 ) ) { 530 if ( session->last_tx <= mxit_now_milli() - ( MXIT_ACK_TIMEOUT * 1000 ) ) {
531 /* ack timeout! so we close the connection here */ 531 /* ack timeout! so we close the connection here */
532 purple_debug_info( MXIT_PLUGIN_ID, "mxit_manage_queue: Timeout awaiting ACK for command '%i'\n", session->outack ); 532 purple_debug_info( MXIT_PLUGIN_ID, "mxit_manage_queue: Timeout awaiting ACK for command '%i'\n", session->outack );
533 purple_connection_error( session->con, _( "Timeout while waiting for a response from the MXit server." ) ); 533 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Timeout while waiting for a response from the MXit server." ) );
534 } 534 }
535 return; 535 return;
536 } 536 }
537 537
538 /* 538 /*
702 unsigned int features = MXIT_CP_FEATURES; 702 unsigned int features = MXIT_CP_FEATURES;
703 703
704 locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE ); 704 locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE );
705 705
706 /* Voice and Video supported */ 706 /* Voice and Video supported */
707 if (mxit_audio_enabled() && mxit_video_enabled()) 707 if ( mxit_audio_enabled() && mxit_video_enabled() )
708 features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO); 708 features |= ( MXIT_CF_VOICE | MXIT_CF_VIDEO );
709 else if (mxit_audio_enabled()) 709 else if ( mxit_audio_enabled() )
710 features |= MXIT_CF_VOICE; 710 features |= MXIT_CF_VOICE;
711 711
712 /* generate client version string (eg, P-2.7.10-Y-PURPLE) */ 712 /* generate client version string (eg, P-2.7.10-Y-PURPLE) */
713 clientVersion = g_strdup_printf( "%c-%i.%i.%i-%s-%s", MXIT_CP_DISTCODE, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CP_ARCH, MXIT_CP_PLATFORM ); 713 clientVersion = g_strdup_printf( "%c-%i.%i.%i-%s-%s", MXIT_CP_DISTCODE, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CP_ARCH, MXIT_CP_PLATFORM );
714 714
716 datalen = snprintf( data, sizeof( data ), 716 datalen = snprintf( data, sizeof( data ),
717 "ms=%s%c%s%c%i%c%s%c" /* "ms"=password\1version\1maxreplyLen\1name\1 */ 717 "ms=%s%c%s%c%i%c%s%c" /* "ms"=password\1version\1maxreplyLen\1name\1 */
718 "%s%c%i%c%s%c%s%c" /* dateOfBirth\1gender\1location\1capabilities\1 */ 718 "%s%c%i%c%s%c%s%c" /* dateOfBirth\1gender\1location\1capabilities\1 */
719 "%s%c%i%c%s%c%s" /* dc\1features\1dialingcode\1locale */ 719 "%s%c%i%c%s%c%s" /* dc\1features\1dialingcode\1locale */
720 "%c%i%c%i", /* \1protocolVer\1lastRosterUpdate */ 720 "%c%i%c%i", /* \1protocolVer\1lastRosterUpdate */
721 session->encpwd, CP_FLD_TERM, clientVersion, CP_FLD_TERM, CP_MAX_FILESIZE, CP_FLD_TERM, profile->nickname, CP_FLD_TERM, 721 session->encpwd, CP_FLD_TERM, clientVersion, CP_FLD_TERM, CP_MAX_PACKET, CP_FLD_TERM, profile->nickname, CP_FLD_TERM,
722 profile->birthday, CP_FLD_TERM, ( profile->male ) ? 1 : 0, CP_FLD_TERM, MXIT_DEFAULT_LOC, CP_FLD_TERM, MXIT_CP_CAP, CP_FLD_TERM, 722 profile->birthday, CP_FLD_TERM, ( profile->male ) ? 1 : 0, CP_FLD_TERM, MXIT_DEFAULT_LOC, CP_FLD_TERM, MXIT_CP_CAP, CP_FLD_TERM,
723 session->distcode, CP_FLD_TERM, features, CP_FLD_TERM, session->dialcode, CP_FLD_TERM, locale, 723 session->distcode, CP_FLD_TERM, features, CP_FLD_TERM, session->dialcode, CP_FLD_TERM, locale,
724 CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0 724 CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0
725 ); 725 );
726 726
746 unsigned int features = MXIT_CP_FEATURES; 746 unsigned int features = MXIT_CP_FEATURES;
747 747
748 locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE ); 748 locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE );
749 749
750 /* Voice and Video supported */ 750 /* Voice and Video supported */
751 if (mxit_audio_enabled() && mxit_video_enabled()) 751 if ( mxit_audio_enabled() && mxit_video_enabled() )
752 features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO); 752 features |= ( MXIT_CF_VOICE | MXIT_CF_VIDEO );
753 else if (mxit_audio_enabled()) 753 else if ( mxit_audio_enabled() )
754 features |= MXIT_CF_VOICE; 754 features |= MXIT_CF_VOICE;
755 755
756 /* generate client version string (eg, P-2.7.10-Y-PURPLE) */ 756 /* generate client version string (eg, P-2.7.10-Y-PURPLE) */
757 clientVersion = g_strdup_printf( "%c-%i.%i.%i-%s-%s", MXIT_CP_DISTCODE, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CP_ARCH, MXIT_CP_PLATFORM ); 757 clientVersion = g_strdup_printf( "%c-%i.%i.%i-%s-%s", MXIT_CP_DISTCODE, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CP_ARCH, MXIT_CP_PLATFORM );
758 758
763 "%s%c%s%c" /* dialingcode\1locale\1 */ 763 "%s%c%s%c" /* dialingcode\1locale\1 */
764 "%i%c%i%c%i", /* maxReplyLen\1protocolVer\1lastRosterUpdate */ 764 "%i%c%i%c%i", /* maxReplyLen\1protocolVer\1lastRosterUpdate */
765 session->encpwd, CP_FLD_TERM, clientVersion, CP_FLD_TERM, 1, CP_FLD_TERM, 765 session->encpwd, CP_FLD_TERM, clientVersion, CP_FLD_TERM, 1, CP_FLD_TERM,
766 MXIT_CP_CAP, CP_FLD_TERM, session->distcode, CP_FLD_TERM, features, CP_FLD_TERM, 766 MXIT_CP_CAP, CP_FLD_TERM, session->distcode, CP_FLD_TERM, features, CP_FLD_TERM,
767 session->dialcode, CP_FLD_TERM, locale, CP_FLD_TERM, 767 session->dialcode, CP_FLD_TERM, locale, CP_FLD_TERM,
768 CP_MAX_FILESIZE, CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0 768 CP_MAX_PACKET, CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0
769 ); 769 );
770 770
771 /* include "custom resource" information */ 771 /* include "custom resource" information */
772 splashId = splash_current( session ); 772 splashId = splash_current( session );
773 if ( splashId != NULL ) 773 if ( splashId != NULL )
833 ( username ? username : "" ), CP_FLD_TERM, nr_attrib 833 ( username ? username : "" ), CP_FLD_TERM, nr_attrib
834 ); 834 );
835 835
836 /* add attributes */ 836 /* add attributes */
837 for ( i = 0; i < nr_attrib; i++ ) 837 for ( i = 0; i < nr_attrib; i++ )
838 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); 838 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
839 839
840 /* queue packet for transmission */ 840 /* queue packet for transmission */
841 mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_GET ); 841 mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_GET );
842 } 842 }
843 843
866 ( password ) ? password : "", CP_FLD_TERM, nr_attrib 866 ( password ) ? password : "", CP_FLD_TERM, nr_attrib
867 ); 867 );
868 868
869 /* add attributes */ 869 /* add attributes */
870 for ( i = 1; i < nr_attrib * 3; i+=3 ) 870 for ( i = 1; i < nr_attrib * 3; i+=3 )
871 datalen += sprintf( data + datalen, "%c%s%c%s%c%s", /* \1name\1type\1value */ 871 datalen += sprintf( data + datalen, "%c%s%c%s%c%s", /* \1name\1type\1value */
872 CP_FLD_TERM, parts[i], CP_FLD_TERM, parts[i + 1], CP_FLD_TERM, parts[i + 2] ); 872 CP_FLD_TERM, parts[i], CP_FLD_TERM, parts[i + 1], CP_FLD_TERM, parts[i + 2] );
873 873
874 /* queue packet for transmission */ 874 /* queue packet for transmission */
875 mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_SET ); 875 mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_SET );
876 876
898 "ms=%i%c%s%c%i%c%i%c%i", /* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */ 898 "ms=%i%c%s%c%i%c%i%c%i", /* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */
899 CP_SUGGEST_FRIENDS, CP_FLD_TERM, "", CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib ); 899 CP_SUGGEST_FRIENDS, CP_FLD_TERM, "", CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib );
900 900
901 /* add attributes */ 901 /* add attributes */
902 for ( i = 0; i < nr_attrib; i++ ) 902 for ( i = 0; i < nr_attrib; i++ )
903 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); 903 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
904 904
905 /* queue packet for transmission */ 905 /* queue packet for transmission */
906 mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS ); 906 mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS );
907 } 907 }
908 908
927 "ms=%i%c%s%c%i%c%i%c%i", /* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */ 927 "ms=%i%c%s%c%i%c%i%c%i", /* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */
928 CP_SUGGEST_SEARCH, CP_FLD_TERM, text, CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib ); 928 CP_SUGGEST_SEARCH, CP_FLD_TERM, text, CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib );
929 929
930 /* add attributes */ 930 /* add attributes */
931 for ( i = 0; i < nr_attrib; i++ ) 931 for ( i = 0; i < nr_attrib; i++ )
932 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); 932 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] );
933 933
934 /* queue packet for transmission */ 934 /* queue packet for transmission */
935 mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS ); 935 mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS );
936 } 936 }
937 937
1173 groupname, CP_FLD_TERM, nr_usernames 1173 groupname, CP_FLD_TERM, nr_usernames
1174 ); 1174 );
1175 1175
1176 /* add usernames */ 1176 /* add usernames */
1177 for ( i = 0; i < nr_usernames; i++ ) 1177 for ( i = 0; i < nr_usernames; i++ )
1178 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] ); 1178 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
1179 1179
1180 /* queue packet for transmission */ 1180 /* queue packet for transmission */
1181 mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_CREATE ); 1181 mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_CREATE );
1182 } 1182 }
1183 1183
1202 roomid, CP_FLD_TERM, nr_usernames 1202 roomid, CP_FLD_TERM, nr_usernames
1203 ); 1203 );
1204 1204
1205 /* add usernames */ 1205 /* add usernames */
1206 for ( i = 0; i < nr_usernames; i++ ) 1206 for ( i = 0; i < nr_usernames; i++ )
1207 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] ); 1207 datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] );
1208 1208
1209 /* queue packet for transmission */ 1209 /* queue packet for transmission */
1210 mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_INVITE ); 1210 mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_INVITE );
1211 } 1211 }
1212 1212
1446 static void mxit_parse_cmd_login( struct MXitSession* session, struct record** records, int rcount ) 1446 static void mxit_parse_cmd_login( struct MXitSession* session, struct record** records, int rcount )
1447 { 1447 {
1448 PurpleStatus* status; 1448 PurpleStatus* status;
1449 int presence; 1449 int presence;
1450 const char* statusmsg; 1450 const char* statusmsg;
1451 const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_HIDENUMBER, CP_PROFILE_FULLNAME, 1451 const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME,
1452 CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL, 1452 CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL,
1453 CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_FLAGS }; 1453 CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_FLAGS };
1454 1454
1455 purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN ); 1455 purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN );
1456 1456
1514 */ 1514 */
1515 static void mxit_parse_cmd_message( struct MXitSession* session, struct record** records, int rcount ) 1515 static void mxit_parse_cmd_message( struct MXitSession* session, struct record** records, int rcount )
1516 { 1516 {
1517 struct RXMsgData* mx = NULL; 1517 struct RXMsgData* mx = NULL;
1518 char* message = NULL; 1518 char* message = NULL;
1519 char* sender = NULL;
1519 int msglen = 0; 1520 int msglen = 0;
1520 int msgflags = 0; 1521 int msgflags = 0;
1521 int msgtype = 0; 1522 int msgtype = 0;
1522 1523
1523 if ( ( rcount == 1 ) || ( records[0]->fcount < 2 ) || ( records[1]->fcount == 0 ) || ( records[1]->fields[0]->len == 0 ) ) { 1524 if ( ( rcount == 1 ) || ( records[0]->fcount < 2 ) || ( records[1]->fcount == 0 ) || ( records[1]->fields[0]->len == 0 ) ) {
1527 1528
1528 message = records[1]->fields[0]->data; 1529 message = records[1]->fields[0]->data;
1529 msglen = strlen( message ); 1530 msglen = strlen( message );
1530 1531
1531 /* strip off dummy domain */ 1532 /* strip off dummy domain */
1532 mxit_strip_domain( records[0]->fields[0]->data ); 1533 sender = records[0]->fields[0]->data;
1534 mxit_strip_domain( sender );
1533 1535
1534 #ifdef DEBUG_PROTOCOL 1536 #ifdef DEBUG_PROTOCOL
1535 purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", records[0]->fields[0]->data ); 1537 purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", sender );
1536 #endif 1538 #endif
1537 1539
1538 /* decode message flags (if any) */ 1540 /* decode message flags (if any) */
1539 if ( records[0]->fcount >= 5 ) 1541 if ( records[0]->fcount >= 5 )
1540 msgflags = atoi( records[0]->fields[4]->data ); 1542 msgflags = atoi( records[0]->fields[4]->data );
1541 msgtype = atoi( records[0]->fields[2]->data ); 1543 msgtype = atoi( records[0]->fields[2]->data );
1542 1544
1543 if ( msgflags & CP_MSG_ENCRYPTED ) { 1545 if ( msgflags & CP_MSG_PWD_ENCRYPTED ) {
1544 /* this is an encrypted message. we do not currently support those so ignore it */ 1546 /* this is a password encrypted message. we do not currently support those so ignore it */
1545 PurpleBuddy* buddy; 1547 PurpleBuddy* buddy;
1546 const char* name; 1548 const char* name;
1547 char msg[128]; 1549 char msg[128];
1548 1550
1549 buddy = purple_find_buddy( session->acc, records[0]->fields[0]->data ); 1551 buddy = purple_find_buddy( session->acc, sender );
1550 if ( buddy ) 1552 if ( buddy )
1551 name = purple_buddy_get_alias( buddy ); 1553 name = purple_buddy_get_alias( buddy );
1552 else 1554 else
1553 name = records[0]->fields[0]->data; 1555 name = sender;
1554 g_snprintf( msg, sizeof( msg ), _( "%s sent you an encrypted message, but it is not supported on this client." ), name ); 1556 g_snprintf( msg, sizeof( msg ), _( "%s sent you an encrypted message, but it is not supported on this client." ), name );
1555 mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Message Error" ), msg ); 1557 mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Message Error" ), msg );
1556 return; 1558 return;
1557 } 1559 }
1560 else if ( msgflags & CP_MSG_TL_ENCRYPTED ) {
1561 /* this is a transport-layer encrypted message. */
1562 message = mxit_decrypt_message( session, message );
1563 if ( !message ) {
1564 /* could not be decrypted */
1565 serv_got_im( session->con, sender, _( "An encrypted message was received which could not be decrypted." ), PURPLE_MESSAGE_ERROR, time( NULL ) );
1566 return;
1567 }
1568 }
1558 1569
1559 if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) { 1570 if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) {
1560 /* delivery notification is requested */ 1571 /* delivery notification is requested */
1561 if ( records[0]->fcount >= 4 ) 1572 if ( records[0]->fcount >= 4 )
1562 mxit_send_msgevent( session, records[0]->fields[0]->data, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED ); 1573 mxit_send_msgevent( session, sender, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED );
1563 } 1574 }
1564 1575
1565 /* create and initialise new markup struct */ 1576 /* create and initialise new markup struct */
1566 mx = g_new0( struct RXMsgData, 1 ); 1577 mx = g_new0( struct RXMsgData, 1 );
1567 mx->msg = g_string_sized_new( msglen ); 1578 mx->msg = g_string_sized_new( msglen );
1568 mx->session = session; 1579 mx->session = session;
1569 mx->from = g_strdup( records[0]->fields[0]->data ); 1580 mx->from = g_strdup( sender );
1570 mx->timestamp = atoi( records[0]->fields[1]->data ); 1581 mx->timestamp = atoi( records[0]->fields[1]->data );
1571 mx->got_img = FALSE; 1582 mx->got_img = FALSE;
1572 mx->chatid = -1; 1583 mx->chatid = -1;
1573 mx->img_count = 0; 1584 mx->img_count = 0;
1574 1585
1595 /* this means there are still images outstanding for this message and 1606 /* this means there are still images outstanding for this message and
1596 * still need to wait for them before we can display the message. 1607 * still need to wait for them before we can display the message.
1597 * so the image received callback function will eventually display 1608 * so the image received callback function will eventually display
1598 * the message. */ 1609 * the message. */
1599 } 1610 }
1611
1612 /* cleanup */
1613 if ( msgflags & CP_MSG_TL_ENCRYPTED )
1614 g_free( message );
1600 } 1615 }
1601 1616
1602 1617
1603 /*------------------------------------------------------------------------ 1618 /*------------------------------------------------------------------------
1604 * Process a received subscription request packet. 1619 * Process a received subscription request packet.
1631 g_strlcpy( contact->alias, rec->fields[1]->data, sizeof( contact->alias ) ); 1646 g_strlcpy( contact->alias, rec->fields[1]->data, sizeof( contact->alias ) );
1632 contact->type = atoi( rec->fields[2]->data ); 1647 contact->type = atoi( rec->fields[2]->data );
1633 1648
1634 if ( rec->fcount >= 5 ) { 1649 if ( rec->fcount >= 5 ) {
1635 /* there is a personal invite message attached */ 1650 /* there is a personal invite message attached */
1636 if ( ( rec->fields[4]->data ) && ( strlen( rec->fields[4]->data ) > 0 ) ) 1651 if ( ( rec->fields[4]->data ) && ( *rec->fields[4]->data ) )
1637 contact->msg = strdup( rec->fields[4]->data ); 1652 contact->msg = strdup( rec->fields[4]->data );
1638 } 1653 }
1639 1654
1640 /* handle the subscription */ 1655 /* handle the subscription */
1641 if ( contact-> type == MXIT_TYPE_MULTIMX ) { /* subscription to a MultiMX room */ 1656 if ( contact-> type == MXIT_TYPE_MULTIMX ) { /* subscription to a MultiMX room */
1808 } 1823 }
1809 else if ( strcmp( CP_PROFILE_GENDER, fname ) == 0 ) { 1824 else if ( strcmp( CP_PROFILE_GENDER, fname ) == 0 ) {
1810 /* gender */ 1825 /* gender */
1811 profile->male = ( fvalue[0] == '1' ); 1826 profile->male = ( fvalue[0] == '1' );
1812 } 1827 }
1813 else if ( strcmp( CP_PROFILE_HIDENUMBER, fname ) == 0 ) {
1814 /* hide number */
1815 profile->hidden = ( fvalue[0] == '1' );
1816 }
1817 else if ( strcmp( CP_PROFILE_FULLNAME, fname ) == 0 ) { 1828 else if ( strcmp( CP_PROFILE_FULLNAME, fname ) == 0 ) {
1818 /* nickname */ 1829 /* nickname */
1819 g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) ); 1830 g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) );
1820 } 1831 }
1821 else if ( strcmp( CP_PROFILE_STATUS, fname ) == 0 ) { 1832 else if ( strcmp( CP_PROFILE_STATUS, fname ) == 0 ) {
1877 struct contact* contact = NULL; 1888 struct contact* contact = NULL;
1878 1889
1879 contact = get_mxit_invite_contact( session, mxitId ); 1890 contact = get_mxit_invite_contact( session, mxitId );
1880 if ( contact ) { 1891 if ( contact ) {
1881 /* this is an invite, so update its profile info */ 1892 /* this is an invite, so update its profile info */
1882 if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) { 1893 if ( ( statusMsg ) && ( *statusMsg ) ) {
1883 /* update the status message */ 1894 /* update the status message */
1884 if ( contact->statusMsg ) 1895 if ( contact->statusMsg )
1885 g_free( contact->statusMsg ); 1896 g_free( contact->statusMsg );
1886 contact->statusMsg = strdup( statusMsg ); 1897 contact->statusMsg = strdup( statusMsg );
1887 } 1898 }
1888 else 1899 else
1889 contact->statusMsg = NULL; 1900 contact->statusMsg = NULL;
1890 if ( contact->profile ) 1901 if ( contact->profile )
1891 g_free( contact->profile ); 1902 g_free( contact->profile );
1892 contact->profile = profile; 1903 contact->profile = profile;
1893 if ( ( avatarId ) && ( strlen( avatarId ) > 0 ) ) { 1904 if ( ( avatarId ) && ( *avatarId ) ) {
1894 /* avatar must be requested for this invite before we can display it */ 1905 /* avatar must be requested for this invite before we can display it */
1895 mxit_get_avatar( session, mxitId, avatarId ); 1906 mxit_get_avatar( session, mxitId, avatarId );
1896 if ( contact->avatarId ) 1907 if ( contact->avatarId )
1897 g_free( contact->avatarId ); 1908 g_free( contact->avatarId );
1898 contact->avatarId = strdup( avatarId ); 1909 contact->avatarId = strdup( avatarId );
1906 else { 1917 else {
1907 /* this is a contact */ 1918 /* this is a contact */
1908 if ( avatarId ) 1919 if ( avatarId )
1909 mxit_update_buddy_avatar( session, mxitId, avatarId ); 1920 mxit_update_buddy_avatar( session, mxitId, avatarId );
1910 1921
1911 if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) { 1922 if ( ( statusMsg ) && ( *statusMsg ) ) {
1912 /* update the status message */ 1923 /* update the status message */
1913 PurpleBuddy* buddy = NULL; 1924 PurpleBuddy* buddy = NULL;
1914 1925
1915 buddy = purple_find_buddy( session->acc, mxitId ); 1926 buddy = purple_find_buddy( session->acc, mxitId );
1916 if ( buddy ) { 1927 if ( buddy ) {
2123 purple_debug_info( MXIT_PLUGIN_ID, "updating avatar for contact '%s'\n", chunk.mxitid ); 2134 purple_debug_info( MXIT_PLUGIN_ID, "updating avatar for contact '%s'\n", chunk.mxitid );
2124 2135
2125 contact = get_mxit_invite_contact( session, chunk.mxitid ); 2136 contact = get_mxit_invite_contact( session, chunk.mxitid );
2126 if ( contact ) { 2137 if ( contact ) {
2127 /* this is an invite (add image to the internal image store) */ 2138 /* this is an invite (add image to the internal image store) */
2128 contact->imgid = purple_imgstore_add_with_id( chunk.data, chunk.length, NULL ); 2139 contact->imgid = purple_imgstore_add_with_id( g_memdup( chunk.data, chunk.length ), chunk.length, NULL );
2129 /* show the profile */ 2140 /* show the profile */
2130 mxit_show_profile( session, chunk.mxitid, contact->profile ); 2141 mxit_show_profile( session, chunk.mxitid, contact->profile );
2131 } 2142 }
2132 else { 2143 else {
2133 /* this is a contact's avatar, so update it */ 2144 /* this is a contact's avatar, so update it */
2134 purple_buddy_icons_set_for_user( session->acc, chunk.mxitid, g_memdup( chunk.data, chunk.length), chunk.length, chunk.avatarid ); 2145 purple_buddy_icons_set_for_user( session->acc, chunk.mxitid, g_memdup( chunk.data, chunk.length ), chunk.length, chunk.avatarid );
2135 } 2146 }
2136 } 2147 }
2137 } 2148 }
2138 break; 2149 break;
2139 2150
2190 /* redirect to a MXit socket proxy */ 2201 /* redirect to a MXit socket proxy */
2191 g_strlcpy( session->server, &host[1][2], sizeof( session->server ) ); 2202 g_strlcpy( session->server, &host[1][2], sizeof( session->server ) );
2192 session->port = atoi( host[2] ); 2203 session->port = atoi( host[2] );
2193 } 2204 }
2194 else { 2205 else {
2195 purple_connection_error( session->con, _( "Cannot perform redirect using the specified protocol" ) ); 2206 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Cannot perform redirect using the specified protocol" ) );
2196 goto redirect_fail; 2207 goto redirect_fail;
2197 } 2208 }
2198 2209
2199 /* Part 2: type of redirect */ 2210 /* Part 2: type of redirect */
2200 type = atoi( parts[1] ); 2211 type = atoi( parts[1] );
2268 mxit_parse_cmd_contact( session, &packet->records[2], packet->rcount - 3 ); 2279 mxit_parse_cmd_contact( session, &packet->records[2], packet->rcount - 3 );
2269 break; 2280 break;
2270 2281
2271 case CP_CMD_PRESENCE : 2282 case CP_CMD_PRESENCE :
2272 /* presence update */ 2283 /* presence update */
2273 mxit_parse_cmd_presence(session, &packet->records[2], packet->rcount - 3 ); 2284 mxit_parse_cmd_presence( session, &packet->records[2], packet->rcount - 3 );
2274 break; 2285 break;
2275 2286
2276 case CP_CMD_RX_MSG : 2287 case CP_CMD_RX_MSG :
2277 /* incoming message (no bogus record) */ 2288 /* incoming message (no bogus record) */
2278 mxit_parse_cmd_message( session, &packet->records[2], packet->rcount - 2 ); 2289 mxit_parse_cmd_message( session, &packet->records[2], packet->rcount - 2 );
2359 2370
2360 purple_debug_info( MXIT_PLUGIN_ID, "Error Reply %i:%s\n", packet->errcode, errdesc ); 2371 purple_debug_info( MXIT_PLUGIN_ID, "Error Reply %i:%s\n", packet->errcode, errdesc );
2361 2372
2362 if ( packet->errcode == MXIT_ERRCODE_LOGGEDOUT ) { 2373 if ( packet->errcode == MXIT_ERRCODE_LOGGEDOUT ) {
2363 /* we are not currently logged in, so we need to reconnect */ 2374 /* we are not currently logged in, so we need to reconnect */
2364 purple_connection_error( session->con, _( errdesc ) ); 2375 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( errdesc ) );
2365 } 2376 }
2366 2377
2367 /* packet command */ 2378 /* packet command */
2368 switch ( packet->cmd ) { 2379 switch ( packet->cmd ) {
2369 2380
2373 mxit_perform_redirect( session, packet->errmsg ); 2384 mxit_perform_redirect( session, packet->errmsg );
2374 return 0; 2385 return 0;
2375 } 2386 }
2376 else { 2387 else {
2377 snprintf( errmsg, sizeof( errmsg ), _( "Login error: %s (%i)" ), errdesc, packet->errcode ); 2388 snprintf( errmsg, sizeof( errmsg ), _( "Login error: %s (%i)" ), errdesc, packet->errcode );
2378 purple_connection_error( session->con, errmsg ); 2389 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, errmsg );
2379 return -1; 2390 return -1;
2380 } 2391 }
2381 case CP_CMD_LOGOUT : 2392 case CP_CMD_LOGOUT :
2382 snprintf( errmsg, sizeof( errmsg ), _( "Logout error: %s (%i)" ), errdesc, packet->errcode ); 2393 snprintf( errmsg, sizeof( errmsg ), _( "Logout error: %s (%i)" ), errdesc, packet->errcode );
2383 purple_connection_error_reason( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) ); 2394 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NAME_IN_USE, _( errmsg ) );
2384 return -1; 2395 return -1;
2385 case CP_CMD_CONTACT : 2396 case CP_CMD_CONTACT :
2386 mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Contact Error" ), _( errdesc ) ); 2397 mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Contact Error" ), _( errdesc ) );
2387 break; 2398 break;
2388 case CP_CMD_RX_MSG : 2399 case CP_CMD_RX_MSG :
2641 i++; 2652 i++;
2642 } 2653 }
2643 2654
2644 if ( packet.rcount < 2 ) { 2655 if ( packet.rcount < 2 ) {
2645 /* bad packet */ 2656 /* bad packet */
2646 purple_connection_error( session->con, _( "Invalid packet received from MXit." ) ); 2657 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "Invalid packet received from MXit." ) );
2647 free_rx_packet( &packet ); 2658 free_rx_packet( &packet );
2648 continue; 2659 continue;
2649 } 2660 }
2650 2661
2651 session->rx_dbuf[session->rx_i] = '\0'; 2662 session->rx_dbuf[session->rx_i] = '\0';
2706 if ( session->rx_state == RX_STATE_RLEN ) { 2717 if ( session->rx_state == RX_STATE_RLEN ) {
2707 /* we are reading in the packet length */ 2718 /* we are reading in the packet length */
2708 len = read( session->fd, &ch, 1 ); 2719 len = read( session->fd, &ch, 1 );
2709 if ( len < 0 ) { 2720 if ( len < 0 ) {
2710 /* connection error */ 2721 /* connection error */
2711 purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x01)" ) ); 2722 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x01)" ) );
2712 return; 2723 return;
2713 } 2724 }
2714 else if ( len == 0 ) { 2725 else if ( len == 0 ) {
2715 /* connection closed */ 2726 /* connection closed */
2716 purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x02)" ) ); 2727 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x02)" ) );
2717 return; 2728 return;
2718 } 2729 }
2719 else { 2730 else {
2720 /* byte read */ 2731 /* byte read */
2721 if ( ch == CP_REC_TERM ) { 2732 if ( ch == CP_REC_TERM ) {
2722 /* the end of the length record found */ 2733 /* the end of the length record found */
2723 session->rx_lbuf[session->rx_i] = '\0'; 2734 session->rx_lbuf[session->rx_i] = '\0';
2724 session->rx_res = atoi( &session->rx_lbuf[3] ); 2735 session->rx_res = atoi( &session->rx_lbuf[3] );
2725 if ( session->rx_res > CP_MAX_PACKET ) { 2736 if ( session->rx_res > CP_MAX_PACKET ) {
2726 purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x03)" ) ); 2737 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x03)" ) );
2727 } 2738 }
2728 session->rx_state = RX_STATE_DATA; 2739 session->rx_state = RX_STATE_DATA;
2729 session->rx_i = 0; 2740 session->rx_i = 0;
2730 } 2741 }
2731 else { 2742 else {
2732 /* still part of the packet length record */ 2743 /* still part of the packet length record */
2733 session->rx_lbuf[session->rx_i] = ch; 2744 session->rx_lbuf[session->rx_i] = ch;
2734 session->rx_i++; 2745 session->rx_i++;
2735 if ( session->rx_i >= sizeof( session->rx_lbuf ) ) { 2746 if ( session->rx_i >= sizeof( session->rx_lbuf ) ) {
2736 /* malformed packet length record (too long) */ 2747 /* malformed packet length record (too long) */
2737 purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x04)" ) ); 2748 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x04)" ) );
2738 return; 2749 return;
2739 } 2750 }
2740 } 2751 }
2741 } 2752 }
2742 } 2753 }
2743 else if ( session->rx_state == RX_STATE_DATA ) { 2754 else if ( session->rx_state == RX_STATE_DATA ) {
2744 /* we are reading in the packet data */ 2755 /* we are reading in the packet data */
2745 len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res ); 2756 len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res );
2746 if ( len < 0 ) { 2757 if ( len < 0 ) {
2747 /* connection error */ 2758 /* connection error */
2748 purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x05)" ) ); 2759 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x05)" ) );
2749 return; 2760 return;
2750 } 2761 }
2751 else if ( len == 0 ) { 2762 else if ( len == 0 ) {
2752 /* connection closed */ 2763 /* connection closed */
2753 purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x06)" ) ); 2764 purple_connection_error( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _( "A connection error occurred to MXit. (read stage 0x06)" ) );
2754 return; 2765 return;
2755 } 2766 }
2756 else { 2767 else {
2757 /* data read */ 2768 /* data read */
2758 session->rx_i += len; 2769 session->rx_i += len;
2806 purple_util_fetch_url_cancel( (PurpleUtilFetchUrlData*) session->http_out_req ); 2817 purple_util_fetch_url_cancel( (PurpleUtilFetchUrlData*) session->http_out_req );
2807 session->http_out_req = NULL; 2818 session->http_out_req = NULL;
2808 } 2819 }
2809 2820
2810 /* remove the input cb function */ 2821 /* remove the input cb function */
2811 if ( session->con->inpa ) { 2822 if ( session->inpa ) {
2812 purple_input_remove( session->con->inpa ); 2823 purple_input_remove( session->inpa );
2813 session->con->inpa = 0; 2824 session->inpa = 0;
2814 } 2825 }
2815 2826
2816 /* remove HTTP poll timer */ 2827 /* remove HTTP poll timer */
2817 if ( session->http_timer_id > 0 ) 2828 if ( session->http_timer_id > 0 )
2818 purple_timeout_remove( session->http_timer_id ); 2829 purple_timeout_remove( session->http_timer_id );