Changes in / [feb1bad:b0a89cc]


Ignore:
Files:
2 added
4 deleted
23 edited

Legend:

Unmodified
Added
Removed
  • configure

    rfeb1bad rb0a89cc  
    423423fi;
    424424
    425 if [ "$msn" = "1" -a "$ssl" != "openssl" ]; then
    426         # Needed for MSN only. OpenSSL exports nice cipher functions already,
    427         # others don't, so use our own 3des code.
    428         echo 'DES=des.o' >> Makefile.settings
    429 fi
    430 
    431425echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
    432426
  • doc/CHANGES

    rfeb1bad rb0a89cc  
    44http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on
    55
    6 Version ...
     6Version 1.3dev:
    77- For the first time since 2007, a dev snapshot. Like then, this is pretty
    88  stable already (running on testing.bitlbee.org for weeks by now), but not
     
    5252    for a list of supported protocols (works only in libpurple-enabled
    5353    binaries).
    54 - Rewritten MSN module, implementing MSNP15 instead of the old MSNP8:
    55   * MSNP8 support from MSN was getting pretty unreliable. There were issues
    56     with remembering display names and adding contacts/auth requests.
    57   * Support for sending offline messages.
    58   * Support for setting and reading status messages.
    5954- Support for file transfers, in and out. /DCC SEND a file to a contact and
    6055  it becomes a file transfer, and incoming file transfers become /DCC SENDs
     
    6459  fixes issues with authorization requests.
    6560
    66 Finished ...
     61Finished 6 Aug 2010
    6762
    6863Version 1.2.8:
  • lib/Makefile

    rfeb1bad rb0a89cc  
    1313
    1414# [SH] Program variables
    15 objects = arc.o base64.o $(DES) $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
     15objects = arc.o base64.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
    1616
    1717LFLAGS += -r
  • lib/misc.c

    rfeb1bad rb0a89cc  
    298298void http_encode( char *s )
    299299{
    300         char t[strlen(s)+1];
     300        char *t;
    301301        int i, j;
    302302       
    303         strcpy( t, s );
     303        t = g_strdup( s );
     304       
    304305        for( i = j = 0; t[i]; i ++, j ++ )
    305306        {
     
    319320        }
    320321        s[j] = 0;
     322       
     323        g_free( t );
    321324}
    322325
  • lib/sha1.c

    rfeb1bad rb0a89cc  
    3636 */
    3737
    38 #include <string.h>
    3938#include "sha1.h"
    4039
     
    375374        sha1_process_block(context);
    376375}
    377 
    378 #define HMAC_BLOCK_SIZE 64
    379 
    380 /* BitlBee addition: */
    381 void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t payload_len, uint8_t Message_Digest[sha1_hash_size])
    382 {
    383         sha1_state_t sha1;
    384         uint8_t hash[sha1_hash_size];
    385         uint8_t key[HMAC_BLOCK_SIZE+1];
    386         int i;
    387        
    388         if( key_len == 0 )
    389                 key_len = strlen( key_ );
    390         if( payload_len == 0 )
    391                 payload_len = strlen( payload );
    392        
    393         /* Create K. If our current key is >64 chars we have to hash it,
    394            otherwise just pad. */
    395         memset( key, 0, HMAC_BLOCK_SIZE + 1 );
    396         if( key_len > HMAC_BLOCK_SIZE )
    397         {
    398                 sha1_init( &sha1 );
    399                 sha1_append( &sha1, (uint8_t*) key_, key_len );
    400                 sha1_finish( &sha1, key );
    401         }
    402         else
    403         {
    404                 memcpy( key, key_, key_len );
    405         }
    406        
    407         /* Inner part: H(K XOR 0x36, text) */
    408         sha1_init( &sha1 );
    409         for( i = 0; i < HMAC_BLOCK_SIZE; i ++ )
    410                 key[i] ^= 0x36;
    411         sha1_append( &sha1, key, HMAC_BLOCK_SIZE );
    412         sha1_append( &sha1, (const uint8_t*) payload, payload_len );
    413         sha1_finish( &sha1, hash );
    414        
    415         /* Final result: H(K XOR 0x5C, inner stuff) */
    416         sha1_init( &sha1 );
    417         for( i = 0; i < HMAC_BLOCK_SIZE; i ++ )
    418                 key[i] ^= 0x36 ^ 0x5c;
    419         sha1_append( &sha1, key, HMAC_BLOCK_SIZE );
    420         sha1_append( &sha1, hash, sha1_hash_size );
    421         sha1_finish( &sha1, Message_Digest );
    422 }
  • lib/sha1.h

    rfeb1bad rb0a89cc  
    6767G_MODULE_EXPORT int sha1_append(sha1_state_t *, const uint8_t *, unsigned int);
    6868G_MODULE_EXPORT int sha1_finish(sha1_state_t *, uint8_t Message_Digest[sha1_hash_size]);
    69 G_MODULE_EXPORT void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t payload_len, uint8_t Message_Digest[sha1_hash_size]);
    7069
    7170#endif
  • lib/ssl_client.h

    rfeb1bad rb0a89cc  
    7878   the same action as the handler that just received the SSL_AGAIN.) */
    7979G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn );
    80 
    81 G_MODULE_EXPORT size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res);
  • lib/ssl_gnutls.c

    rfeb1bad rb0a89cc  
    189189                ssl_errno = SSL_AGAIN;
    190190       
    191         if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st );
    192        
    193191        return st;
    194192}
     
    209207        if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
    210208                ssl_errno = SSL_AGAIN;
    211        
    212         if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st );
    213209       
    214210        return st;
  • lib/ssl_openssl.c

    rfeb1bad rb0a89cc  
    116116        {
    117117                initialized = TRUE;
    118                 SSL_library_init();
    119                 //SSLeay_add_ssl_algorithms();
    120                 //OpenSSL_add_all_algorithms();
     118                SSLeay_add_ssl_algorithms();
    121119        }
    122120       
     
    207205        }
    208206       
    209         if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st );
    210        
    211207        return st;
    212208}
     
    223219       
    224220        st = SSL_write( ((struct scd*)conn)->ssl, buf, len );
    225        
    226         if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) write( 1, buf, st );
    227221       
    228222        ssl_errno = SSL_OK;
     
    278272        return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? B_EV_IO_WRITE : B_EV_IO_READ );
    279273}
    280 
    281 size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res)
    282 {
    283         int output_length = 0;   
    284         EVP_CIPHER_CTX ctx;
    285        
    286         *res = g_new0(unsigned char, 72);
    287        
    288         /* Don't set key or IV because we will modify the parameters */
    289         EVP_CIPHER_CTX_init(&ctx);
    290         EVP_CipherInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, NULL, NULL, 1);
    291         EVP_CIPHER_CTX_set_key_length(&ctx, key_len);
    292         EVP_CIPHER_CTX_set_padding(&ctx, 0);
    293         /* We finished modifying parameters so now we can set key and IV */
    294         EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, 1);
    295         EVP_CipherUpdate(&ctx, *res, &output_length, input, input_len);
    296         EVP_CipherFinal_ex(&ctx, *res, &output_length);
    297         EVP_CIPHER_CTX_cleanup(&ctx);   
    298         //EVP_cleanup();
    299        
    300         return output_length;
    301 }
  • lib/xmltree.c

    rfeb1bad rb0a89cc  
    141141/* Feed the parser, don't execute any handler. Returns -1 on errors, 0 on
    142142   end-of-stream and 1 otherwise. */
    143 int xt_feed( struct xt_parser *xt, const char *text, int text_len )
     143int xt_feed( struct xt_parser *xt, char *text, int text_len )
    144144{
    145145        if( !g_markup_parse_context_parse( xt->parser, text, text_len, &xt->gerr ) )
     
    174174        if( node->flags & XT_COMPLETE && !( node->flags & XT_SEEN ) )
    175175        {
    176                 if( xt->handlers ) for( i = 0; xt->handlers[i].func; i ++ )
     176                for( i = 0; xt->handlers[i].func; i ++ )
    177177                {
    178178                        /* This one is fun! \o/ */
    179179                       
    180                             /* If handler.name == NULL it means it should always match. */
     180                                                /* If handler.name == NULL it means it should always match. */
    181181                        if( ( xt->handlers[i].name == NULL ||
    182                               /* If it's not, compare. There should always be a name. */
     182                                                /* If it's not, compare. There should always be a name. */
    183183                              g_strcasecmp( xt->handlers[i].name, node->name ) == 0 ) &&
    184                             /* If handler.parent == NULL, it's a match. */
     184                                                /* If handler.parent == NULL, it's a match. */
    185185                            ( xt->handlers[i].parent == NULL ||
    186                               /* If there's a parent node, see if the name matches. */
     186                                                /* If there's a parent node, see if the name matches. */
    187187                              ( node->parent ? g_strcasecmp( xt->handlers[i].parent, node->parent->name ) == 0 :
    188                               /* If there's no parent, the handler should mention <root> as a parent. */
    189                                                strcmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) )
     188                                                /* If there's no parent, the handler should mention <root> as a parent. */
     189                                               g_strcasecmp( xt->handlers[i].parent, "<root>" ) == 0 ) ) )
    190190                        {
    191191                                st = xt->handlers[i].func( node, xt->data );
     
    260260}
    261261
    262 struct xt_node *xt_from_string( const char *in )
    263 {
    264         struct xt_parser *parser;
    265         struct xt_node *ret;
    266        
    267         parser = xt_new( NULL, NULL );
    268         xt_feed( parser, in, strlen( in ) );
    269         ret = parser->root;
    270         parser->root = NULL;
    271         xt_free( parser );
    272        
    273         return ret;
    274 }
    275 
    276262static void xt_to_string_real( struct xt_node *node, GString *str )
    277263{
     
    331317        /* Indentation */
    332318        for( c = node; c->parent; c = c->parent )
    333                 printf( "    " );
     319                printf( "\t" );
    334320       
    335321        /* Start the tag */
     
    338324        /* Print the attributes */
    339325        for( i = 0; node->attr[i].key; i ++ )
    340         {
    341                 char *v = g_markup_escape_text( node->attr[i].value, -1 );
    342                 printf( " %s=\"%s\"", node->attr[i].key, v );
    343                 g_free( v );
    344         }
     326                printf( " %s=\"%s\"", node->attr[i].key, g_markup_escape_text( node->attr[i].value, -1 ) );
    345327       
    346328        /* /> in case there's really *nothing* inside this tag, otherwise
     
    362344                for( i = 0; node->text[i] && isspace( node->text[i] ); i ++ );
    363345                if( node->text[i] )
    364                 {
    365                         char *v = g_markup_escape_text( node->text, -1 );
    366                         printf( "%s", v );
    367                         g_free( v );
    368                 }
     346                        printf( "%s", g_markup_escape_text( node->text, -1 ) );
    369347        }
    370348       
     
    377355        if( node->children )
    378356                for( c = node; c->parent; c = c->parent )
    379                         printf( "    " );
     357                        printf( "\t" );
    380358       
    381359        /* Non-empty tag is now finished. */
     
    482460               
    483461                node = node->next;
    484         }
    485        
    486         return node;
    487 }
    488 
    489 /* More advanced than the one above, understands something like
    490    ../foo/bar to find a subnode bar of a node foo which is a child
    491    of node's parent. Pass the node directly, not its list of children. */
    492 struct xt_node *xt_find_path( struct xt_node *node, const char *name )
    493 {
    494         while( name && *name && node )
    495         {
    496                 char *colon, *slash;
    497                 int n;
    498                
    499                 if( ( slash = strchr( name, '/' ) ) )
    500                         n = slash - name;
    501                 else
    502                         n = strlen( name );
    503                
    504                 if( strncmp( name, "..", n ) == 0 )
    505                 {
    506                         node = node->parent;
    507                 }
    508                 else
    509                 {
    510                         node = node->children;
    511                        
    512                         while( node )
    513                         {
    514                                 if( g_strncasecmp( node->name, name, n ) == 0 ||
    515                                     ( ( colon = strchr( node->name, ':' ) ) &&
    516                                       g_strncasecmp( colon + 1, name, n ) == 0 ) )
    517                                         break;
    518                                
    519                                 node = node->next;
    520                         }
    521                 }
    522                
    523                 name = slash ? slash + 1 : NULL;
    524462        }
    525463       
     
    612550}
    613551
    614 /* Same, but at the beginning. */
    615 void xt_insert_child( struct xt_node *parent, struct xt_node *child )
    616 {
    617         struct xt_node *node, *last;
    618        
    619         for( node = child; node; node = node->next )
    620         {
    621                 if( node->parent != NULL )
    622                 {
    623                         /* ERROR CONDITION: They seem to have a parent already??? */
    624                 }
    625                
    626                 node->parent = parent;
    627                 last = node;
    628         }
    629        
    630         last->next = parent->children;
    631         parent->children = child;
    632 }
    633 
    634552void xt_add_attr( struct xt_node *node, const char *key, const char *value )
    635553{
  • lib/xmltree.h

    rfeb1bad rb0a89cc  
    7979struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data );
    8080void xt_reset( struct xt_parser *xt );
    81 int xt_feed( struct xt_parser *xt, const char *text, int text_len );
     81int xt_feed( struct xt_parser *xt, char *text, int text_len );
    8282int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth );
    8383void xt_cleanup( struct xt_parser *xt, struct xt_node *node, int depth );
    84 struct xt_node *xt_from_string( const char *in );
    8584char *xt_to_string( struct xt_node *node );
    8685void xt_print( struct xt_node *node );
     
    8988void xt_free( struct xt_parser *xt );
    9089struct xt_node *xt_find_node( struct xt_node *node, const char *name );
    91 struct xt_node *xt_find_path( struct xt_node *node, const char *name );
    9290char *xt_find_attr( struct xt_node *node, const char *key );
    9391
    9492struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children );
    9593void xt_add_child( struct xt_node *parent, struct xt_node *child );
    96 void xt_insert_child( struct xt_node *parent, struct xt_node *child );
    9794void xt_add_attr( struct xt_node *node, const char *key, const char *value );
    9895int xt_remove_attr( struct xt_node *node, const char *key );
  • protocols/bee.h

    rfeb1bad rb0a89cc  
    151151 * - 'state' and 'message' can be NULL */
    152152G_MODULE_EXPORT void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message );
    153 G_MODULE_EXPORT void imcb_buddy_status_msg( struct im_connection *ic, const char *handle, const char *message );
    154153G_MODULE_EXPORT void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle );
    155154/* Call when a handle says something. 'flags' and 'sent_at may be just 0. */
  • protocols/bee_user.c

    rfeb1bad rb0a89cc  
    187187        /* TODO(wilmer): OPT_AWAY, or just state == NULL ? */
    188188        bu->flags = flags;
     189        bu->status = g_strdup( ( flags & OPT_AWAY ) && state == NULL ? "Away" : state );
    189190        bu->status_msg = g_strdup( message );
    190         if( state && *state )
    191                 bu->status = g_strdup( state );
    192         else if( flags & OPT_AWAY )
    193                 bu->status = g_strdup( "Away" );
    194         else
    195                 bu->status = NULL;
    196191       
    197192        if( bu->status == NULL && ( flags & OPT_MOBILE ) &&
     
    207202        g_free( old->status_msg );
    208203        g_free( old->status );
    209         g_free( old );
    210 }
    211 
    212 /* Same, but only change the away/status message, not any away/online state info. */
    213 void imcb_buddy_status_msg( struct im_connection *ic, const char *handle, const char *message )
    214 {
    215         bee_t *bee = ic->bee;
    216         bee_user_t *bu, *old;
    217        
    218         if( !( bu = bee_user_by_handle( bee, ic, handle ) ) )
    219         {
    220                 return;
    221         }
    222        
    223         old = g_memdup( bu, sizeof( bee_user_t ) );
    224        
    225         bu->status_msg = message && *message ? g_strdup( message ) : NULL;
    226        
    227         if( bee->ui->user_status )
    228                 bee->ui->user_status( bee, bu, old );
    229        
    230         g_free( old->status_msg );
    231204        g_free( old );
    232205}
  • protocols/msn/Makefile

    rfeb1bad rb0a89cc  
    1313
    1414# [SH] Program variables
    15 objects = msn.o msn_util.o ns.o sb.o soap.o tables.o
     15objects = msn.o msn_util.o ns.o passport.o sb.o tables.o
    1616
    1717LFLAGS += -r
  • protocols/msn/msn.c

    rfeb1bad rb0a89cc  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2525
    2626#include "nogaim.h"
    27 #include "soap.h"
    2827#include "msn.h"
    2928
     
    3635static void msn_init( account_t *acc )
    3736{
    38         set_t *s;
    39        
    40         s = set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc );
    41         s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY;
    42        
     37        set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc );
     38        set_add( &acc->set, "local_display_name", "false", set_eval_bool, acc );
    4339        set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
    4440        set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc );
    45        
    46         acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE;
    4741}
    4842
     
    7468        md->ic = ic;
    7569        md->away_state = msn_away_state_list;
    76         md->domaintree = g_tree_new( msn_domaintree_cmp );
    7770       
    7871        msn_connections = g_slist_append( msn_connections, ic );
     
    8376        struct msn_data *md = ic->proto_data;
    8477        GSList *l;
    85         int i;
    8678       
    8779        if( md )
     
    108100                msn_msgq_purge( ic, &md->msgq );
    109101               
    110                 for( i = 0; i < sizeof( md->tokens ) / sizeof( md->tokens[0] ); i ++ )
    111                         g_free( md->tokens[i] );
    112                 g_free( md->lock_key );
    113                
    114                 while( md->groups )
    115                 {
    116                         struct msn_group *mg = md->groups->data;
    117                         g_free( mg->id );
    118                         g_free( mg->name );
    119                         g_free( mg );
    120                         md->groups = g_slist_remove( md->groups, mg );
    121                 }
    122                
    123                 g_tree_destroy( md->domaintree );
    124                 md->domaintree = NULL;
     102                while( md->groupcount > 0 )
     103                        g_free( md->grouplist[--md->groupcount] );
     104                g_free( md->grouplist );
    125105               
    126106                while( md->grpq )
     
    194174{
    195175        char buf[1024];
    196         char *uux;
    197176        struct msn_data *md = ic->proto_data;
    198177       
     
    203182       
    204183        g_snprintf( buf, sizeof( buf ), "CHG %d %s\r\n", ++md->trId, md->away_state->code );
    205         if( !msn_write( ic, buf, strlen( buf ) ) )
    206                 return;
    207        
    208         uux = g_markup_printf_escaped( "<Data><PSM>%s</PSM><CurrentMedia></CurrentMedia>"
    209                                        "</Data>", message ? message : "" );
    210         g_snprintf( buf, sizeof( buf ), "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux );
    211         if( !msn_write( ic, buf, strlen( buf ) ) )
    212                 return;
     184        msn_write( ic, buf, strlen( buf ) );
     185}
     186
     187static void msn_set_my_name( struct im_connection *ic, char *info )
     188{
     189        msn_set_display_name( ic, info );
    213190}
    214191
     
    223200        struct bee_user *bu = bee_user_by_handle( ic->bee, ic, who );
    224201       
    225         msn_buddy_list_add( ic, MSN_BUDDY_FL, who, who, group );
     202        msn_buddy_list_add( ic, "FL", who, who, group );
    226203        if( bu && bu->group )
    227                 msn_buddy_list_remove( ic, MSN_BUDDY_FL, who, bu->group->name );
     204                msn_buddy_list_remove( ic, "FL", who, bu->group->name );
    228205}
    229206
    230207static void msn_remove_buddy( struct im_connection *ic, char *who, char *group )
    231208{
    232         msn_buddy_list_remove( ic, MSN_BUDDY_FL, who, NULL );
     209        msn_buddy_list_remove( ic, "FL", who, NULL );
    233210}
    234211
     
    295272static void msn_add_permit( struct im_connection *ic, char *who )
    296273{
    297         msn_buddy_list_add( ic, MSN_BUDDY_AL, who, who, NULL );
     274        msn_buddy_list_add( ic, "AL", who, who, NULL );
    298275}
    299276
    300277static void msn_rem_permit( struct im_connection *ic, char *who )
    301278{
    302         msn_buddy_list_remove( ic, MSN_BUDDY_AL, who, NULL );
     279        msn_buddy_list_remove( ic, "AL", who, NULL );
    303280}
    304281
     
    307284        struct msn_switchboard *sb;
    308285       
    309         msn_buddy_list_add( ic, MSN_BUDDY_BL, who, who, NULL );
     286        msn_buddy_list_add( ic, "BL", who, who, NULL );
    310287       
    311288        /* If there's still a conversation with this person, close it. */
     
    318295static void msn_rem_deny( struct im_connection *ic, char *who )
    319296{
    320         msn_buddy_list_remove( ic, MSN_BUDDY_BL, who, NULL );
     297        msn_buddy_list_remove( ic, "BL", who, NULL );
    321298}
    322299
     
    337314        account_t *acc = set->data;
    338315        struct im_connection *ic = acc->ic;
    339         struct msn_data *md = ic->proto_data;
     316       
     317        /* Allow any name if we're offline. */
     318        if( ic == NULL )
     319                return value;
    340320       
    341321        if( strlen( value ) > 129 )
     
    345325        }
    346326       
    347         if( md->flags & MSN_GOT_PROFILE_DN )
    348                 imcb_log( ic, "Warning: Persistent name changes for this account have to be done "
    349                               "in the profile. BitlBee doesn't currently support this." );
    350        
    351         msn_soap_addressbook_set_display_name( ic, value );
    352         return msn_ns_set_display_name( ic, value ) ? value : NULL;
    353 }
    354 
    355 static void msn_buddy_data_add( bee_user_t *bu )
    356 {
    357         struct msn_data *md = bu->ic->proto_data;
    358         bu->data = g_new0( struct msn_buddy_data, 1 );
    359         g_tree_insert( md->domaintree, bu->handle, bu );
    360 }
    361 
    362 static void msn_buddy_data_free( bee_user_t *bu )
    363 {
    364         struct msn_data *md = bu->ic->proto_data;
    365         g_tree_remove( md->domaintree, bu->handle );
    366         g_free( bu->data );
     327        /* Returning NULL would be better, because the server still has to
     328           confirm the name change. However, it looks a bit confusing to the
     329           user. */
     330        return msn_set_display_name( ic, value ) ? value : NULL;
    367331}
    368332
     
    379343        ret->set_away = msn_set_away;
    380344        ret->get_info = msn_get_info;
     345        ret->set_my_name = msn_set_my_name;
    381346        ret->add_buddy = msn_add_buddy;
    382347        ret->remove_buddy = msn_remove_buddy;
     
    392357        ret->send_typing = msn_send_typing;
    393358        ret->handle_cmp = g_strcasecmp;
    394         ret->buddy_data_add = msn_buddy_data_add;
    395         ret->buddy_data_free = msn_buddy_data_free;
    396        
    397359        //ret->transfer_request = msn_ftp_transfer_request;
    398360
  • protocols/msn/msn.h

    rfeb1bad rb0a89cc  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    3939#endif
    4040
    41 /* This should be MSN Messenger 7.0.0813
    42 #define MSNP11_PROD_KEY "CFHUR$52U_{VIX5T"
    43 #define MSNP11_PROD_ID  "PROD0101{0RM?UBW"
    44 */
    45 
    46 /* Some other version.
    47 #define MSNP11_PROD_KEY "O4BG@C7BWLYQX?5G"
    48 #define MSNP11_PROD_ID  "PROD01065C%ZFN6F"
    49 */
    50 
    51 #define MSNP11_PROD_KEY "ILTXC!4IXB5FB*PX"
    52 #define MSNP11_PROD_ID  "PROD0119GSJUC$18"
    53 #define MSNP_VER        "MSNP15"
    54 #define MSNP_BUILD      "8.5.1288"
     41#define QRY_NAME "msmsgs@msnmsgr.com"
     42#define QRY_CODE "Q1P7W2E4J9R8U3S5"
    5543
    5644#define MSN_SB_NEW         -24062002
     
    7361#define PROFILE_URL "http://members.msn.com/"
    7462
    75 typedef enum
    76 {
    77         MSN_GOT_PROFILE = 1,
    78         MSN_GOT_PROFILE_DN = 2,
    79         MSN_DONE_ADL = 4,
    80 } msn_flags_t;
    81 
    8263struct msn_data
    8364{
     
    8667        int fd;
    8768        struct msn_handler_data *handler;
    88         msn_flags_t flags;
    8969       
    9070        int trId;
    91         char *tokens[4];
    92         char *lock_key;
    9371       
    9472        GSList *msgq, *grpq;
     
    9674        int sb_failures;
    9775        time_t first_sb_failure;
     76        GSList *filetransfers;
    9877       
    9978        const struct msn_away_state *away_state;
    100         GSList *groups;
    101        
    102         /* Mostly used for sending the ADL command; since MSNP13 the client
    103            is responsible for downloading the contact list and then sending
    104            it to the MSNP server. */
    105         GTree *domaintree;
    106         int adl_todo;
     79        int buddycount;
     80        int groupcount;
     81        char **grouplist;
    10782};
    10883
     
    165140        int (*exec_command) ( gpointer data, char **cmd, int count );
    166141        int (*exec_message) ( gpointer data, char *msg, int msglen, char **cmd, int count );
    167 };
    168 
    169 typedef enum
    170 {
    171         MSN_BUDDY_FL = 1,   /* Warning: FL,AL,BL *must* be 1,2,4. */
    172         MSN_BUDDY_AL = 2,
    173         MSN_BUDDY_BL = 4,
    174         MSN_BUDDY_RL = 8,
    175         MSN_BUDDY_PL = 16,
    176         MSN_BUDDY_ADL_SYNCED = 256,
    177 } msn_buddy_flags_t;
    178 
    179 struct msn_buddy_data
    180 {
    181         char *cid;
    182         msn_buddy_flags_t flags;
    183 };
    184 
    185 struct msn_group
    186 {
    187         char *name;
    188         char *id;
    189142};
    190143
     
    209162/* ns.c */
    210163gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond );
    211 void msn_auth_got_passport_token( struct im_connection *ic, const char *token, const char *error );
    212 void msn_auth_got_contact_list( struct im_connection *ic );
    213 int msn_ns_finish_login( struct im_connection *ic );
    214164
    215165/* msn_util.c */
    216166int msn_write( struct im_connection *ic, char *s, int len );
    217167int msn_logged_in( struct im_connection *ic );
    218 int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname_, const char *group );
    219 int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group );
    220 void msn_buddy_ask( bee_user_t *bu );
     168int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *who, const char *realname_, const char *group );
     169int msn_buddy_list_remove( struct im_connection *ic, char *list, const char *who, const char *group );
     170void msn_buddy_ask( struct im_connection *ic, char *handle, char *realname );
    221171char *msn_findheader( char *text, char *header, int len );
    222172char **msn_linesplit( char *line );
    223173int msn_handler( struct msn_handler_data *h );
     174char *msn_http_encode( const char *input );
    224175void msn_msgq_purge( struct im_connection *ic, GSList **list );
    225 char *msn_p11_challenge( char *challenge );
    226 gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ );
    227 struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name );
    228 struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id );
    229 int msn_ns_set_display_name( struct im_connection *ic, const char *value );
     176gboolean msn_set_display_name( struct im_connection *ic, const char *rawname );
    230177
    231178/* tables.c */
     
    249196void msn_sb_stop_keepalives( struct msn_switchboard *sb );
    250197
     198/* invitation.c */
     199void msn_ftp_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who );
     200
    251201#endif //_MSN_H
  • protocols/msn/msn_util.c

    rfeb1bad rb0a89cc  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2626#include "nogaim.h"
    2727#include "msn.h"
    28 #include "md5.h"
    29 #include "soap.h"
    3028#include <ctype.h>
    3129
     
    3432        struct msn_data *md = ic->proto_data;
    3533        int st;
    36        
    37         if( getenv( "BITLBEE_DEBUG" ) )
    38         {
    39                 write( 2, "->NS:", 5 );
    40                 write( 2, s, len );
    41         }
    4234       
    4335        st = write( md->fd, s, len );
     
    5951}
    6052
    61 static char *adlrml_entry( const char *handle_, msn_buddy_flags_t list )
    62 {
    63         char *domain, handle[strlen(handle_)+1];
    64        
    65         strcpy( handle, handle_ );
    66         if( ( domain = strchr( handle, '@' ) ) )
    67                 *(domain++) = '\0';
    68         else
    69                 return NULL;
    70        
    71         return g_markup_printf_escaped( "<ml><d n=\"%s\"><c n=\"%s\" l=\"%d\" t=\"1\"/></d></ml>",
    72                 domain, handle, list );
    73 }
    74 
    75 int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname, const char *group )
     53int msn_buddy_list_add( struct im_connection *ic, const char *list, const char *who, const char *realname_, const char *group )
    7654{
    7755        struct msn_data *md = ic->proto_data;
    78         char buf[1024], groupid[8];
    79         bee_user_t *bu;
    80         struct msn_buddy_data *bd;
    81         char *adl;
     56        char buf[1024], *realname, groupid[8];
    8257       
    8358        *groupid = '\0';
    84 #if 0
    8559        if( group )
    8660        {
     
    11387                        if( l == NULL )
    11488                        {
    115                                 char groupname[strlen(group)+1];
    116                                 strcpy( groupname, group );
    117                                 http_encode( groupname );
     89                                char *groupname = msn_http_encode( group );
    11890                                g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 );
     91                                g_free( groupname );
    11992                                return msn_write( ic, buf, strlen( buf ) );
    12093                        }
     
    128101                }
    129102        }
    130 #endif
    131        
    132         if( !( ( bu = bee_user_by_handle( ic->bee, ic, who ) ) ||
    133                ( bu = bee_user_new( ic->bee, ic, who, 0 ) ) ) ||
    134             !( bd = bu->data ) || bd->flags & list )
    135                 return 1;
    136        
    137         bd->flags |= list;
    138        
    139         if( list == MSN_BUDDY_FL )
    140                 msn_soap_ab_contact_add( ic, bu );
    141         else
    142                 msn_soap_memlist_edit( ic, who, TRUE, list );
    143        
    144         if( ( adl = adlrml_entry( who, list ) ) )
    145         {
    146                 g_snprintf( buf, sizeof( buf ), "ADL %d %zd\r\n%s",
    147                             ++md->trId, strlen( adl ), adl );
    148                 g_free( adl );
    149                
    150                 return msn_write( ic, buf, strlen( buf ) );
    151         }
    152        
    153         return 1;
    154 }
    155 
    156 int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group )
     103       
     104        realname = msn_http_encode( realname_ );
     105        g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s%s\r\n", ++md->trId, list, who, realname, groupid );
     106        g_free( realname );
     107       
     108        return msn_write( ic, buf, strlen( buf ) );
     109}
     110
     111int msn_buddy_list_remove( struct im_connection *ic, char *list, const char *who, const char *group )
    157112{
    158113        struct msn_data *md = ic->proto_data;
    159114        char buf[1024], groupid[8];
    160         bee_user_t *bu;
    161         struct msn_buddy_data *bd;
    162         char *adl;
    163115       
    164116        *groupid = '\0';
    165 #if 0
    166117        if( group )
    167118        {
     
    174125                        }
    175126        }
    176 #endif
    177        
    178         if( !( bu = bee_user_by_handle( ic->bee, ic, who ) ) ||
    179             !( bd = bu->data ) || !( bd->flags & list ) )
    180                 return 1;
    181        
    182         bd->flags &= ~list;
    183        
    184         if( list == MSN_BUDDY_FL )
    185                 msn_soap_ab_contact_del( ic, bu );
    186         else
    187                 msn_soap_memlist_edit( ic, who, FALSE, list );
    188        
    189         if( ( adl = adlrml_entry( who, list ) ) )
    190         {
    191                 g_snprintf( buf, sizeof( buf ), "RML %d %zd\r\n%s",
    192                             ++md->trId, strlen( adl ), adl );
    193                 g_free( adl );
    194                
    195                 return msn_write( ic, buf, strlen( buf ) );
    196         }
    197        
    198         return 1;
     127       
     128        g_snprintf( buf, sizeof( buf ), "REM %d %s %s%s\r\n", ++md->trId, list, who, groupid );
     129        if( msn_write( ic, buf, strlen( buf ) ) )
     130                return( 1 );
     131       
     132        return( 0 );
    199133}
    200134
     
    210144        struct msn_buddy_ask_data *bla = data;
    211145       
    212         msn_buddy_list_add( bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL );
     146        msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname, NULL );
    213147       
    214148        imcb_ask_add( bla->ic, bla->handle, NULL );
     
    223157        struct msn_buddy_ask_data *bla = data;
    224158       
    225         msn_buddy_list_add( bla->ic, MSN_BUDDY_BL, bla->handle, bla->realname, NULL );
     159        msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname, NULL );
    226160       
    227161        g_free( bla->handle );
     
    230164}
    231165
    232 void msn_buddy_ask( bee_user_t *bu )
    233 {
    234         struct msn_buddy_ask_data *bla;
    235         struct msn_buddy_data *bd = bu->data;
     166void msn_buddy_ask( struct im_connection *ic, char *handle, char *realname )
     167{
     168        struct msn_buddy_ask_data *bla = g_new0( struct msn_buddy_ask_data, 1 );
    236169        char buf[1024];
    237170       
    238         if( ( bd->flags & 30 ) != 8 && ( bd->flags & 30 ) != 16 )
    239                 return;
    240        
    241         bla = g_new0( struct msn_buddy_ask_data, 1 );
    242         bla->ic = bu->ic;
    243         bla->handle = g_strdup( bu->handle );
    244         bla->realname = g_strdup( bu->fullname );
     171        bla->ic = ic;
     172        bla->handle = g_strdup( handle );
     173        bla->realname = g_strdup( realname );
    245174       
    246175        g_snprintf( buf, sizeof( buf ),
    247176                    "The user %s (%s) wants to add you to his/her buddy list.",
    248                     bu->handle, bu->fullname );
    249         imcb_ask( bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no );
     177                    handle, realname );
     178        imcb_ask( ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no );
    250179}
    251180
     
    350279        if( st <= 0 )
    351280                return( -1 );
    352        
    353         if( getenv( "BITLBEE_DEBUG" ) )
    354         {
    355                 write( 2, "->C:", 4 );
    356                 write( 2, h->rxq + h->rxlen - st, st );
    357         }
    358281       
    359282        while( st )
     
    444367}
    445368
     369/* The difference between this function and the normal http_encode() function
     370   is that this one escapes every 7-bit ASCII character because this is said
     371   to avoid some lame server-side checks when setting a real-name. Also,
     372   non-ASCII characters are not escaped because MSN servers don't seem to
     373   appreciate that! */
     374char *msn_http_encode( const char *input )
     375{
     376        char *ret, *s;
     377        int i;
     378       
     379        ret = s = g_new0( char, strlen( input ) * 3 + 1 );
     380        for( i = 0; input[i]; i ++ )
     381                if( input[i] & 128 )
     382                {
     383                        *s = input[i];
     384                        s ++;
     385                }
     386                else
     387                {
     388                        g_snprintf( s, 4, "%%%02X", input[i] );
     389                        s += 3;
     390                }
     391       
     392        return ret;
     393}
     394
    446395void msn_msgq_purge( struct im_connection *ic, GSList **list )
    447396{
     
    484433}
    485434
    486 /* Copied and heavily modified from http://tmsnc.sourceforge.net/chl.c */
    487 char *msn_p11_challenge( char *challenge )
    488 {
    489         char *output, buf[256];
    490         md5_state_t md5c;
    491         unsigned char md5Hash[16], *newHash;
    492         unsigned int *md5Parts, *chlStringParts, newHashParts[5];
    493         long long nHigh = 0, nLow = 0;
    494         int i, n;
    495 
    496         /* Create the MD5 hash */
    497         md5_init(&md5c);
    498         md5_append(&md5c, (unsigned char*) challenge, strlen(challenge));
    499         md5_append(&md5c, (unsigned char*) MSNP11_PROD_KEY, strlen(MSNP11_PROD_KEY));
    500         md5_finish(&md5c, md5Hash);
    501 
    502         /* Split it into four integers */
    503         md5Parts = (unsigned int *)md5Hash;
    504         for (i = 0; i < 4; i ++)
    505         { 
    506                 md5Parts[i] = GUINT32_TO_LE(md5Parts[i]);
    507                
    508                 /* & each integer with 0x7FFFFFFF */
    509                 /* and save one unmodified array for later */
    510                 newHashParts[i] = md5Parts[i];
    511                 md5Parts[i] &= 0x7FFFFFFF;
    512         }
    513        
    514         /* make a new string and pad with '0' */
    515         n = g_snprintf(buf, sizeof(buf)-5, "%s%s00000000", challenge, MSNP11_PROD_ID);
    516         /* truncate at an 8-byte boundary */
    517         buf[n&=~7] = '\0';
    518        
    519         /* split into integers */
    520         chlStringParts = (unsigned int *)buf;
    521        
    522         /* this is magic */
    523         for (i = 0; i < (n / 4) - 1; i += 2)
    524         {
    525                 long long temp;
    526 
    527                 chlStringParts[i]   = GUINT32_TO_LE(chlStringParts[i]);
    528                 chlStringParts[i+1] = GUINT32_TO_LE(chlStringParts[i+1]);
    529 
    530                 temp  = (md5Parts[0] * (((0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF;
    531                 nHigh = (md5Parts[2] * (((long long)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF;
    532                 nLow  = nLow + nHigh + temp;
    533         }
    534         nHigh = (nHigh+md5Parts[1]) % 0x7FFFFFFF;
    535         nLow = (nLow+md5Parts[3]) % 0x7FFFFFFF;
    536        
    537         newHashParts[0] ^= nHigh;
    538         newHashParts[1] ^= nLow;
    539         newHashParts[2] ^= nHigh;
    540         newHashParts[3] ^= nLow;
    541        
    542         /* swap more bytes if big endian */
    543         for (i = 0; i < 4; i ++)
    544                 newHashParts[i] = GUINT32_TO_LE(newHashParts[i]);
    545        
    546         /* make a string of the parts */
    547         newHash = (unsigned char *)newHashParts;
    548        
    549         /* convert to hexadecimal */
    550         output = g_new(char, 33);
    551         for (i = 0; i < 16; i ++)
    552                 sprintf(output + i * 2, "%02x", newHash[i]);
    553        
    554         return output;
    555 }
    556 
    557 gint msn_domaintree_cmp( gconstpointer a_, gconstpointer b_ )
    558 {
    559         const char *a = a_, *b = b_;
    560         gint ret;
    561        
    562         if( !( a = strchr( a, '@' ) ) || !( b = strchr( b, '@' ) ) ||
    563             ( ret = strcmp( a, b ) ) == 0 )
    564                 ret = strcmp( a_, b_ );
    565        
    566         return ret;
    567 }
    568 
    569 struct msn_group *msn_group_by_name( struct im_connection *ic, const char *name )
    570 {
     435gboolean msn_set_display_name( struct im_connection *ic, const char *rawname )
     436{
     437        char *fn = msn_http_encode( rawname );
    571438        struct msn_data *md = ic->proto_data;
    572         GSList *l;
    573        
    574         for( l = md->groups; l; l = l->next )
    575         {
    576                 struct msn_group *mg = l->data;
    577                
    578                 if( g_strcasecmp( mg->name, name ) == 0 )
    579                         return mg;
    580         }
    581        
    582         return NULL;
    583 }
    584 
    585 struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id )
    586 {
    587         struct msn_data *md = ic->proto_data;
    588         GSList *l;
    589        
    590         for( l = md->groups; l; l = l->next )
    591         {
    592                 struct msn_group *mg = l->data;
    593                
    594                 if( g_strcasecmp( mg->id, id ) == 0 )
    595                         return mg;
    596         }
    597        
    598         return NULL;
    599 }
    600 
    601 int msn_ns_set_display_name( struct im_connection *ic, const char *value )
    602 {
    603         struct msn_data *md = ic->proto_data;
    604         char fn[strlen(value)*3+1];
    605         char buf[512];
    606        
    607         strcpy( fn, value );
    608         http_encode( fn );
    609         g_snprintf( buf, sizeof( buf ), "PRP %d MFN %s\r\n",
    610                     ++md->trId, fn );
    611        
    612         /* Note: We don't actually know if the server accepted the new name,
    613            and won't give proper feedback yet if it doesn't. */
    614         return msn_write( ic, buf, strlen( buf ) );
    615 }
     439        char buf[1024];
     440       
     441        g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn );
     442        g_free( fn );
     443       
     444        return msn_write( ic, buf, strlen( buf ) ) != 0;
     445}
  • protocols/msn/ns.c

    rfeb1bad rb0a89cc  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2727#include "nogaim.h"
    2828#include "msn.h"
     29#include "passport.h"
    2930#include "md5.h"
    30 #include "soap.h"
    31 #include "xmltree.h"
    3231
    3332static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond );
     
    3534static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
    3635
    37 static void msn_ns_send_adl_start( struct im_connection *ic );
    38 static void msn_ns_send_adl( struct im_connection *ic );
     36static void msn_auth_got_passport_token( struct msn_auth_data *mad );
     37static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name );
    3938
    4039gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
     
    7473        md->handler->rxq = g_new0( char, 1 );
    7574       
    76         g_snprintf( s, sizeof( s ), "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER );
     75        g_snprintf( s, sizeof( s ), "VER %d MSNP8 CVR0\r\n", ++md->trId );
    7776        if( msn_write( ic, s, strlen( s ) ) )
    7877        {
     
    114113        if( strcmp( cmd[0], "VER" ) == 0 )
    115114        {
    116                 if( cmd[2] && strncmp( cmd[2], MSNP_VER, 5 ) != 0 )
     115                if( cmd[2] && strncmp( cmd[2], "MSNP8", 5 ) != 0 )
    117116                {
    118117                        imcb_error( ic, "Unsupported protocol" );
     
    128127        {
    129128                /* We don't give a damn about the information we just received */
    130                 g_snprintf( buf, sizeof( buf ), "USR %d SSO I %s\r\n", ++md->trId, ic->acc->user );
     129                g_snprintf( buf, sizeof( buf ), "USR %d TWN I %s\r\n", ++md->trId, ic->acc->user );
    131130                return( msn_write( ic, buf, strlen( buf ) ) );
    132131        }
     
    136135                int port;
    137136               
    138                 if( num_parts >= 6 && strcmp( cmd[2], "NS" ) == 0 )
     137                if( num_parts == 6 && strcmp( cmd[2], "NS" ) == 0 )
    139138                {
    140139                        b_event_remove( ic->inpa );
     
    157156                        md->fd = proxy_connect( server, port, msn_ns_connected, ic );
    158157                }
    159                 else if( num_parts >= 6 && strcmp( cmd[2], "SB" ) == 0 )
     158                else if( num_parts == 6 && strcmp( cmd[2], "SB" ) == 0 )
    160159                {
    161160                        struct msn_switchboard *sb;
     
    221220        else if( strcmp( cmd[0], "USR" ) == 0 )
    222221        {
    223                 if( num_parts >= 6 && strcmp( cmd[2], "SSO" ) == 0 &&
    224                     strcmp( cmd[3], "S" ) == 0 )
    225                 {
    226                         msn_soap_passport_sso_request( ic, cmd[4], cmd[5] );
    227                 }
    228                 else if( strcmp( cmd[2], "OK" ) == 0 )
    229                 {
     222                if( num_parts == 5 && strcmp( cmd[2], "TWN" ) == 0 && strcmp( cmd[3], "S" ) == 0 )
     223                {
     224                        /* Time for some Passport black magic... */
     225                        if( !passport_get_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )
     226                        {
     227                                imcb_error( ic, "Error while contacting Passport server" );
     228                                imc_logout( ic, TRUE );
     229                                return( 0 );
     230                        }
     231                }
     232                else if( num_parts >= 7 && strcmp( cmd[2], "OK" ) == 0 )
     233                {
     234                        if( num_parts == 7 )
     235                                msn_ns_got_display_name( ic, cmd[4] );
     236                        else
     237                                imcb_log( ic, "Warning: Friendly name in server response was corrupted" );
     238                       
    230239                        imcb_log( ic, "Authenticated, getting buddy list" );
    231                         msn_soap_memlist_request( ic );
     240                       
     241                        g_snprintf( buf, sizeof( buf ), "SYN %d 0\r\n", ++md->trId );
     242                        return( msn_write( ic, buf, strlen( buf ) ) );
    232243                }
    233244                else
     
    240251        else if( strcmp( cmd[0], "MSG" ) == 0 )
    241252        {
    242                 if( num_parts < 4 )
     253                if( num_parts != 4 )
    243254                {
    244255                        imcb_error( ic, "Syntax error" );
     
    256267                }
    257268        }
    258         else if( strcmp( cmd[0], "BLP" ) == 0 )
    259         {
    260                 msn_ns_send_adl_start( ic );
    261                 return msn_ns_finish_login( ic );
    262         }
    263         else if( strcmp( cmd[0], "ADL" ) == 0 )
    264         {
    265                 if( num_parts >= 3 && strcmp( cmd[2], "OK" ) == 0 )
    266                 {
    267                         msn_ns_send_adl( ic );
    268                         return msn_ns_finish_login( ic );
    269                 }
    270                 else if( num_parts >= 3 )
    271                 {
    272                         md->handler->msglen = atoi( cmd[2] );
    273                 }
    274         }
    275         else if( strcmp( cmd[0], "PRP" ) == 0 )
    276         {
    277                 imcb_connected( ic );
     269        else if( strcmp( cmd[0], "SYN" ) == 0 )
     270        {
     271                if( num_parts == 5 )
     272                {
     273                        int i, groupcount;
     274                       
     275                        groupcount = atoi( cmd[4] );
     276                        if( groupcount > 0 )
     277                        {
     278                                /* valgrind says this is leaking memory, I'm guessing
     279                                   that this happens during server redirects. */
     280                                if( md->grouplist )
     281                                {
     282                                        for( i = 0; i < md->groupcount; i ++ )
     283                                                g_free( md->grouplist[i] );
     284                                        g_free( md->grouplist );
     285                                }
     286                               
     287                                md->groupcount = groupcount;
     288                                md->grouplist = g_new0( char *, md->groupcount );
     289                        }
     290                       
     291                        md->buddycount = atoi( cmd[3] );
     292                        if( !*cmd[3] || md->buddycount == 0 )
     293                                msn_logged_in( ic );
     294                }
     295                else
     296                {
     297                        /* Hrrm... This SYN reply doesn't really look like something we expected.
     298                           Let's assume everything is okay. */
     299                       
     300                        msn_logged_in( ic );
     301                }
     302        }
     303        else if( strcmp( cmd[0], "LST" ) == 0 )
     304        {
     305                int list;
     306               
     307                if( num_parts != 4 && num_parts != 5 )
     308                {
     309                        imcb_error( ic, "Syntax error" );
     310                        imc_logout( ic, TRUE );
     311                        return( 0 );
     312                }
     313               
     314                http_decode( cmd[2] );
     315                list = atoi( cmd[3] );
     316               
     317                if( list & 1 ) /* FL */
     318                {
     319                        char *group = NULL;
     320                        int num;
     321                       
     322                        if( cmd[4] != NULL && sscanf( cmd[4], "%d", &num ) == 1 && num < md->groupcount )
     323                                group = md->grouplist[num];
     324                       
     325                        imcb_add_buddy( ic, cmd[1], group );
     326                        imcb_rename_buddy( ic, cmd[1], cmd[2] );
     327                }
     328                if( list & 2 ) /* AL */
     329                {
     330                        ic->permit = g_slist_append( ic->permit, g_strdup( cmd[1] ) );
     331                }
     332                if( list & 4 ) /* BL */
     333                {
     334                        ic->deny = g_slist_append( ic->deny, g_strdup( cmd[1] ) );
     335                }
     336                if( list & 8 ) /* RL */
     337                {
     338                        if( ( list & 6 ) == 0 )
     339                                msn_buddy_ask( ic, cmd[1], cmd[2] );
     340                }
     341               
     342                if( --md->buddycount == 0 )
     343                {
     344                        if( ic->flags & OPT_LOGGED_IN )
     345                        {
     346                                imcb_log( ic, "Successfully transferred to different server" );
     347                                g_snprintf( buf, sizeof( buf ), "CHG %d %s %d\r\n", ++md->trId, md->away_state->code, 0 );
     348                                return( msn_write( ic, buf, strlen( buf ) ) );
     349                        }
     350                        else
     351                        {
     352                                msn_logged_in( ic );
     353                        }
     354                }
     355        }
     356        else if( strcmp( cmd[0], "LSG" ) == 0 )
     357        {
     358                int num;
     359               
     360                if( num_parts != 4 )
     361                {
     362                        imcb_error( ic, "Syntax error" );
     363                        imc_logout( ic, TRUE );
     364                        return( 0 );
     365                }
     366               
     367                http_decode( cmd[2] );
     368                num = atoi( cmd[1] );
     369               
     370                if( num < md->groupcount )
     371                        md->grouplist[num] = g_strdup( cmd[2] );
    278372        }
    279373        else if( strcmp( cmd[0], "CHL" ) == 0 )
    280374        {
    281                 char *resp;
    282                
    283                 if( num_parts < 3 )
    284                 {
    285                         imcb_error( ic, "Syntax error" );
    286                         imc_logout( ic, TRUE );
    287                         return( 0 );
    288                 }
    289                
    290                 resp = msn_p11_challenge( cmd[2] );
    291                 g_snprintf( buf, sizeof( buf ), "QRY %d %s %zd\r\n%s",
    292                             ++md->trId, MSNP11_PROD_ID,
    293                             strlen( resp ), resp );
    294                 g_free( resp );
     375                md5_state_t state;
     376                md5_byte_t digest[16];
     377                int i;
     378               
     379                if( num_parts != 3 )
     380                {
     381                        imcb_error( ic, "Syntax error" );
     382                        imc_logout( ic, TRUE );
     383                        return( 0 );
     384                }
     385               
     386                md5_init( &state );
     387                md5_append( &state, (const md5_byte_t *) cmd[2], strlen( cmd[2] ) );
     388                md5_append( &state, (const md5_byte_t *) QRY_CODE, strlen( QRY_CODE ) );
     389                md5_finish( &state, digest );
     390               
     391                g_snprintf( buf, sizeof( buf ), "QRY %d %s %d\r\n", ++md->trId, QRY_NAME, 32 );
     392                for( i = 0; i < 16; i ++ )
     393                        g_snprintf( buf + strlen( buf ), 3, "%02x", digest[i] );
    295394               
    296395                return( msn_write( ic, buf, strlen( buf ) ) );
     
    300399                const struct msn_away_state *st;
    301400               
    302                 if( num_parts < 6 )
    303                 {
    304                         imcb_error( ic, "Syntax error" );
    305                         imc_logout( ic, TRUE );
    306                         return( 0 );
    307                 }
    308                
    309                 http_decode( cmd[5] );
    310                 imcb_rename_buddy( ic, cmd[3], cmd[5] );
     401                if( num_parts != 6 )
     402                {
     403                        imcb_error( ic, "Syntax error" );
     404                        imc_logout( ic, TRUE );
     405                        return( 0 );
     406                }
     407               
     408                http_decode( cmd[4] );
     409                imcb_rename_buddy( ic, cmd[3], cmd[4] );
    311410               
    312411                st = msn_away_state_by_code( cmd[2] );
     
    333432        {
    334433                const struct msn_away_state *st;
    335                 int cap;
    336                
    337                 if( num_parts < 6 )
    338                 {
    339                         imcb_error( ic, "Syntax error" );
    340                         imc_logout( ic, TRUE );
    341                         return( 0 );
    342                 }
    343                
    344                 http_decode( cmd[4] );
    345                 cap = atoi( cmd[5] );
    346                 imcb_rename_buddy( ic, cmd[2], cmd[4] );
     434               
     435                if( num_parts != 5 )
     436                {
     437                        imcb_error( ic, "Syntax error" );
     438                        imc_logout( ic, TRUE );
     439                        return( 0 );
     440                }
     441               
     442                http_decode( cmd[3] );
     443                imcb_rename_buddy( ic, cmd[2], cmd[3] );
    347444               
    348445                st = msn_away_state_by_code( cmd[1] );
     
    354451               
    355452                imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN |
    356                                    ( st != msn_away_state_list ? OPT_AWAY : 0 ) |
    357                                    ( cap & 1 ? OPT_MOBILE : 0 ),
     453                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
    358454                                   st->name, NULL );
    359455               
     
    366462                int session, port;
    367463               
    368                 if( num_parts < 7 )
     464                if( num_parts != 7 )
    369465                {
    370466                        imcb_error( ic, "Syntax error" );
     
    408504                }
    409505        }
     506        else if( strcmp( cmd[0], "ADD" ) == 0 )
     507        {
     508                if( num_parts == 6 && strcmp( cmd[2], "RL" ) == 0 )
     509                {
     510                        GSList *l;
     511                       
     512                        http_decode( cmd[5] );
     513                       
     514                        if( strchr( cmd[4], '@' ) == NULL )
     515                        {
     516                                imcb_error( ic, "Syntax error" );
     517                                imc_logout( ic, TRUE );
     518                                return 0;
     519                        }
     520                       
     521                        /* We got added by someone. If we don't have this
     522                           person in permit/deny yet, inform the user. */
     523                        for( l = ic->permit; l; l = l->next )
     524                                if( g_strcasecmp( l->data, cmd[4] ) == 0 )
     525                                        return 1;
     526                       
     527                        for( l = ic->deny; l; l = l->next )
     528                                if( g_strcasecmp( l->data, cmd[4] ) == 0 )
     529                                        return 1;
     530                       
     531                        msn_buddy_ask( ic, cmd[4], cmd[5] );
     532                }
     533                else if( num_parts >= 6 && strcmp( cmd[2], "FL" ) == 0 )
     534                {
     535                        const char *group = NULL;
     536                        int num;
     537                       
     538                        if( cmd[6] != NULL && sscanf( cmd[6], "%d", &num ) == 1 && num < md->groupcount )
     539                                group = md->grouplist[num];
     540                       
     541                        http_decode( cmd[5] );
     542                        imcb_add_buddy( ic, cmd[4], group );
     543                        imcb_rename_buddy( ic, cmd[4], cmd[5] );
     544                }
     545        }
    410546        else if( strcmp( cmd[0], "OUT" ) == 0 )
    411547        {
     
    429565                return( 0 );
    430566        }
     567#if 0
     568        /* Discard this one completely for now since I don't care about the ack
     569           and since MSN servers can apparently screw up the formatting. */
     570        else if( strcmp( cmd[0], "REA" ) == 0 )
     571        {
     572                if( num_parts != 5 )
     573                {
     574                        imcb_error( ic, "Syntax error" );
     575                        imc_logout( ic, TRUE );
     576                        return( 0 );
     577                }
     578               
     579                if( g_strcasecmp( cmd[3], ic->acc->user ) == 0 )
     580                {
     581                        set_t *s;
     582                       
     583                        http_decode( cmd[4] );
     584                        strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) );
     585                        ic->displayname[sizeof(ic->displayname)-1] = 0;
     586                       
     587                        if( ( s = set_find( &ic->acc->set, "display_name" ) ) )
     588                        {
     589                                g_free( s->value );
     590                                s->value = g_strdup( cmd[4] );
     591                        }
     592                }
     593                else
     594                {
     595                        /* This is not supposed to happen, but let's handle it anyway... */
     596                        http_decode( cmd[4] );
     597                        imcb_rename_buddy( ic, cmd[3], cmd[4] );
     598                }
     599        }
     600#endif
    431601        else if( strcmp( cmd[0], "IPG" ) == 0 )
    432602        {
     
    442612                }
    443613        }
    444 #if 0
    445614        else if( strcmp( cmd[0], "ADG" ) == 0 )
    446615        {
     
    486655                        }
    487656                }
    488         }
    489 #endif
    490         else if( strcmp( cmd[0], "GCF" ) == 0 )
    491         {
    492                 /* Coming up is cmd[2] bytes of stuff we're supposed to
    493                    censore. Meh. */
    494                 md->handler->msglen = atoi( cmd[2] );
    495         }
    496         else if( strcmp( cmd[0], "UBX" ) == 0 )
    497         {
    498                 /* Status message. */
    499                 if( num_parts >= 4 )
    500                         md->handler->msglen = atoi( cmd[3] );
    501         }
    502         else if( strcmp( cmd[0], "NOT" ) == 0 )
    503         {
    504                 /* Some kind of notification, poorly documented but
    505                    apparently used to announce address book changes. */
    506                 if( num_parts >= 2 )
    507                         md->handler->msglen = atoi( cmd[1] );
    508657        }
    509658        else if( isdigit( cmd[0][0] ) )
     
    616765                }
    617766        }
    618         else if( strcmp( cmd[0], "UBX" ) == 0 )
    619         {
    620                 struct xt_node *psm;
    621                 char *psm_text = NULL;
    622                
    623                 psm = xt_from_string( msg );
    624                 if( psm && strcmp( psm->name, "Data" ) == 0 &&
    625                     ( psm = xt_find_node( psm->children, "PSM" ) ) )
    626                         psm_text = psm->text;
    627                
    628                 imcb_buddy_status_msg( ic, cmd[1], psm_text );
    629                 xt_free_node( psm );
    630         }
    631         else if( strcmp( cmd[0], "ADL" ) == 0 )
    632         {
    633                 struct xt_node *adl, *d, *c;
    634                
    635                 if( !( adl = xt_from_string( msg ) ) )
    636                         return 1;
    637                
    638                 for( d = adl->children; d; d = d->next )
    639                 {
    640                         char *dn;
    641                         if( strcmp( d->name, "d" ) != 0 ||
    642                             ( dn = xt_find_attr( d, "n" ) ) == NULL )
    643                                 continue;
    644                         for( c = d->children; c; c = c->next )
    645                         {
    646                                 bee_user_t *bu;
    647                                 struct msn_buddy_data *bd;
    648                                 char *cn, *handle, *f, *l;
    649                                 int flags;
    650                                
    651                                 if( strcmp( c->name, "c" ) != 0 ||
    652                                     ( l = xt_find_attr( c, "l" ) ) == NULL ||
    653                                     ( cn = xt_find_attr( c, "n" ) ) == NULL )
    654                                         continue;
    655                                
    656                                 handle = g_strdup_printf( "%s@%s", cn, dn );
    657                                 if( !( ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) ||
    658                                        ( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) ) )
    659                                 {
    660                                         g_free( handle );
    661                                         continue;
    662                                 }
    663                                 g_free( handle );
    664                                 bd = bu->data;
    665                                
    666                                 if( ( f = xt_find_attr( c, "f" ) ) )
    667                                 {
    668                                         http_decode( f );
    669                                         imcb_rename_buddy( ic, bu->handle, f );
    670                                 }
    671                                
    672                                 flags = atoi( l ) & 15;
    673                                 if( bd->flags != flags )
    674                                 {
    675                                         bd->flags = flags;
    676                                         msn_buddy_ask( bu );
    677                                 }
    678                         }
    679                 }
    680         }
    681767       
    682768        return( 1 );
    683769}
    684770
    685 void msn_auth_got_passport_token( struct im_connection *ic, const char *token, const char *error )
     771static void msn_auth_got_passport_token( struct msn_auth_data *mad )
    686772{
     773        struct im_connection *ic = mad->data;
    687774        struct msn_data *md;
    688775       
     
    692779       
    693780        md = ic->proto_data;
    694        
    695         if( token )
    696         {
    697                 char buf[1536];
    698                
    699                 g_snprintf( buf, sizeof( buf ), "USR %d SSO S %s %s\r\n", ++md->trId, md->tokens[0], token );
     781        if( mad->token )
     782        {
     783                char buf[1024];
     784               
     785                g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token );
    700786                msn_write( ic, buf, strlen( buf ) );
    701787        }
    702788        else
    703789        {
    704                 imcb_error( ic, "Error during Passport authentication: %s", error );
     790                imcb_error( ic, "Error during Passport authentication: %s", mad->error );
    705791                imc_logout( ic, TRUE );
    706792        }
    707793}
    708794
    709 void msn_auth_got_contact_list( struct im_connection *ic )
     795static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name )
    710796{
    711         char buf[64];
    712         struct msn_data *md;
    713        
    714         /* Dead connection? */
    715         if( g_slist_find( msn_connections, ic ) == NULL )
    716                 return;
    717        
    718         md = ic->proto_data;
    719        
    720        
    721         g_snprintf( buf, sizeof( buf ), "BLP %d %s\r\n", ++md->trId, "BL" );
    722         msn_write( ic, buf, strlen( buf ) );
     797        set_t *s;
     798       
     799        if( ( s = set_find( &ic->acc->set, "display_name" ) ) == NULL )
     800                return FALSE; /* Shouldn't happen.. */
     801       
     802        http_decode( name );
     803       
     804        if( s->value && strcmp( s->value, name ) == 0 )
     805        {
     806                return TRUE;
     807                /* The names match, nothing to worry about. */
     808        }
     809        else if( s->value != NULL &&
     810                 ( strcmp( name, ic->acc->user ) == 0 ||
     811                   set_getbool( &ic->acc->set, "local_display_name" ) ) )
     812        {
     813                /* The server thinks our display name is our e-mail address
     814                   which is probably wrong, or the user *wants* us to do this:
     815                   Always use the locally set display_name. */
     816                return msn_set_display_name( ic, s->value );
     817        }
     818        else
     819        {
     820                if( s->value && *s->value )
     821                        imcb_log( ic, "BitlBee thinks your display name is `%s' but "
     822                                      "the MSN server says it's `%s'. Using the MSN "
     823                                      "server's name. Set local_display_name to true "
     824                                      "to use the local name.", s->value, name );
     825               
     826                if( g_utf8_validate( name, -1, NULL ) )
     827                {
     828                        g_free( s->value );
     829                        s->value = g_strdup( name );
     830                }
     831                else
     832                {
     833                        imcb_log( ic, "Warning: Friendly name in server response was corrupted" );
     834                }
     835               
     836                return TRUE;
     837        }
    723838}
    724 
    725 static gboolean msn_ns_send_adl_1( gpointer key, gpointer value, gpointer data )
    726 {
    727         struct xt_node *adl = data, *d, *c;
    728         struct bee_user *bu = value;
    729         struct msn_buddy_data *bd = bu->data;
    730         struct msn_data *md = bu->ic->proto_data;
    731         char handle[strlen(bu->handle)];
    732         char *domain;
    733         char l[4];
    734        
    735         if( ( bd->flags & 7 ) == 0 || ( bd->flags & MSN_BUDDY_ADL_SYNCED ) )
    736                 return FALSE;
    737        
    738         strcpy( handle, bu->handle );
    739         if( ( domain = strchr( handle, '@' ) ) == NULL ) /* WTF */
    740                 return FALSE;
    741         *domain = '\0';
    742         domain ++;
    743        
    744         if( ( d = adl->children ) == NULL ||
    745             g_strcasecmp( xt_find_attr( d, "n" ), domain ) != 0 )
    746         {
    747                 d = xt_new_node( "d", NULL, NULL );
    748                 xt_add_attr( d, "n", domain );
    749                 xt_insert_child( adl, d );
    750         }
    751        
    752         g_snprintf( l, sizeof( l ), "%d", bd->flags & 7 );
    753         c = xt_new_node( "c", NULL, NULL );
    754         xt_add_attr( c, "n", handle );
    755         xt_add_attr( c, "l", l );
    756         xt_add_attr( c, "t", "1" ); /* 1 means normal, 4 means mobile? */
    757         xt_insert_child( d, c );
    758        
    759         /* Do this in batches of 100. */
    760         bd->flags |= MSN_BUDDY_ADL_SYNCED;
    761         return (--md->adl_todo % 140) == 0;
    762 }
    763 
    764 static void msn_ns_send_adl( struct im_connection *ic )
    765 {
    766         struct xt_node *adl;
    767         struct msn_data *md = ic->proto_data;
    768         char *adls, buf[64];
    769        
    770         adl = xt_new_node( "ml", NULL, NULL );
    771         xt_add_attr( adl, "l", "1" );
    772         g_tree_foreach( md->domaintree, msn_ns_send_adl_1, adl );
    773         if( adl->children == NULL )
    774         {
    775                 /* This tells the caller that we're done now. */
    776                 md->adl_todo = -1;
    777                 xt_free_node( adl );
    778                 return;
    779         }
    780         adls = xt_to_string( adl );
    781        
    782         g_snprintf( buf, sizeof( buf ), "ADL %d %zd\r\n", ++md->trId, strlen( adls ) );
    783         if( msn_write( ic, buf, strlen( buf ) ) )
    784                 msn_write( ic, adls, strlen( adls ) );
    785        
    786         g_free( adls );
    787 }
    788 
    789 static void msn_ns_send_adl_start( struct im_connection *ic )
    790 {
    791         struct msn_data *md;
    792         GSList *l;
    793        
    794         /* Dead connection? */
    795         if( g_slist_find( msn_connections, ic ) == NULL )
    796                 return;
    797        
    798         md = ic->proto_data;
    799         md->adl_todo = 0;
    800         for( l = ic->bee->users; l; l = l->next )
    801         {
    802                 bee_user_t *bu = l->data;
    803                 struct msn_buddy_data *bd = bu->data;
    804                
    805                 if( bu->ic != ic || ( bd->flags & 7 ) == 0 )
    806                         continue;
    807                
    808                 bd->flags &= ~MSN_BUDDY_ADL_SYNCED;
    809                 md->adl_todo++;
    810         }
    811        
    812         msn_ns_send_adl( ic );
    813 }
    814 
    815 int msn_ns_finish_login( struct im_connection *ic )
    816 {
    817         struct msn_data *md = ic->proto_data;
    818        
    819         if( ic->flags & OPT_LOGGED_IN )
    820                 return 1;
    821        
    822         if( md->adl_todo < 0 )
    823                 md->flags |= MSN_DONE_ADL;
    824        
    825         if( ( md->flags & MSN_DONE_ADL ) && ( md->flags & MSN_GOT_PROFILE ) )
    826                 return msn_ns_set_display_name( ic, set_getstr( &ic->acc->set, "display_name" ) );
    827         else
    828                 return 1;
    829 }
  • protocols/msn/sb.c

    rfeb1bad rb0a89cc  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2005 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2727#include "nogaim.h"
    2828#include "msn.h"
     29#include "passport.h"
    2930#include "md5.h"
    30 #include "soap.h"
    3131#include "invitation.h"
    3232
     
    3838{
    3939        int st;
    40        
    41         if( getenv( "BITLBEE_DEBUG" ) )
    42         {
    43                 write( 2, "->SB:", 5 );
    44                 write( 2, s, len );
    45         }
    4640       
    4741        st = write( sb->fd, s, len );
     
    413407        else if( strcmp( cmd[0], "USR" ) == 0 )
    414408        {
    415                 if( num_parts < 5 )
     409                if( num_parts != 5 )
    416410                {
    417411                        msn_sb_destroy( sb );
     
    439433                int num, tot;
    440434               
    441                 if( num_parts < 6 )
     435                if( num_parts != 6 )
    442436                {
    443437                        msn_sb_destroy( sb );
     
    476470        else if( strcmp( cmd[0], "ANS" ) == 0 )
    477471        {
    478                 if( num_parts < 3 )
     472                if( num_parts != 3 )
    479473                {
    480474                        msn_sb_destroy( sb );
     
    495489        else if( strcmp( cmd[0], "CAL" ) == 0 )
    496490        {
    497                 if( num_parts < 4 || !isdigit( cmd[3][0] ) )
     491                if( num_parts != 4 || !isdigit( cmd[3][0] ) )
    498492                {
    499493                        msn_sb_destroy( sb );
     
    505499        else if( strcmp( cmd[0], "JOI" ) == 0 )
    506500        {
    507                 if( num_parts < 3 )
     501                if( num_parts != 3 )
    508502                {
    509503                        msn_sb_destroy( sb );
     
    566560        else if( strcmp( cmd[0], "MSG" ) == 0 )
    567561        {
    568                 if( num_parts < 4 )
     562                if( num_parts != 4 )
    569563                {
    570564                        msn_sb_destroy( sb );
     
    631625                const struct msn_status_code *err = msn_status_by_number( num );
    632626               
    633                 /* If the person is offline, send an offline message instead,
    634                    and don't report an error. */
    635                 if( num == 217 )
    636                         msn_soap_oim_send_queue( ic, &sb->msgq );
    637                 else
    638                         imcb_error( ic, "Error reported by switchboard server: %s", err->text );
     627                imcb_error( ic, "Error reported by switchboard server: %s", err->text );
    639628               
    640629                if( err->flags & STATUS_SB_FATAL )
     
    752741                else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 )
    753742                {
    754                         /* Not currently implemented. Don't warn about it since
    755                            this seems to be used for avatars now. */
     743                        imcb_error( sb->ic, "Cannot receive file from %s: BitlBee does not "
     744                                        "support msnmsgrp2p yet.", sb->who );
    756745                        g_free( ct );
    757746                }
  • protocols/msn/tables.c

    rfeb1bad rb0a89cc  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2004 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    8383        { 230, "Cannot remove that group",                              0 },
    8484        { 231, "Invalid group",                                         0 },
    85         { 240, "ADL/RML command with corrupted payload",                STATUS_FATAL },
    86         { 241, "ADL/RML command with invalid modification",             0 },
    8785        { 280, "Switchboard failed",                                    STATUS_SB_FATAL },
    8886        { 281, "Transfer to switchboard failed",                        0 },
  • protocols/nogaim.c

    rfeb1bad rb0a89cc  
    326326        imcb_log( ic, "Signing off.." );
    327327       
     328        b_event_remove( ic->keepalive );
     329        ic->keepalive = 0;
     330        ic->acc->prpl->logout( ic );
     331        b_event_remove( ic->inpa );
     332       
     333        g_free( ic->away );
     334        ic->away = NULL;
     335       
    328336        for( l = bee->users; l; )
    329337        {
     
    336344                l = next;
    337345        }
    338        
    339         b_event_remove( ic->keepalive );
    340         ic->keepalive = 0;
    341         ic->acc->prpl->logout( ic );
    342         b_event_remove( ic->inpa );
    343        
    344         g_free( ic->away );
    345         ic->away = NULL;
    346346       
    347347        query_del_by_conn( (irc_t*) ic->bee->ui_data, ic );
  • protocols/nogaim.h

    rfeb1bad rb0a89cc  
    195195           this info via imcb_log(). Implementing these are optional. */
    196196        void (* get_info)       (struct im_connection *, char *who);
    197         /* set_my_name is *DEPRECATED*, not used by the UI anymore. Use the
    198            display_name setting instead. */
    199197        void (* set_my_name)    (struct im_connection *, char *name);
    200198        void (* set_name)       (struct im_connection *, char *who, char *name);
  • storage_xml.c

    rfeb1bad rb0a89cc  
    320320        else if( g_strcasecmp( g_markup_parse_context_get_element( ctx ), "setting" ) == 0 && xd->current_setting )
    321321        {
    322                 if( xd->current_account )
    323                 {
    324                         set_t *s = set_find( xd->current_set_head, xd->current_setting );
    325                         if( s && ( s->flags & ACC_SET_ONLINE_ONLY ) )
    326                         {
    327                                 g_free( xd->current_setting );
    328                                 xd->current_setting = NULL;
    329                                 return;
    330                         }
    331                 }
    332322                set_setstr( xd->current_set_head, xd->current_setting, (char*) text );
    333323                g_free( xd->current_setting );
Note: See TracChangeset for help on using the changeset viewer.