diff options
Diffstat (limited to 'libpurple/protocols/mxit/protocol.c')
-rw-r--r-- | libpurple/protocols/mxit/protocol.c | 193 |
1 files changed, 140 insertions, 53 deletions
diff --git a/libpurple/protocols/mxit/protocol.c b/libpurple/protocols/mxit/protocol.c index 166f54f472..851496dac2 100644 --- a/libpurple/protocols/mxit/protocol.c +++ b/libpurple/protocols/mxit/protocol.c @@ -445,7 +445,7 @@ static void mxit_queue_packet( struct MXitSession* session, const char* data, in 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 @@ gboolean mxit_manage_queue( gpointer user_data ) /* 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 @@ void mxit_send_register( struct MXitSession* session ) 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,12 +671,15 @@ void mxit_send_login( struct MXitSession* session ) 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", /* dialingcode\1locale */ + "%s%c%s%c" /* dialingcode\1locale\1 */ + "%i%c%i%c%i", /* maxReplyLen\1protocolVer\1lastRosterUpdate */ session->encpwd, CP_FLD_TERM, MXIT_CP_VERSION, CP_FLD_TERM, 1, CP_FLD_TERM, MXIT_CP_CAP, CP_FLD_TERM, session->distcode, CP_FLD_TERM, MXIT_CP_FEATURES, CP_FLD_TERM, - session->dialcode, CP_FLD_TERM, locale + session->dialcode, CP_FLD_TERM, locale, CP_FLD_TERM, + CP_MAX_FILESIZE, CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0 ); /* include "custom resource" information */ @@ -709,7 +713,8 @@ void mxit_send_message( struct MXitSession* session, const char* to, const char* 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 ); @@ -735,7 +740,8 @@ void mxit_send_extprofile_request( struct MXitSession* session, const char* user 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 */ @@ -765,7 +771,8 @@ void mxit_send_extprofile_update( struct MXitSession* session, const char* passw 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 ); @@ -795,7 +802,8 @@ void mxit_send_presence( struct MXitSession* session, int presence, const char* 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 ); @@ -820,7 +828,8 @@ void mxit_send_mood( struct MXitSession* session, int mood ) 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 ); @@ -843,7 +852,8 @@ void mxit_send_invite( struct MXitSession* session, const char* username, const 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, "" ); @@ -865,7 +875,8 @@ void mxit_send_remove( struct MXitSession* session, const char* username ) 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 ); @@ -887,7 +898,8 @@ void mxit_send_allow_sub( struct MXitSession* session, const char* username, con 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 ); @@ -908,7 +920,8 @@ void mxit_send_deny_sub( struct MXitSession* session, const char* username ) 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 ); @@ -931,7 +944,8 @@ void mxit_send_update_contact( struct MXitSession* session, const char* username 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 ); @@ -952,7 +966,8 @@ void mxit_send_splashclick( struct MXitSession* session, const char* splashid ) 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 ); @@ -962,6 +977,32 @@ void mxit_send_splashclick( struct MXitSession* session, const char* splashid ) /*------------------------------------------------------------------------ + * Send a message event packet. + * + * @param session The MXit session object + * @param to The username of the original sender (ie, recipient of the event) + * @param id The identifier of the event (received in message) + * @param event Identified the type of event + */ +void mxit_send_msgevent( struct MXitSession* session, const char* to, const char* id, int event) +{ + char data[CP_MAX_PACKET]; + int datalen; + + 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 = 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 + ); + + /* queue packet for transmission */ + mxit_queue_packet( session, data, datalen, CP_CMD_MSGEVENT ); +} + + +/*------------------------------------------------------------------------ * Send packet to create a MultiMX room. * * @param session The MXit session object @@ -976,7 +1017,8 @@ void mxit_send_groupchat_create( struct MXitSession* session, const char* groupn 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 ); @@ -1005,7 +1047,8 @@ void mxit_send_groupchat_invite( struct MXitSession* session, const char* roomid 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 ); @@ -1158,7 +1201,7 @@ void mxit_send_file_received( struct MXitSession* session, const char* fileid, s return; } - set_chunk_type( chunk, CP_CHUNK_RECIEVED ); + set_chunk_type( chunk, CP_CHUNK_RECEIVED ); set_chunk_length( chunk, size ); datalen += MXIT_CHUNK_HEADER_SIZE + size; @@ -1257,7 +1300,7 @@ static void mxit_parse_cmd_login( struct MXitSession* session, struct record** r 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 ); @@ -1266,6 +1309,19 @@ static void mxit_parse_cmd_login( struct MXitSession* session, struct record** r purple_connection_update_progress( session->con, _( "Successfully Logged In..." ), 3, 4 ); purple_connection_set_state( session->con, PURPLE_CONNECTED ); + /* save extra info if this is a HTTP connection */ + if ( session->http ) { + /* save the http server to use for this session */ + g_strlcpy( session->http_server, records[1]->fields[3]->data, sizeof( session->http_server ) ); + + /* save the session id */ + session->http_sesid = atoi( records[0]->fields[0]->data ); + } + + /* extract MXitId (from protocol 5.9) */ + if ( records[1]->fcount >= 9 ) + session->uid = g_strdup( records[1]->fields[8]->data ); + /* display the current splash-screen */ if ( splash_popup_enabled( session ) ) splash_display( session ); @@ -1290,15 +1346,6 @@ static void mxit_parse_cmd_login( struct MXitSession* session, struct record** r g_free( statusmsg2 ); } - /* save extra info if this is a HTTP connection */ - if ( session->http ) { - /* save the http server to use for this session */ - g_strlcpy( session->http_server, records[1]->fields[3]->data, sizeof( session->http_server ) ); - - /* save the session id */ - session->http_sesid = atoi( records[0]->fields[0]->data ); - } - /* retrieve our MXit profile */ mxit_send_extprofile_request( session, NULL, ARRAY_SIZE( profilelist ), profilelist ); } @@ -1355,6 +1402,12 @@ static void mxit_parse_cmd_message( struct MXitSession* session, struct record** return; } + if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) { + /* delivery notification is requested */ + if ( records[0]->fcount >= 4 ) + mxit_send_msgevent( session, records[0]->fields[0]->data, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED ); + } + /* create and initialise new markup struct */ mx = g_new0( struct RXMsgData, 1 ); mx->msg = g_string_sized_new( msglen ); @@ -1419,9 +1472,9 @@ static void mxit_parse_cmd_new_sub( struct MXitSession* session, struct record** /* 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 ) { @@ -1472,20 +1525,24 @@ static void mxit_parse_cmd_contact( struct MXitSession* session, struct record** /* 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 ); contact->mood = atoi( rec->fields[5]->data ); if ( rec->fcount > 6 ) { - /* added in protocol 5.9.0 - flags & subtype */ + /* added in protocol 5.9 - flags & subtype */ contact->flags = atoi( rec->fields[6]->data ); contact->subtype = rec->fields[7]->data[0]; } + if ( rec->fcount > 8 ) { + /* added in protocol 6.0 - reject message */ + contact->msg = g_strdup( rec->fields[8]->data ); + } /* add the contact to the buddy list */ if ( contact-> type == MXIT_TYPE_MULTIMX ) /* contact is a MultiMX room */ @@ -1525,12 +1582,13 @@ static void mxit_parse_cmd_presence( struct MXitSession* session, struct record* /* * 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 ); } } @@ -1548,10 +1606,21 @@ static void mxit_parse_cmd_extprofile( struct MXitSession* session, struct recor 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 ); - profile = g_new0( struct MXitProfile, 1 ); + 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; + } + else { + /* is a buddy's profile */ + profile = g_new0( struct MXitProfile, 1 ); + } /* set the count for attributes */ count = atoi( records[0]->fields[1]->data ); @@ -1593,8 +1662,13 @@ static void mxit_parse_cmd_extprofile( struct MXitSession* session, struct recor /* 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 */ @@ -1616,23 +1690,31 @@ static void mxit_parse_cmd_extprofile( struct MXitSession* session, struct recor /* mobile number */ g_strlcpy( profile->mobilenr, fvalue, sizeof( profile->mobilenr ) ); } + else if ( strcmp( CP_PROFILE_REGCOUNTRY, fname ) == 0 ) { + /* 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 ( records[0]->fields[0]->len == 0 ) { - /* no MXit id provided, so this must be our own profile information */ - if ( session->profile ) - g_free( session->profile ); - session->profile = profile; - } - else { - /* display other user's profile */ - mxit_show_profile( session, mxitId, profile ); + if ( profile != session->profile ) { + /* update avatar (if necessary) */ + if ( avatarId ) + mxit_update_buddy_avatar( session, mxitId, avatarId ); - /* cleanup */ + /* if this is not our profile, just display it */ + mxit_show_profile( session, mxitId, profile ); g_free( profile ); } } @@ -1752,7 +1834,7 @@ static void mxit_parse_cmd_media( struct MXitSession* session, struct record** r /* this is a ack for a file send. no action is required */ break; - case CP_CHUNK_RECIEVED : + case CP_CHUNK_RECEIVED : /* this is a ack for a file received. no action is required */ break; @@ -1917,6 +1999,8 @@ static int process_success_response( struct MXitSession* session, struct rx_pack /* profile update */ case CP_CMD_SPLASHCLICK : /* splash-screen clickthrough */ + case CP_CMD_MSGEVENT : + /* event message */ break; default : @@ -1962,12 +2046,12 @@ static int process_error_response( struct MXitSession* session, struct rx_packet 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 : @@ -2020,6 +2104,7 @@ static int process_error_response( struct MXitSession* session, struct rx_packet mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Profile Error" ), _( errdesc ) ); break; case CP_CMD_SPLASHCLICK : + case CP_CMD_MSGEVENT : /* ignore error */ break; case CP_CMD_PING : @@ -2438,6 +2523,8 @@ void mxit_close_connection( struct MXitSession* session ) mxit_free_emoticon_cache( session ); /* free allocated memory */ + if ( session->uid ) + g_free( session->uid ); g_free( session->encpwd ); session->encpwd = NULL; |