diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2010-10-01 22:34:53 -0700 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2010-10-01 22:34:53 -0700 |
commit | 62f53b508742804d5df6533150f17d41e6afcbb2 (patch) | |
tree | e01a02a2a730110dde6ded977458090859fe2115 /protocols/msn/sb.c | |
parent | 05bf2a0d55999c944ac6cf03ad85270cb2165923 (diff) | |
parent | 04cd284bce74c114fde3043c951a5c8ef9eb79ae (diff) |
Merging msnp13 branch which, confusingly, upgrades the msn module to use
MSNP15. (The reason for this is that A) IMHO MSNP13 is what causes most of
the pain in this upgade and B) I initially intended to only implement MSNP13
but then discovered MS doesn't support it anymore.)
This fixes issues with display names being forgotten, adding contacts (and
them automatically getting blocked sometimes!!), and adds support for
away/status messages and some support for sending offline messages.
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 ) |