Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/ns.c

    r80175a1 r70ac477  
    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] );
     
    334433                const struct msn_away_state *st;
    335434               
    336                 if( num_parts < 5 )
    337                 {
    338                         imcb_error( ic, "Syntax error" );
    339                         imc_logout( ic, TRUE );
    340                         return( 0 );
    341                 }
    342                
    343                 http_decode( cmd[4] );
    344                 imcb_rename_buddy( ic, cmd[2], cmd[4] );
     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] );
    345444               
    346445                st = msn_away_state_by_code( cmd[1] );
     
    363462                int session, port;
    364463               
    365                 if( num_parts < 7 )
     464                if( num_parts != 7 )
    366465                {
    367466                        imcb_error( ic, "Syntax error" );
     
    405504                }
    406505        }
     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        }
    407546        else if( strcmp( cmd[0], "OUT" ) == 0 )
    408547        {
     
    426565                return( 0 );
    427566        }
     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
    428601        else if( strcmp( cmd[0], "IPG" ) == 0 )
    429602        {
     
    439612                }
    440613        }
    441 #if 0
    442614        else if( strcmp( cmd[0], "ADG" ) == 0 )
    443615        {
     
    483655                        }
    484656                }
    485         }
    486 #endif
    487         else if( strcmp( cmd[0], "GCF" ) == 0 )
    488         {
    489                 /* Coming up is cmd[2] bytes of stuff we're supposed to
    490                    censore. Meh. */
    491                 md->handler->msglen = atoi( cmd[2] );
    492         }
    493         else if( strcmp( cmd[0], "UBX" ) == 0 )
    494         {
    495                 /* Status message. */
    496                 if( num_parts >= 4 )
    497                         md->handler->msglen = atoi( cmd[3] );
    498         }
    499         else if( strcmp( cmd[0], "NOT" ) == 0 )
    500         {
    501                 /* Some kind of notification, poorly documented but
    502                    apparently used to announce address book changes. */
    503                 if( num_parts >= 2 )
    504                         md->handler->msglen = atoi( cmd[1] );
    505657        }
    506658        else if( isdigit( cmd[0][0] ) )
     
    613765                }
    614766        }
    615         else if( strcmp( cmd[0], "UBX" ) == 0 )
    616         {
    617                 struct xt_node *psm;
    618                 char *psm_text = NULL;
    619                
    620                 psm = xt_from_string( msg );
    621                 if( psm && strcmp( psm->name, "Data" ) == 0 &&
    622                     ( psm = xt_find_node( psm->children, "PSM" ) ) )
    623                         psm_text = psm->text;
    624                
    625                 imcb_buddy_status_msg( ic, cmd[1], psm_text );
    626                 xt_free_node( psm );
    627         }
    628         else if( strcmp( cmd[0], "ADL" ) == 0 )
    629         {
    630                 struct xt_node *adl, *d, *c;
    631                
    632                 if( !( adl = xt_from_string( msg ) ) )
    633                         return 1;
    634                
    635                 for( d = adl->children; d; d = d->next )
    636                 {
    637                         char *dn;
    638                         if( strcmp( d->name, "d" ) != 0 ||
    639                             ( dn = xt_find_attr( d, "n" ) ) == NULL )
    640                                 continue;
    641                         for( c = d->children; c; c = c->next )
    642                         {
    643                                 bee_user_t *bu;
    644                                 struct msn_buddy_data *bd;
    645                                 char *cn, *handle, *f, *l;
    646                                 int flags;
    647                                
    648                                 if( strcmp( c->name, "c" ) != 0 ||
    649                                     ( l = xt_find_attr( c, "l" ) ) == NULL ||
    650                                     ( cn = xt_find_attr( c, "n" ) ) == NULL )
    651                                         continue;
    652                                
    653                                 handle = g_strdup_printf( "%s@%s", cn, dn );
    654                                 if( !( ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) ||
    655                                        ( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) ) )
    656                                 {
    657                                         g_free( handle );
    658                                         continue;
    659                                 }
    660                                 g_free( handle );
    661                                 bd = bu->data;
    662                                
    663                                 if( ( f = xt_find_attr( c, "f" ) ) )
    664                                 {
    665                                         http_decode( f );
    666                                         imcb_rename_buddy( ic, bu->handle, f );
    667                                 }
    668                                
    669                                 flags = atoi( l ) & 15;
    670                                 if( bd->flags != flags )
    671                                 {
    672                                         bd->flags = flags;
    673                                         msn_buddy_ask( bu );
    674                                 }
    675                         }
    676                 }
    677         }
    678767       
    679768        return( 1 );
    680769}
    681770
    682 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 )
    683772{
     773        struct im_connection *ic = mad->data;
    684774        struct msn_data *md;
    685775       
     
    689779       
    690780        md = ic->proto_data;
    691        
    692         if( token )
    693         {
    694                 char buf[1536];
    695                
    696                 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 );
    697786                msn_write( ic, buf, strlen( buf ) );
    698787        }
    699788        else
    700789        {
    701                 imcb_error( ic, "Error during Passport authentication: %s", error );
     790                imcb_error( ic, "Error during Passport authentication: %s", mad->error );
    702791                imc_logout( ic, TRUE );
    703792        }
    704793}
    705794
    706 void msn_auth_got_contact_list( struct im_connection *ic )
     795static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name )
    707796{
    708         char buf[64];
    709         struct msn_data *md;
    710        
    711         /* Dead connection? */
    712         if( g_slist_find( msn_connections, ic ) == NULL )
    713                 return;
    714        
    715         md = ic->proto_data;
    716        
    717        
    718         g_snprintf( buf, sizeof( buf ), "BLP %d %s\r\n", ++md->trId, "BL" );
    719         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        }
    720838}
    721 
    722 static gboolean msn_ns_send_adl_1( gpointer key, gpointer value, gpointer data )
    723 {
    724         struct xt_node *adl = data, *d, *c;
    725         struct bee_user *bu = value;
    726         struct msn_buddy_data *bd = bu->data;
    727         struct msn_data *md = bu->ic->proto_data;
    728         char handle[strlen(bu->handle)];
    729         char *domain;
    730         char l[4];
    731        
    732         if( ( bd->flags & 7 ) == 0 || ( bd->flags & MSN_BUDDY_ADL_SYNCED ) )
    733                 return FALSE;
    734        
    735         strcpy( handle, bu->handle );
    736         if( ( domain = strchr( handle, '@' ) ) == NULL ) /* WTF */
    737                 return FALSE;
    738         *domain = '\0';
    739         domain ++;
    740        
    741         if( ( d = adl->children ) == NULL ||
    742             g_strcasecmp( xt_find_attr( d, "n" ), domain ) != 0 )
    743         {
    744                 d = xt_new_node( "d", NULL, NULL );
    745                 xt_add_attr( d, "n", domain );
    746                 xt_insert_child( adl, d );
    747         }
    748        
    749         g_snprintf( l, sizeof( l ), "%d", bd->flags & 7 );
    750         c = xt_new_node( "c", NULL, NULL );
    751         xt_add_attr( c, "n", handle );
    752         xt_add_attr( c, "l", l );
    753         xt_add_attr( c, "t", "1" ); /* 1 means normal, 4 means mobile? */
    754         xt_insert_child( d, c );
    755        
    756         /* Do this in batches of 100. */
    757         bd->flags |= MSN_BUDDY_ADL_SYNCED;
    758         return (--md->adl_todo % 140) == 0;
    759 }
    760 
    761 static void msn_ns_send_adl( struct im_connection *ic )
    762 {
    763         struct xt_node *adl;
    764         struct msn_data *md = ic->proto_data;
    765         char *adls, buf[64];
    766        
    767         adl = xt_new_node( "ml", NULL, NULL );
    768         xt_add_attr( adl, "l", "1" );
    769         g_tree_foreach( md->domaintree, msn_ns_send_adl_1, adl );
    770         if( adl->children == NULL )
    771         {
    772                 /* This tells the caller that we're done now. */
    773                 md->adl_todo = -1;
    774                 xt_free_node( adl );
    775                 return;
    776         }
    777         adls = xt_to_string( adl );
    778        
    779         g_snprintf( buf, sizeof( buf ), "ADL %d %zd\r\n", ++md->trId, strlen( adls ) );
    780         if( msn_write( ic, buf, strlen( buf ) ) )
    781                 msn_write( ic, adls, strlen( adls ) );
    782        
    783         g_free( adls );
    784 }
    785 
    786 static void msn_ns_send_adl_start( struct im_connection *ic )
    787 {
    788         struct msn_data *md;
    789         GSList *l;
    790        
    791         /* Dead connection? */
    792         if( g_slist_find( msn_connections, ic ) == NULL )
    793                 return;
    794        
    795         md = ic->proto_data;
    796         md->adl_todo = 0;
    797         for( l = ic->bee->users; l; l = l->next )
    798         {
    799                 bee_user_t *bu = l->data;
    800                 struct msn_buddy_data *bd = bu->data;
    801                
    802                 if( bu->ic != ic || ( bd->flags & 7 ) == 0 )
    803                         continue;
    804                
    805                 bd->flags &= ~MSN_BUDDY_ADL_SYNCED;
    806                 md->adl_todo++;
    807         }
    808        
    809         msn_ns_send_adl( ic );
    810 }
    811 
    812 int msn_ns_finish_login( struct im_connection *ic )
    813 {
    814         struct msn_data *md = ic->proto_data;
    815        
    816         if( ic->flags & OPT_LOGGED_IN )
    817                 return 1;
    818        
    819         if( md->adl_todo < 0 )
    820                 md->flags |= MSN_DONE_ADL;
    821        
    822         if( ( md->flags & MSN_DONE_ADL ) && ( md->flags & MSN_GOT_PROFILE ) )
    823                 return msn_ns_set_display_name( ic, set_getstr( &ic->acc->set, "display_name" ) );
    824         else
    825                 return 1;
    826 }
Note: See TracChangeset for help on using the changeset viewer.