Ignore:
Timestamp:
2008-04-02T14:22:57Z (16 years ago)
Author:
Jelmer Vernooij <jelmer@…>
Branches:
master
Children:
f9dbc99
Parents:
875ad42 (diff), dd34575 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/msn.c

    r875ad42 r85d7b85  
    2727#include "msn.h"
    2828
    29 static void msn_login( struct aim_user *acct )
    30 {
    31         struct gaim_connection *gc = new_gaim_conn( acct );
     29static char *msn_set_display_name( set_t *set, char *value );
     30
     31static void msn_init( account_t *acc )
     32{
     33        set_t *s;
     34       
     35        s = set_add( &acc->set, "display_name", NULL, msn_set_display_name, acc );
     36        s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY;
     37
     38        s = set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc );
     39}
     40
     41static void msn_login( account_t *acc )
     42{
     43        struct im_connection *ic = imcb_new( acc );
    3244        struct msn_data *md = g_new0( struct msn_data, 1 );
    3345       
    34         set_login_progress( gc, 1, "Connecting" );
    35        
    36         gc->proto_data = md;
     46        ic->proto_data = md;
    3747        md->fd = -1;
    3848       
    39         if( strchr( acct->username, '@' ) == NULL )
    40         {
    41                 hide_login_progress( gc, "Invalid account name" );
    42                 signoff( gc );
     49        if( strchr( acc->user, '@' ) == NULL )
     50        {
     51                imcb_error( ic, "Invalid account name" );
     52                imc_logout( ic, FALSE );
    4353                return;
    4454        }
    4555       
    46         md->fd = proxy_connect( "messenger.hotmail.com", 1863, msn_ns_connected, gc );
     56        imcb_log( ic, "Connecting" );
     57       
     58        md->fd = proxy_connect( "messenger.hotmail.com", 1863, msn_ns_connected, ic );
    4759        if( md->fd < 0 )
    4860        {
    49                 hide_login_progress( gc, "Could not connect to server" );
    50                 signoff( gc );
    51         }
    52         else
    53         {
    54                 md->gc = gc;
    55                 md->away_state = msn_away_state_list;
    56                
    57                 msn_connections = g_slist_append( msn_connections, gc );
    58         }
    59 }
    60 
    61 static void msn_close( struct gaim_connection *gc )
    62 {
    63         struct msn_data *md = gc->proto_data;
     61                imcb_error( ic, "Could not connect to server" );
     62                imc_logout( ic, TRUE );
     63                return;
     64        }
     65       
     66        md->ic = ic;
     67        md->away_state = msn_away_state_list;
     68       
     69        msn_connections = g_slist_append( msn_connections, ic );
     70}
     71
     72static void msn_logout( struct im_connection *ic )
     73{
     74        struct msn_data *md = ic->proto_data;
    6475        GSList *l;
    6576       
    66         if( md->fd >= 0 )
    67                 closesocket( md->fd );
    68        
    69         if( md->handler )
    70         {
    71                 if( md->handler->rxq ) g_free( md->handler->rxq );
    72                 if( md->handler->cmd_text ) g_free( md->handler->cmd_text );
    73                 g_free( md->handler );
    74         }
    75        
    76         while( md->switchboards )
    77                 msn_sb_destroy( md->switchboards->data );
    78        
    79         if( md->msgq )
    80         {
    81                 struct msn_message *m;
    82                
    83                 for( l = md->msgq; l; l = l->next )
     77        if( md )
     78        {
     79                if( md->fd >= 0 )
     80                        closesocket( md->fd );
     81               
     82                if( md->handler )
    8483                {
    85                         m = l->data;
    86                
    87                         serv_got_crap( gc, "Warning: Closing down MSN connection with unsent message to %s, you'll have to resend it.", m->who );
    88                         g_free( m->who );
    89                         g_free( m->text );
    90                         g_free( m );
     84                        if( md->handler->rxq ) g_free( md->handler->rxq );
     85                        if( md->handler->cmd_text ) g_free( md->handler->cmd_text );
     86                        g_free( md->handler );
    9187                }
    92                 g_slist_free( md->msgq );
    93         }
    94        
    95         for( l = gc->permit; l; l = l->next )
     88               
     89                while( md->switchboards )
     90                        msn_sb_destroy( md->switchboards->data );
     91               
     92                msn_msgq_purge( ic, &md->msgq );
     93               
     94                while( md->groupcount > 0 )
     95                        g_free( md->grouplist[--md->groupcount] );
     96                g_free( md->grouplist );
     97               
     98                g_free( md );
     99        }
     100       
     101        for( l = ic->permit; l; l = l->next )
    96102                g_free( l->data );
    97         g_slist_free( gc->permit );
    98        
    99         for( l = gc->deny; l; l = l->next )
     103        g_slist_free( ic->permit );
     104       
     105        for( l = ic->deny; l; l = l->next )
    100106                g_free( l->data );
    101         g_slist_free( gc->deny );
    102        
    103         g_free( md );
    104        
    105         msn_connections = g_slist_remove( msn_connections, gc );
    106 }
    107 
    108 static int msn_send_im( struct gaim_connection *gc, char *who, char *message, int len, int away )
     107        g_slist_free( ic->deny );
     108       
     109        msn_connections = g_slist_remove( msn_connections, ic );
     110}
     111
     112static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, int away )
    109113{
    110114        struct msn_switchboard *sb;
    111         struct msn_data *md = gc->proto_data;
    112        
    113         if( ( sb = msn_sb_by_handle( gc, who ) ) )
     115        struct msn_data *md = ic->proto_data;
     116       
     117        if( ( sb = msn_sb_by_handle( ic, who ) ) )
    114118        {
    115119                return( msn_sb_sendmessage( sb, message ) );
     
    126130               
    127131                /* FIXME: *CHECK* the reliability of using spare sb's! */
    128                 if( ( sb = msn_sb_spare( gc ) ) )
     132                if( ( sb = msn_sb_spare( ic ) ) )
    129133                {
    130134                        debug( "Trying to use a spare switchboard to message %s", who );
     
    144148                /* If we reach this line, there was no spare switchboard, so let's make one. */
    145149                g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
    146                 if( !msn_write( gc, buf, strlen( buf ) ) )
     150                if( !msn_write( ic, buf, strlen( buf ) ) )
    147151                {
    148152                        g_free( m->who );
     
    164168}
    165169
    166 static GList *msn_away_states( struct gaim_connection *gc )
    167 {
    168         GList *l = NULL;
     170static GList *msn_away_states( struct im_connection *ic )
     171{
     172        static GList *l = NULL;
    169173        int i;
    170174       
    171         for( i = 0; msn_away_state_list[i].number > -1; i ++ )
    172                 l = g_list_append( l, (void*) msn_away_state_list[i].name );
    173        
    174         return( l );
    175 }
    176 
    177 static char *msn_get_status_string( struct gaim_connection *gc, int number )
    178 {
    179         const struct msn_away_state *st = msn_away_state_by_number( number );
    180        
    181         if( st )
    182                 return( (char*) st->name );
    183         else
    184                 return( "" );
    185 }
    186 
    187 static void msn_set_away( struct gaim_connection *gc, char *state, char *message )
     175        if( l == NULL )
     176                for( i = 0; msn_away_state_list[i].number > -1; i ++ )
     177                        l = g_list_append( l, (void*) msn_away_state_list[i].name );
     178       
     179        return l;
     180}
     181
     182static void msn_set_away( struct im_connection *ic, char *state, char *message )
    188183{
    189184        char buf[1024];
    190         struct msn_data *md = gc->proto_data;
     185        struct msn_data *md = ic->proto_data;
    191186        const struct msn_away_state *st;
    192187       
     
    200195       
    201196        g_snprintf( buf, sizeof( buf ), "CHG %d %s\r\n", ++md->trId, st->code );
    202         msn_write( gc, buf, strlen( buf ) );
    203 }
    204 
    205 static void msn_set_info( struct gaim_connection *gc, char *info )
    206 {
    207         int i;
    208         char buf[1024], *fn, *s;
    209         struct msn_data *md = gc->proto_data;
    210        
    211         if( strlen( info ) > 129 )
    212         {
    213                 do_error_dialog( gc, "Maximum name length exceeded", "MSN" );
    214                 return;
    215         }
    216        
    217         /* Of course we could use http_encode() here, but when we encode
    218            every character, the server is less likely to complain about the
    219            chosen name. However, the MSN server doesn't seem to like escaped
    220            non-ASCII chars, so we keep those unescaped. */
    221         s = fn = g_new0( char, strlen( info ) * 3 + 1 );
    222         for( i = 0; info[i]; i ++ )
    223                 if( info[i] & 128 )
    224                 {
    225                         *s = info[i];
    226                         s ++;
    227                 }
    228                 else
    229                 {
    230                         g_snprintf( s, 4, "%%%02X", info[i] );
    231                         s += 3;
    232                 }
    233        
    234         g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn );
    235         msn_write( gc, buf, strlen( buf ) );
    236         g_free( fn );
    237 }
    238 
    239 static void msn_get_info(struct gaim_connection *gc, char *who)
     197        msn_write( ic, buf, strlen( buf ) );
     198}
     199
     200static void msn_set_my_name( struct im_connection *ic, char *info )
     201{
     202        msn_set_display_name( set_find( &ic->acc->set, "display_name" ), info );
     203}
     204
     205static void msn_get_info(struct im_connection *ic, char *who)
    240206{
    241207        /* Just make an URL and let the user fetch the info */
    242         serv_got_crap( gc, "%s\n%s: %s%s", _("User Info"), _("For now, fetch yourself"), PROFILE_URL, who );
    243 }
    244 
    245 static void msn_add_buddy( struct gaim_connection *gc, char *who )
    246 {
    247         msn_buddy_list_add( gc, "FL", who, who );
    248 }
    249 
    250 static void msn_remove_buddy( struct gaim_connection *gc, char *who, char *group )
    251 {
    252         msn_buddy_list_remove( gc, "FL", who );
    253 }
    254 
    255 static int msn_chat_send( struct gaim_connection *gc, int id, char *message )
    256 {
    257         struct msn_switchboard *sb = msn_sb_by_id( gc, id );
     208        imcb_log( ic, "%s\n%s: %s%s", _("User Info"), _("For now, fetch yourself"), PROFILE_URL, who );
     209}
     210
     211static void msn_add_buddy( struct im_connection *ic, char *who, char *group )
     212{
     213        msn_buddy_list_add( ic, "FL", who, who );
     214}
     215
     216static void msn_remove_buddy( struct im_connection *ic, char *who, char *group )
     217{
     218        msn_buddy_list_remove( ic, "FL", who );
     219}
     220
     221static void msn_chat_msg( struct groupchat *c, char *message, int flags )
     222{
     223        struct msn_switchboard *sb = msn_sb_by_chat( c );
    258224       
    259225        if( sb )
    260                 return( msn_sb_sendmessage( sb, message ) );
    261         else
    262                 return( 0 );
    263 }
    264 
    265 static void msn_chat_invite( struct gaim_connection *gc, int id, char *msg, char *who )
    266 {
    267         struct msn_switchboard *sb = msn_sb_by_id( gc, id );
     226                msn_sb_sendmessage( sb, message );
     227        /* FIXME: Error handling (although this can't happen unless something's
     228           already severely broken) disappeared here! */
     229}
     230
     231static void msn_chat_invite( struct groupchat *c, char *who, char *message )
     232{
     233        struct msn_switchboard *sb = msn_sb_by_chat( c );
    268234        char buf[1024];
    269235       
     
    275241}
    276242
    277 static void msn_chat_leave( struct gaim_connection *gc, int id )
    278 {
    279         struct msn_switchboard *sb = msn_sb_by_id( gc, id );
     243static void msn_chat_leave( struct groupchat *c )
     244{
     245        struct msn_switchboard *sb = msn_sb_by_chat( c );
    280246       
    281247        if( sb )
     
    283249}
    284250
    285 static int msn_chat_open( struct gaim_connection *gc, char *who )
     251static struct groupchat *msn_chat_with( struct im_connection *ic, char *who )
    286252{
    287253        struct msn_switchboard *sb;
    288         struct msn_data *md = gc->proto_data;
     254        struct msn_data *md = ic->proto_data;
    289255        char buf[1024];
    290256       
    291         if( ( sb = msn_sb_by_handle( gc, who ) ) )
     257        if( ( sb = msn_sb_by_handle( ic, who ) ) )
    292258        {
    293259                debug( "Converting existing switchboard to %s to a groupchat", who );
    294                 msn_sb_to_chat( sb );
    295                 return( 1 );
     260                return msn_sb_to_chat( sb );
    296261        }
    297262        else
     
    299264                struct msn_message *m;
    300265               
    301                 if( ( sb = msn_sb_spare( gc ) ) )
     266                if( ( sb = msn_sb_spare( ic ) ) )
    302267                {
    303268                        debug( "Trying to reuse an existing switchboard as a groupchat with %s", who );
    304269                        g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who );
    305270                        if( msn_sb_write( sb, buf, strlen( buf ) ) )
    306                         {
    307                                 msn_sb_to_chat( sb );
    308                                 return( 1 );
    309                         }
     271                                return msn_sb_to_chat( sb );
    310272                }
    311273               
     
    315277                /* Request a new switchboard. */
    316278                g_snprintf( buf, sizeof( buf ), "XFR %d SB\r\n", ++md->trId );
    317                 if( !msn_write( gc, buf, strlen( buf ) ) )
     279                if( !msn_write( ic, buf, strlen( buf ) ) )
    318280                        return( 0 );
    319281               
     
    326288                md->msgq = g_slist_append( md->msgq, m );
    327289               
    328                 return( 1 );
    329         }
    330        
    331         return( 0 );
    332 }
    333 
    334 static void msn_keepalive( struct gaim_connection *gc )
    335 {
    336         msn_write( gc, "PNG\r\n", strlen( "PNG\r\n" ) );
    337 }
    338 
    339 static void msn_add_permit( struct gaim_connection *gc, char *who )
    340 {
    341         msn_buddy_list_add( gc, "AL", who, who );
    342 }
    343 
    344 static void msn_rem_permit( struct gaim_connection *gc, char *who )
    345 {
    346         msn_buddy_list_remove( gc, "AL", who );
    347 }
    348 
    349 static void msn_add_deny( struct gaim_connection *gc, char *who )
     290                /* FIXME: Can I try to return something here already? */
     291                return NULL;
     292        }
     293       
     294        return NULL;
     295}
     296
     297static void msn_keepalive( struct im_connection *ic )
     298{
     299        msn_write( ic, "PNG\r\n", strlen( "PNG\r\n" ) );
     300}
     301
     302static void msn_add_permit( struct im_connection *ic, char *who )
     303{
     304        msn_buddy_list_add( ic, "AL", who, who );
     305}
     306
     307static void msn_rem_permit( struct im_connection *ic, char *who )
     308{
     309        msn_buddy_list_remove( ic, "AL", who );
     310}
     311
     312static void msn_add_deny( struct im_connection *ic, char *who )
    350313{
    351314        struct msn_switchboard *sb;
    352315       
    353         msn_buddy_list_add( gc, "BL", who, who );
     316        msn_buddy_list_add( ic, "BL", who, who );
    354317       
    355318        /* If there's still a conversation with this person, close it. */
    356         if( ( sb = msn_sb_by_handle( gc, who ) ) )
     319        if( ( sb = msn_sb_by_handle( ic, who ) ) )
    357320        {
    358321                msn_sb_destroy( sb );
     
    360323}
    361324
    362 static void msn_rem_deny( struct gaim_connection *gc, char *who )
    363 {
    364         msn_buddy_list_remove( gc, "BL", who );
    365 }
    366 
    367 static int msn_send_typing( struct gaim_connection *gc, char *who, int typing )
    368 {
    369         if( typing )
    370                 return( msn_send_im( gc, who, TYPING_NOTIFICATION_MESSAGE, strlen( TYPING_NOTIFICATION_MESSAGE ), 0 ) );
     325static void msn_rem_deny( struct im_connection *ic, char *who )
     326{
     327        msn_buddy_list_remove( ic, "BL", who );
     328}
     329
     330static int msn_send_typing( struct im_connection *ic, char *who, int typing )
     331{
     332        if( typing & OPT_TYPING )
     333                return( msn_buddy_msg( ic, who, TYPING_NOTIFICATION_MESSAGE, 0 ) );
    371334        else
    372335                return( 1 );
    373336}
    374337
    375 void msn_init()
     338static char *msn_set_display_name( set_t *set, char *value )
     339{
     340        account_t *acc = set->data;
     341        struct im_connection *ic = acc->ic;
     342        struct msn_data *md;
     343        char buf[1024], *fn;
     344       
     345        /* Double-check. */
     346        if( ic == NULL )
     347                return NULL;
     348       
     349        md = ic->proto_data;
     350       
     351        if( strlen( value ) > 129 )
     352        {
     353                imcb_log( ic, "Maximum name length exceeded" );
     354                return NULL;
     355        }
     356       
     357        fn = msn_http_encode( value );
     358       
     359        g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn );
     360        msn_write( ic, buf, strlen( buf ) );
     361        g_free( fn );
     362       
     363        /* Returning NULL would be better, because the server still has to
     364           confirm the name change. However, it looks a bit confusing to the
     365           user. */
     366        return value;
     367}
     368
     369void msn_initmodule()
    376370{
    377371        struct prpl *ret = g_new0(struct prpl, 1);
     372       
    378373        ret->name = "msn";
    379374        ret->login = msn_login;
    380         ret->close = msn_close;
    381         ret->send_im = msn_send_im;
     375        ret->init = msn_init;
     376        ret->logout = msn_logout;
     377        ret->buddy_msg = msn_buddy_msg;
    382378        ret->away_states = msn_away_states;
    383         ret->get_status_string = msn_get_status_string;
    384379        ret->set_away = msn_set_away;
    385         ret->set_info = msn_set_info;
    386380        ret->get_info = msn_get_info;
     381        ret->set_my_name = msn_set_my_name;
    387382        ret->add_buddy = msn_add_buddy;
    388383        ret->remove_buddy = msn_remove_buddy;
    389         ret->chat_send = msn_chat_send;
     384        ret->chat_msg = msn_chat_msg;
    390385        ret->chat_invite = msn_chat_invite;
    391386        ret->chat_leave = msn_chat_leave;
    392         ret->chat_open = msn_chat_open;
     387        ret->chat_with = msn_chat_with;
    393388        ret->keepalive = msn_keepalive;
    394389        ret->add_permit = msn_add_permit;
     
    397392        ret->rem_deny = msn_rem_deny;
    398393        ret->send_typing = msn_send_typing;
    399         ret->cmp_buddynames = g_strcasecmp;
     394        ret->handle_cmp = g_strcasecmp;
    400395
    401396        register_protocol(ret);
Note: See TracChangeset for help on using the changeset viewer.