Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/ns.c

    r6bef211 rd0752e8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2012 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2525
    2626#include <ctype.h>
    27 #include <sys/utsname.h>
    2827#include "nogaim.h"
    2928#include "msn.h"
    3029#include "md5.h"
    31 #include "sha1.h"
    3230#include "soap.h"
    3331#include "xmltree.h"
     
    112110        handler->rxlen = 0;
    113111        handler->rxq = g_new0( char, 1 );
    114        
    115         if( md->uuid == NULL )
    116         {
    117                 struct utsname name;
    118                 sha1_state_t sha[1];
    119                
    120                 /* UUID == SHA1("BitlBee" + my hostname + MSN username) */
    121                 sha1_init( sha );
    122                 sha1_append( sha, (void*) "BitlBee", 7 );
    123                 if( uname( &name ) == 0 )
    124                 {
    125                         sha1_append( sha, (void*) name.nodename, strlen( name.nodename ) );
    126                 }
    127                 sha1_append( sha, (void*) ic->acc->user, strlen( ic->acc->user ) );
    128                 md->uuid = sha1_random_uuid( sha );
    129                 memcpy( md->uuid, "b171be3e", 8 ); /* :-P */
    130         }
    131112       
    132113        if( msn_ns_write( ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER ) )
     
    372353                return st;
    373354        }
    374         else if( strcmp( cmd[0], "ILN" ) == 0 || strcmp( cmd[0], "NLN" ) == 0 )
     355        else if( strcmp( cmd[0], "ILN" ) == 0 )
    375356        {
    376357                const struct msn_away_state *st;
    377                 const char *handle;
    378                 int cap = 0;
    379358               
    380359                if( num_parts < 6 )
     
    384363                        return( 0 );
    385364                }
    386                 /* ILN and NLN are more or less the same, except ILN has a trId
    387                    at the start, and NLN has a capability field at the end.
    388                    Does ILN still exist BTW? */
    389                 if( cmd[0][1] == 'I' )
    390                         cmd ++;
    391                 else
    392                         cap = atoi( cmd[4] );
    393 
    394                 handle = msn_normalize_handle( cmd[2] );
    395                 if( strcmp( handle, ic->acc->user ) == 0 )
    396                         return 1; /* That's me! */
    397                
    398                 http_decode( cmd[3] );
    399                 imcb_rename_buddy( ic, handle, cmd[3] );
     365               
     366                http_decode( cmd[5] );
     367                imcb_rename_buddy( ic, cmd[3], cmd[5] );
     368               
     369                st = msn_away_state_by_code( cmd[2] );
     370                if( !st )
     371                {
     372                        /* FIXME: Warn/Bomb about unknown away state? */
     373                        st = msn_away_state_list + 1;
     374                }
     375               
     376                imcb_buddy_status( ic, cmd[3], OPT_LOGGED_IN |
     377                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ),
     378                                   st->name, NULL );
     379        }
     380        else if( strcmp( cmd[0], "FLN" ) == 0 )
     381        {
     382                if( cmd[1] == NULL )
     383                        return 1;
     384               
     385                imcb_buddy_status( ic, cmd[1], 0, NULL, NULL );
     386               
     387                msn_sb_start_keepalives( msn_sb_by_handle( ic, cmd[1] ), TRUE );
     388        }
     389        else if( strcmp( cmd[0], "NLN" ) == 0 )
     390        {
     391                const struct msn_away_state *st;
     392                int cap;
     393               
     394                if( num_parts < 6 )
     395                {
     396                        imcb_error( ic, "Syntax error" );
     397                        imc_logout( ic, TRUE );
     398                        return( 0 );
     399                }
     400               
     401                http_decode( cmd[4] );
     402                cap = atoi( cmd[5] );
     403                imcb_rename_buddy( ic, cmd[2], cmd[4] );
    400404               
    401405                st = msn_away_state_by_code( cmd[1] );
     
    406410                }
    407411               
    408                 imcb_buddy_status( ic, handle, OPT_LOGGED_IN |
     412                imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN |
    409413                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ) |
    410414                                   ( cap & 1 ? OPT_MOBILE : 0 ),
    411415                                   st->name, NULL );
    412416               
    413                 msn_sb_stop_keepalives( msn_sb_by_handle( ic, handle ) );
    414         }
    415         else if( strcmp( cmd[0], "FLN" ) == 0 )
    416         {
    417                 const char *handle;
    418                
    419                 if( cmd[1] == NULL )
    420                         return 1;
    421                
    422                 handle = msn_normalize_handle( cmd[1] );
    423                 imcb_buddy_status( ic, handle, 0, NULL, NULL );
    424                 msn_sb_start_keepalives( msn_sb_by_handle( ic, handle ), TRUE );
     417                msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) );
    425418        }
    426419        else if( strcmp( cmd[0], "RNG" ) == 0 )
     
    469462                else
    470463                {
    471                         sb->who = g_strdup( msn_normalize_handle( cmd[5] ) );
     464                        sb->who = g_strdup( cmd[5] );
    472465                }
    473466        }
     
    562555        {
    563556                /* Status message. */
    564                 if( num_parts >= 3 )
    565                         handler->msglen = atoi( cmd[2] );
     557                if( num_parts >= 4 )
     558                        handler->msglen = atoi( cmd[3] );
    566559        }
    567560        else if( strcmp( cmd[0], "NOT" ) == 0 )
     
    675668                        else if( g_strncasecmp( ct, "text/x-msmsgsactivemailnotification", 35 ) == 0 )
    676669                        {
    677                         }
    678                         else if( g_strncasecmp( ct, "text/x-msmsgsinitialmdatanotification", 37 ) == 0 ||
    679                                  g_strncasecmp( ct, "text/x-msmsgsoimnotification", 28 ) == 0 )
    680                         {
    681                                 /* We received an offline message. Or at least notification
    682                                    that there is one waiting for us. Fetching the message(s)
    683                                    and purging them from the server is a lot of SOAPy work
    684                                    not worth doing IMHO. Also I thought it was possible to
    685                                    have the notification server send them directly, I was
    686                                    pretty sure I saw Pidgin do it..
    687                                    
    688                                    At least give a notification for now, seems like a
    689                                    reasonable thing to do. Only problem is, they'll keep
    690                                    coming back at login time until you read them using a
    691                                    different client. :-( */
    692                                
    693                                 char *xml = get_rfc822_header( body, "Mail-Data:", blen );
    694                                 struct xt_node *md, *m;
    695                                
    696                                 if( !xml )
    697                                         return 1;
    698                                 md = xt_from_string( xml, 0 );
    699                                 if( !md )
    700                                         return 1;
    701                                
    702                                 for( m = md->children; ( m = xt_find_node( m, "M" ) ); m = m->next )
    703                                 {
    704                                         struct xt_node *e = xt_find_node( m->children, "E" );
    705                                         struct xt_node *rt = xt_find_node( m->children, "RT" );
    706                                         struct tm tp;
    707                                         time_t msgtime = 0;
    708                                        
    709                                         if( !e || !e->text )
    710                                                 continue;
    711                                        
    712                                         memset( &tp, 0, sizeof( tp ) );
    713                                         if( rt && rt->text &&
    714                                             sscanf( rt->text, "%4d-%2d-%2dT%2d:%2d:%2d.",
    715                                                     &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
    716                                                     &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) == 6 )
    717                                         {
    718                                                 tp.tm_year -= 1900;
    719                                                 tp.tm_mon --;
    720                                                 msgtime = mktime_utc( &tp );
    721                                                
    722                                         }
    723                                         imcb_buddy_msg( ic, e->text, "<< \002BitlBee\002 - Received offline message. BitlBee can't show these. >>", 0, msgtime );
    724                                 }
    725                                
    726                                 g_free( xml );
    727                                 xt_free_node( md );
     670                                /* Sorry, but this one really is *USELESS* */
    728671                        }
    729672                        else
     
    745688                        psm_text = psm->text;
    746689               
    747                 imcb_buddy_status_msg( ic, msn_normalize_handle( cmd[1] ), psm_text );
     690                imcb_buddy_status_msg( ic, cmd[1], psm_text );
    748691                xt_free_node( ubx );
    749692        }
     
    814757        if( token )
    815758        {
    816                 msn_ns_write( ic, -1, "USR %d SSO S %s %s {%s}\r\n", ++md->trId, md->tokens[0], token, md->uuid );
     759                msn_ns_write( ic, -1, "USR %d SSO S %s %s\r\n", ++md->trId, md->tokens[0], token );
    817760        }
    818761        else
     
    943886        return 1;
    944887}
    945 
    946 int msn_ns_sendmessage( struct im_connection *ic, bee_user_t *bu, const char *text )
    947 {
    948         struct msn_data *md = ic->proto_data;
    949         char *buf;
    950        
    951         if( strncmp( text, "\r\r\r", 3 ) == 0 )
    952                 /* Err. Shouldn't happen but I guess it can. Don't send others
    953                    any of the "SHAKE THAT THING" messages. :-D */
    954                 return 1;
    955        
    956         buf = g_strdup_printf( "%s%s", MSN_MESSAGE_HEADERS, text );
    957        
    958         if( msn_ns_write( ic, -1, "UUM %d %s %d %d %zd\r\n%s",
    959                                   ++md->trId, bu->handle,
    960                                   1, /* type == MSN offline message */
    961                                   1, /* type == IM (not nudge/typing) */
    962                                   strlen( buf ), buf ) )
    963                 return 1;
    964         else
    965                 return 0;
    966 }
    967 
    968 void msn_ns_oim_send_queue( struct im_connection *ic, GSList **msgq )
    969 {
    970         GSList *l;
    971        
    972         for( l = *msgq; l; l = l->next )
    973         {
    974                 struct msn_message *m = l->data;
    975                 bee_user_t *bu = bee_user_by_handle( ic->bee, ic, m->who );
    976                
    977                 if( bu )
    978                         if( !msn_ns_sendmessage( ic, bu, m->text ) )
    979                                 return;
    980         }
    981        
    982         while( *msgq != NULL )
    983         {
    984                 struct msn_message *m = (*msgq)->data;
    985                
    986                 g_free( m->who );
    987                 g_free( m->text );
    988                 g_free( m );
    989                
    990                 *msgq = g_slist_remove( *msgq, m );
    991         }
    992 }
Note: See TracChangeset for help on using the changeset viewer.