Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/sb.c

    rf8cb76d rbae0617  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2005 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2727#include "nogaim.h"
    2828#include "msn.h"
    29 #include "passport.h"
    3029#include "md5.h"
     30#include "soap.h"
     31#include "invitation.h"
    3132
    3233static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond );
    33 static int msn_sb_command( gpointer data, char **cmd, int num_parts );
    34 static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
    35 
    36 int msn_sb_write( struct msn_switchboard *sb, char *s, int len )
    37 {
     34static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts );
     35static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts );
     36
     37int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... )
     38{
     39        va_list params;
     40        char *out;
     41        size_t len;
    3842        int st;
    3943       
    40         st = write( sb->fd, s, len );
     44        va_start( params, fmt );
     45        out = g_strdup_vprintf( fmt, params );
     46        va_end( params );
     47       
     48        if( getenv( "BITLBEE_DEBUG" ) )
     49                fprintf( stderr, "->SB%d:%s", sb->fd, out );
     50       
     51        len = strlen( out );
     52        st = write( sb->fd, out, len );
     53        g_free( out );
    4154        if( st != len )
    4255        {
    4356                msn_sb_destroy( sb );
    44                 return( 0 );
    45         }
    46        
    47         return( 1 );
     57                return 0;
     58        }
     59       
     60        return 1;
    4861}
    4962
     
    5265        struct msn_data *md = ic->proto_data;
    5366        struct msn_switchboard *sb;
    54         char buf[1024];
    5567
    5668        /* FIXME: *CHECK* the reliability of using spare sb's! */
     
    6072               
    6173                sb->who = g_strdup( m->who );
    62                 g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, m->who );
    63                 if( msn_sb_write( sb, buf, strlen( buf ) ) )
     74                if( msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, m->who ) )
    6475                {
    6576                        /* He/She should join the switchboard soon, let's queue the message. */
     
    7283       
    7384        /* If we reach this line, there was no spare switchboard, so let's make one. */
    74         g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
    75         if( !msn_write( ic, buf, strlen( buf ) ) )
     85        if( !msn_ns_write( ic, -1, "XFR %d SB\r\n", ++md->trId ) )
    7686        {
    7787                g_free( m->who );
     
    164174        if( sb->ready )
    165175        {
    166                 char *packet, *buf;
     176                char *buf;
    167177                int i, j;
    168178               
     
    177187                {
    178188                        buf = g_strdup( SB_KEEPALIVE_HEADERS );
     189                        i = strlen( buf );
     190                }
     191                else if( strncmp( text, MSN_INVITE_HEADERS, sizeof( MSN_INVITE_HEADERS ) - 1 ) == 0 )
     192                {
     193                        buf = g_strdup( text );
    179194                        i = strlen( buf );
    180195                }
     
    195210               
    196211                /* Build the final packet (MSG command + the message). */
    197                 packet = g_strdup_printf( "MSG %d N %d\r\n%s", ++sb->trId, i, buf );
    198                 g_free( buf );
    199                 if( msn_sb_write( sb, packet, strlen( packet ) ) )
    200                 {
    201                         g_free( packet );
    202                         return( 1 );
     212                if( msn_sb_write( sb, "MSG %d N %d\r\n%s", ++sb->trId, i, buf ) )
     213                {
     214                        g_free( buf );
     215                        return 1;
    203216                }
    204217                else
    205218                {
    206                         g_free( packet );
    207                         return( 0 );
     219                        g_free( buf );
     220                        return 0;
    208221                }
    209222        }
     
    227240{
    228241        struct im_connection *ic = sb->ic;
     242        struct groupchat *c = NULL;
    229243        char buf[1024];
    230244       
    231245        /* Create the groupchat structure. */
    232246        g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
    233         sb->chat = imcb_chat_new( ic, buf );
     247        if( sb->who )
     248                c = bee_chat_by_title( ic->bee, ic, sb->who );
     249        if( c && !msn_sb_by_chat( c ) )
     250                sb->chat = c;
     251        else
     252                sb->chat = imcb_chat_new( ic, buf );
    234253       
    235254        /* Populate the channel. */
     
    314333                g_snprintf( buf, sizeof( buf ), "ANS %d %s %s %d\r\n", ++sb->trId, ic->acc->user, sb->key, sb->session );
    315334       
    316         if( msn_sb_write( sb, buf, strlen( buf ) ) )
    317                 sb->inp = b_input_add( sb->fd, GAIM_INPUT_READ, msn_sb_callback, sb );
     335        if( msn_sb_write( sb, "%s", buf ) )
     336                sb->inp = b_input_add( sb->fd, B_EV_IO_READ, msn_sb_callback, sb );
    318337        else
    319338                debug( "Error %d while connecting to switchboard server", 2 );
     
    334353        {
    335354                time_t now = time( NULL );
    336                 char buf[1024];
    337355               
    338356                if( now - md->first_sb_failure > 600 )
     
    366384                debug( "Moved queued messages back to the main queue, "
    367385                       "creating a new switchboard to retry." );
    368                 g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
    369                 if( !msn_write( ic, buf, strlen( buf ) ) )
     386                if( !msn_ns_write( ic, -1, "XFR %d SB\r\n", ++md->trId ) )
    370387                        return FALSE;
    371388        }
     
    375392}
    376393
    377 static int msn_sb_command( gpointer data, char **cmd, int num_parts )
    378 {
    379         struct msn_switchboard *sb = data;
     394static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts )
     395{
     396        struct msn_switchboard *sb = handler->data;
    380397        struct im_connection *ic = sb->ic;
    381         char buf[1024];
    382398       
    383399        if( !num_parts )
     
    395411        else if( strcmp( cmd[0], "USR" ) == 0 )
    396412        {
    397                 if( num_parts != 5 )
     413                if( num_parts < 5 )
    398414                {
    399415                        msn_sb_destroy( sb );
     
    408424               
    409425                if( sb->who )
    410                 {
    411                         g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, sb->who );
    412                         return( msn_sb_write( sb, buf, strlen( buf ) ) );
    413                 }
     426                        return msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, sb->who );
    414427                else
    415                 {
    416428                        debug( "Just created a switchboard, but I don't know what to do with it." );
    417                 }
    418429        }
    419430        else if( strcmp( cmd[0], "IRO" ) == 0 )
     
    421432                int num, tot;
    422433               
    423                 if( num_parts != 6 )
     434                if( num_parts < 6 )
    424435                {
    425436                        msn_sb_destroy( sb );
     
    458469        else if( strcmp( cmd[0], "ANS" ) == 0 )
    459470        {
    460                 if( num_parts != 3 )
     471                if( num_parts < 3 )
    461472                {
    462473                        msn_sb_destroy( sb );
     
    477488        else if( strcmp( cmd[0], "CAL" ) == 0 )
    478489        {
    479                 if( num_parts != 4 || !isdigit( cmd[3][0] ) )
     490                if( num_parts < 4 || !isdigit( cmd[3][0] ) )
    480491                {
    481492                        msn_sb_destroy( sb );
     
    487498        else if( strcmp( cmd[0], "JOI" ) == 0 )
    488499        {
    489                 if( num_parts != 3 )
     500                if( num_parts < 3 )
    490501                {
    491502                        msn_sb_destroy( sb );
     
    548559        else if( strcmp( cmd[0], "MSG" ) == 0 )
    549560        {
    550                 if( num_parts != 4 )
     561                if( num_parts < 4 )
    551562                {
    552563                        msn_sb_destroy( sb );
     
    613624                const struct msn_status_code *err = msn_status_by_number( num );
    614625               
    615                 imcb_error( ic, "Error reported by switchboard server: %s", err->text );
     626                /* If the person is offline, send an offline message instead,
     627                   and don't report an error. */
     628                if( num == 217 )
     629                        msn_soap_oim_send_queue( ic, &sb->msgq );
     630                else
     631                        imcb_error( ic, "Error reported by switchboard server: %s", err->text );
    616632               
    617633                if( err->flags & STATUS_SB_FATAL )
     
    649665}
    650666
    651 static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts )
    652 {
    653         struct msn_switchboard *sb = data;
     667static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts )
     668{
     669        struct msn_switchboard *sb = handler->data;
    654670        struct im_connection *ic = sb->ic;
    655671        char *body;
     
    692708                        }
    693709                }
     710#if 0
     711                // Disable MSN ft support for now.
    694712                else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 )
    695713                {
    696                         char *itype = msn_findheader( body, "Application-GUID:", blen );
    697                         char buf[1024];
     714                        char *command = msn_findheader( body, "Invitation-Command:", blen );
     715                        char *cookie = msn_findheader( body, "Invitation-Cookie:", blen );
     716                        unsigned int icookie;
    698717                       
    699718                        g_free( ct );
    700719                       
    701                         *buf = 0;
    702                        
    703                         if( !itype )
    704                                 return( 1 );
    705                        
    706                         /* File transfer. */
    707                         if( strcmp( itype, "{5D3E02AB-6190-11d3-BBBB-00C04F795683}" ) == 0 )
    708                         {
    709                                 char *name = msn_findheader( body, "Application-File:", blen );
    710                                 char *size = msn_findheader( body, "Application-FileSize:", blen );
    711                                
    712                                 if( name && size )
    713                                 {
    714                                         g_snprintf( buf, sizeof( buf ), "<< \x02""BitlBee\x02"" - Filetransfer: `%s', %s bytes >>\n"
    715                                                     "Filetransfers are not supported by BitlBee for now...", name, size );
    716                                 }
    717                                 else
    718                                 {
    719                                         strcpy( buf, "<< \x02""BitlBee\x02"" - Corrupted MSN filetransfer invitation message >>" );
    720                                 }
    721                                
    722                                 if( name ) g_free( name );
    723                                 if( size ) g_free( size );
    724                         }
    725                         else
    726                         {
    727                                 char *iname = msn_findheader( body, "Application-Name:", blen );
    728                                
    729                                 g_snprintf( buf, sizeof( buf ), "<< \x02""BitlBee\x02"" - Unknown MSN invitation - %s (%s) >>",
    730                                                                 itype, iname ? iname : "no name" );
    731                                
    732                                 if( iname ) g_free( iname );
    733                         }
    734                        
    735                         g_free( itype );
    736                        
    737                         if( !*buf )
    738                                 return( 1 );
    739                        
    740                         if( sb->who )
    741                         {
    742                                 imcb_buddy_msg( ic, cmd[1], buf, 0, 0 );
    743                         }
    744                         else if( sb->chat )
    745                         {
    746                                 imcb_chat_msg( sb->chat, cmd[1], buf, 0, 0 );
    747                         }
    748                         else
    749                         {
    750                                 /* PANIC! */
    751                         }
     720                        /* Every invite should have both a Command and Cookie header */
     721                        if( !command || !cookie ) {
     722                                g_free( command );
     723                                g_free( cookie );
     724                                imcb_log( ic, "Warning: No command or cookie from %s", sb->who );
     725                                return 1;
     726                        }
     727                       
     728                        icookie = strtoul( cookie, NULL, 10 );
     729                        g_free( cookie );
     730                       
     731                        if( g_strncasecmp( command, "INVITE", 6 ) == 0 ) {
     732                                msn_invitation_invite( sb, cmd[1], icookie, body, blen );
     733                        } else if( g_strncasecmp( command, "ACCEPT", 6 ) == 0 ) {
     734                                msn_invitation_accept( sb, cmd[1], icookie, body, blen );
     735                        } else if( g_strncasecmp( command, "CANCEL", 6 ) == 0 ) {
     736                                msn_invitation_cancel( sb, cmd[1], icookie, body, blen );
     737                        } else {
     738                                imcb_log( ic, "Warning: Received invalid invitation with "
     739                                                "command %s from %s", command, sb->who );
     740                        }
     741                       
     742                        g_free( command );
     743                }
     744#endif
     745                else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 )
     746                {
     747                        /* Not currently implemented. Don't warn about it since
     748                           this seems to be used for avatars now. */
     749                        g_free( ct );
    752750                }
    753751                else if( g_strncasecmp( ct, "text/x-msmsgscontrol", 20 ) == 0 )
     
    780778void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial )
    781779{
    782         struct buddy *b;
     780        bee_user_t *bu;
    783781       
    784782        if( sb && sb->who && sb->keepalive == 0 &&
    785             ( b = imcb_find_buddy( sb->ic, sb->who ) ) && !b->present &&
     783            ( bu = bee_user_by_handle( sb->ic->bee, sb->ic, sb->who ) ) &&
     784            !( bu->flags & BEE_USER_ONLINE ) &&
    786785            set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) )
    787786        {
Note: See TracChangeset for help on using the changeset viewer.