--- a/libpurple/protocols/mxit/protocol.c Sat Jan 26 12:46:00 2013 +0200 +++ b/libpurple/protocols/mxit/protocol.c Wed Mar 27 01:37:02 2013 +0200 @@ -267,7 +267,7 @@ struct MXitSession* session = (struct MXitSession*) user_data; /* clear outstanding request */ - session->http_out_req = NULL; + session->async_calls = g_slist_remove( session->async_calls, url_data ); if ( ( !url_text ) || ( len == 0 ) ) { /* error with request */ @@ -293,6 +293,7 @@ */ static void mxit_write_http_get( struct MXitSession* session, struct tx_packet* packet ) { + PurpleUtilFetchUrlData* url_data; char* part = NULL; char* url = NULL; @@ -311,7 +312,9 @@ #endif /* send the HTTP request */ - session->http_out_req = purple_util_fetch_url_request( url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, mxit_cb_http_rx, session ); + url_data = purple_util_fetch_url_request( url, TRUE, MXIT_HTTP_USERAGENT, TRUE, NULL, FALSE, mxit_cb_http_rx, session ); + if ( url_data ) + session->async_calls = g_slist_prepend( session->async_calls, url_data ); g_free( url ); if ( part ) @@ -458,23 +461,23 @@ packet->headerlen = 0; /* create generic packet header */ - hlen = snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc ), CP_REC_TERM ); /* client msisdn */ + hlen = snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc ), CP_REC_TERM ); /* client mxitid */ if ( session->http ) { /* http connection only */ - hlen += sprintf( header + hlen, "s=" ); + hlen += snprintf( header + hlen, sizeof( header ) - hlen, "s=" ); if ( session->http_sesid > 0 ) { - hlen += sprintf( header + hlen, "%u%c", session->http_sesid, CP_FLD_TERM ); /* http session id */ + hlen += snprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_sesid, CP_FLD_TERM ); /* http session id */ } session->http_seqno++; - hlen += sprintf( header + hlen, "%u%c", session->http_seqno, CP_REC_TERM ); /* http request sequence id */ + hlen += snprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_seqno, CP_REC_TERM ); /* http request sequence id */ } - hlen += sprintf( header + hlen, "cm=%i%c", cmd, CP_REC_TERM ); /* packet command */ + hlen += snprintf( header + hlen, sizeof( header ) - hlen, "cm=%i%c", cmd, CP_REC_TERM ); /* packet command */ if ( !session->http ) { /* socket connection only */ - packet->headerlen += sprintf( packet->header, "ln=%i%c", ( datalen + hlen ), CP_REC_TERM ); /* packet length */ + packet->headerlen = snprintf( packet->header, sizeof( packet->header ), "ln=%i%c", ( datalen + hlen ), CP_REC_TERM ); /* packet length */ } /* copy the header to packet */ @@ -771,7 +774,7 @@ /* include "custom resource" information */ splashId = splash_current( session ); if ( splashId != NULL ) - datalen += sprintf( data + datalen, "%ccr=%s", CP_REC_TERM, splashId ); + datalen += snprintf( data + datalen, sizeof( data ) - datalen, "%ccr=%s", CP_REC_TERM, splashId ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_LOGIN ); @@ -835,7 +838,7 @@ /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_GET ); @@ -867,9 +870,16 @@ ); /* add attributes */ - for ( i = 1; i < nr_attrib * 3; i+=3 ) - datalen += sprintf( data + datalen, "%c%s%c%s%c%s", /* \1name\1type\1value */ + for ( i = 1; i < nr_attrib * 3; i+=3 ) { + if ( parts == NULL || parts[i] == NULL || parts[i + 1] == NULL || parts[i + 2] == NULL ) { + purple_debug_error( MXIT_PLUGIN_ID, "Invalid profile update attributes = '%s' - nbr=%u\n", attributes, nr_attrib ); + g_strfreev( parts ); + return; + } + datalen += snprintf( data + datalen, sizeof( data ) - datalen, + "%c%s%c%s%c%s", /* \1name\1type\1value */ CP_FLD_TERM, parts[i], CP_FLD_TERM, parts[i + 1], CP_FLD_TERM, parts[i + 2] ); + } /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_SET ); @@ -900,7 +910,7 @@ /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS ); @@ -929,7 +939,7 @@ /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS ); @@ -956,7 +966,7 @@ /* append status message (if one is set) */ if ( statusmsg ) - datalen += sprintf( data + datalen, "%s", statusmsg ); + datalen += snprintf( data + datalen, sizeof( data ) - datalen, "%s", statusmsg ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_STATUS ); @@ -1064,8 +1074,9 @@ * * @param session The MXit session object * @param username The username of the contact being denied + * @param reason The message describing the reason for the rejection (can be NULL). */ -void mxit_send_deny_sub( struct MXitSession* session, const char* username ) +void mxit_send_deny_sub( struct MXitSession* session, const char* username, const char* reason ) { char data[CP_MAX_PACKET]; int datalen; @@ -1076,6 +1087,10 @@ username ); + /* append reason (if one is set) */ + if ( reason ) + datalen += snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, reason ); + /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_DENY ); } @@ -1175,7 +1190,7 @@ /* add usernames */ for ( i = 0; i < nr_usernames; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] ); + datalen += snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, usernames[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_CREATE ); @@ -1204,7 +1219,7 @@ /* add usernames */ for ( i = 0; i < nr_usernames; i++ ) - datalen += sprintf( data + datalen, "%c%s", CP_FLD_TERM, usernames[i] ); + datalen += snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, usernames[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_GRPCHAT_INVITE ); @@ -1230,7 +1245,7 @@ purple_debug_info( MXIT_PLUGIN_ID, "SENDING FILE '%s' of %i bytes to user '%s'\n", filename, buflen, username ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=" ); + datalen = snprintf( data, sizeof( data ), "ms=" ); /* map chunk header over data buffer */ chunk = &data[datalen]; @@ -1266,7 +1281,7 @@ purple_debug_info( MXIT_PLUGIN_ID, "mxit_send_file_reject\n" ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=" ); + datalen = snprintf( data, sizeof( data ), "ms=" ); /* map chunk header over data buffer */ chunk = &data[datalen]; @@ -1304,7 +1319,7 @@ purple_debug_info( MXIT_PLUGIN_ID, "mxit_send_file_accept\n" ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=" ); + datalen = snprintf( data, sizeof( data ), "ms=" ); /* map chunk header over data buffer */ chunk = &data[datalen]; @@ -1340,7 +1355,7 @@ purple_debug_info( MXIT_PLUGIN_ID, "mxit_send_file_received\n" ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=" ); + datalen = snprintf( data, sizeof( data ), "ms=" ); /* map chunk header over data buffer */ chunk = &data[datalen]; @@ -1377,7 +1392,7 @@ purple_debug_info( MXIT_PLUGIN_ID, "mxit_set_avatar: %i bytes\n", avatarlen ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=" ); + datalen = snprintf( data, sizeof( data ), "ms=" ); /* map chunk header over data buffer */ chunk = &data[datalen]; @@ -1416,7 +1431,7 @@ purple_debug_info( MXIT_PLUGIN_ID, "mxit_get_avatar: %s\n", mxitId ); /* convert the packet to a byte stream */ - datalen = sprintf( data, "ms=" ); + datalen = snprintf( data, sizeof( data ), "ms=" ); /* map chunk header over data buffer */ chunk = &data[datalen]; @@ -2435,12 +2450,12 @@ return 0; } else { - snprintf( errmsg, sizeof( errmsg ), _( "Login error: %s (%i)" ), errdesc, packet->errcode ); + g_snprintf( errmsg, sizeof( errmsg ), _( "Login error: %s (%i)" ), errdesc, packet->errcode ); purple_connection_error_reason( session->con, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, errmsg ); return -1; } case CP_CMD_LOGOUT : - snprintf( errmsg, sizeof( errmsg ), _( "Logout error: %s (%i)" ), errdesc, packet->errcode ); + g_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 : @@ -2862,10 +2877,10 @@ } session->flags &= ~MXIT_FLAG_CONNECTED; - /* cancel outstanding HTTP request */ - if ( ( session->http ) && ( session->http_out_req ) ) { - purple_util_fetch_url_cancel( (PurpleUtilFetchUrlData*) session->http_out_req ); - session->http_out_req = NULL; + /* cancel all outstanding async calls */ + while ( session->async_calls ) { + purple_util_fetch_url_cancel( session->async_calls->data ); + session->async_calls = g_slist_delete_link(session->async_calls, session->async_calls); } /* remove the input cb function */