diff options
Diffstat (limited to 'protocols/msn/sb.c')
| -rw-r--r-- | protocols/msn/sb.c | 94 | 
1 files changed, 49 insertions, 45 deletions
diff --git a/protocols/msn/sb.c b/protocols/msn/sb.c index cb5789b8..898fb34f 100644 --- a/protocols/msn/sb.c +++ b/protocols/msn/sb.c @@ -1,7 +1,7 @@    /********************************************************************\    * BitlBee -- An IRC to other IM-networks gateway                     *    *                                                                    * -  * Copyright 2002-2005 Wilmer van der Gaast and others                * +  * Copyright 2002-2010 Wilmer van der Gaast and others                *    \********************************************************************/  /* MSN module - Switchboard server callbacks and utilities              */ @@ -26,33 +26,44 @@  #include <ctype.h>  #include "nogaim.h"  #include "msn.h" -#include "passport.h"  #include "md5.h" +#include "soap.h"  #include "invitation.h"  static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond ); -static int msn_sb_command( gpointer data, char **cmd, int num_parts ); -static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts ); +static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts ); +static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts ); -int msn_sb_write( struct msn_switchboard *sb, char *s, int len ) +int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... )  { +	va_list params; +	char *out; +	size_t len;  	int st; -	st = write( sb->fd, s, len ); +	va_start( params, fmt ); +	out = g_strdup_vprintf( fmt, params ); +	va_end( params ); +	 +	if( getenv( "BITLBEE_DEBUG" ) ) +		fprintf( stderr, "->SB%d:%s", sb->fd, out ); +	 +	len = strlen( out ); +	st = write( sb->fd, out, len ); +	g_free( out );  	if( st != len )  	{  		msn_sb_destroy( sb ); -		return( 0 ); +		return 0;  	} -	return( 1 ); +	return 1;  }  int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m )  {  	struct msn_data *md = ic->proto_data;  	struct msn_switchboard *sb; -	char buf[1024];  	/* FIXME: *CHECK* the reliability of using spare sb's! */  	if( ( sb = msn_sb_spare( ic ) ) ) @@ -60,8 +71,7 @@ int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m )  		debug( "Trying to use a spare switchboard to message %s", m->who );  		sb->who = g_strdup( m->who ); -		g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, m->who ); -		if( msn_sb_write( sb, buf, strlen( buf ) ) ) +		if( msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, m->who ) )  		{  			/* He/She should join the switchboard soon, let's queue the message. */  			sb->msgq = g_slist_append( sb->msgq, m ); @@ -72,8 +82,7 @@ int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m )  	debug( "Creating a new switchboard to message %s", m->who );  	/* If we reach this line, there was no spare switchboard, so let's make one. */ -	g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); -	if( !msn_write( ic, buf, strlen( buf ) ) ) +	if( !msn_ns_write( ic, -1, "XFR %d SB\r\n", ++md->trId ) )  	{  		g_free( m->who );  		g_free( m->text ); @@ -164,7 +173,7 @@ int msn_sb_sendmessage( struct msn_switchboard *sb, char *text )  {  	if( sb->ready )  	{ -		char *packet, *buf; +		char *buf;  		int i, j;  		/* Build the message. Convert LF to CR-LF for normal messages. */ @@ -200,17 +209,15 @@ int msn_sb_sendmessage( struct msn_switchboard *sb, char *text )  		}  		/* Build the final packet (MSG command + the message). */ -		packet = g_strdup_printf( "MSG %d N %d\r\n%s", ++sb->trId, i, buf ); -		g_free( buf ); -		if( msn_sb_write( sb, packet, strlen( packet ) ) ) +		if( msn_sb_write( sb, "MSG %d N %d\r\n%s", ++sb->trId, i, buf ) )  		{ -			g_free( packet ); -			return( 1 ); +			g_free( buf ); +			return 1;  		}  		else  		{ -			g_free( packet ); -			return( 0 ); +			g_free( buf ); +			return 0;  		}  	}  	else if( sb->who ) @@ -325,7 +332,7 @@ gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond )  	else  		g_snprintf( buf, sizeof( buf ), "ANS %d %s %s %d\r\n", ++sb->trId, ic->acc->user, sb->key, sb->session ); -	if( msn_sb_write( sb, buf, strlen( buf ) ) ) +	if( msn_sb_write( sb, "%s", buf ) )  		sb->inp = b_input_add( sb->fd, B_EV_IO_READ, msn_sb_callback, sb );  	else  		debug( "Error %d while connecting to switchboard server", 2 ); @@ -345,7 +352,6 @@ static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition c  	if( sb->msgq != NULL )  	{  		time_t now = time( NULL ); -		char buf[1024];  		if( now - md->first_sb_failure > 600 )  		{ @@ -377,8 +383,7 @@ static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition c  		debug( "Moved queued messages back to the main queue, "  		       "creating a new switchboard to retry." ); -		g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId ); -		if( !msn_write( ic, buf, strlen( buf ) ) ) +		if( !msn_ns_write( ic, -1, "XFR %d SB\r\n", ++md->trId ) )  			return FALSE;  	} @@ -386,11 +391,10 @@ static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition c  	return FALSE;  } -static int msn_sb_command( gpointer data, char **cmd, int num_parts ) +static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts )  { -	struct msn_switchboard *sb = data; +	struct msn_switchboard *sb = handler->data;  	struct im_connection *ic = sb->ic; -	char buf[1024];  	if( !num_parts )  	{ @@ -406,7 +410,7 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  	}  	else if( strcmp( cmd[0], "USR" ) == 0 )  	{ -		if( num_parts != 5 ) +		if( num_parts < 5 )  		{  			msn_sb_destroy( sb );  			return( 0 ); @@ -419,20 +423,15 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  		}  		if( sb->who ) -		{ -			g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, sb->who ); -			return( msn_sb_write( sb, buf, strlen( buf ) ) ); -		} +			return msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, sb->who );  		else -		{  			debug( "Just created a switchboard, but I don't know what to do with it." ); -		}  	}  	else if( strcmp( cmd[0], "IRO" ) == 0 )  	{  		int num, tot; -		if( num_parts != 6 ) +		if( num_parts < 6 )  		{  			msn_sb_destroy( sb );  			return( 0 ); @@ -469,7 +468,7 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  	}  	else if( strcmp( cmd[0], "ANS" ) == 0 )  	{ -		if( num_parts != 3 ) +		if( num_parts < 3 )  		{  			msn_sb_destroy( sb );  			return( 0 ); @@ -488,7 +487,7 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  	}  	else if( strcmp( cmd[0], "CAL" ) == 0 )  	{ -		if( num_parts != 4 || !isdigit( cmd[3][0] ) ) +		if( num_parts < 4 || !isdigit( cmd[3][0] ) )  		{  			msn_sb_destroy( sb );  			return( 0 ); @@ -498,7 +497,7 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  	}  	else if( strcmp( cmd[0], "JOI" ) == 0 )  	{ -		if( num_parts != 3 ) +		if( num_parts < 3 )  		{  			msn_sb_destroy( sb );  			return( 0 ); @@ -559,7 +558,7 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  	}  	else if( strcmp( cmd[0], "MSG" ) == 0 )  	{ -		if( num_parts != 4 ) +		if( num_parts < 4 )  		{  			msn_sb_destroy( sb );  			return( 0 ); @@ -624,7 +623,12 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  		int num = atoi( cmd[0] );  		const struct msn_status_code *err = msn_status_by_number( num ); -		imcb_error( ic, "Error reported by switchboard server: %s", err->text ); +		/* If the person is offline, send an offline message instead, +		   and don't report an error. */ +		if( num == 217 ) +			msn_soap_oim_send_queue( ic, &sb->msgq ); +		else +			imcb_error( ic, "Error reported by switchboard server: %s", err->text );  		if( err->flags & STATUS_SB_FATAL )  		{ @@ -660,9 +664,9 @@ static int msn_sb_command( gpointer data, char **cmd, int num_parts )  	return( 1 );  } -static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts ) +static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts )  { -	struct msn_switchboard *sb = data; +	struct msn_switchboard *sb = handler->data;  	struct im_connection *ic = sb->ic;  	char *body;  	int blen = 0; @@ -740,8 +744,8 @@ static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int  #endif  		else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 )   		{ -			imcb_error( sb->ic, "Cannot receive file from %s: BitlBee does not " -					"support msnmsgrp2p yet.", sb->who ); +			/* Not currently implemented. Don't warn about it since +			   this seems to be used for avatars now. */  			g_free( ct );  		}  		else if( g_strncasecmp( ct, "text/x-msmsgscontrol", 20 ) == 0 )  | 
