aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/msn/sb.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/msn/sb.c')
-rw-r--r--protocols/msn/sb.c94
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 )