Changeset 5ebff60 for protocols/msn/sb.c


Ignore:
Timestamp:
2015-02-20T22:50:54Z (9 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
0b9daac, 3d45471, 7733b8c
Parents:
af359b4
git-author:
Indent <please@…> (19-02-15 05:47:20)
git-committer:
dequis <dx@…> (20-02-15 22:50:54)
Message:

Reindent everything to K&R style with tabs

Used uncrustify, with the configuration file in ./doc/uncrustify.cfg

Commit author set to "Indent <please@…>" so that it's easier to
skip while doing git blame.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/msn/sb.c

    raf359b4 r5ebff60  
    1   /********************************************************************\
     1/********************************************************************\
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
     
    3131#include "invitation.h"
    3232
    33 static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond );
    34 static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts );
    35 static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts );
    36 
    37 int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... )
     33static gboolean msn_sb_callback(gpointer data, gint source, b_input_condition cond);
     34static int msn_sb_command(struct msn_handler_data *handler, char **cmd, int num_parts);
     35static int msn_sb_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts);
     36
     37int msn_sb_write(struct msn_switchboard *sb, const char *fmt, ...)
    3838{
    3939        va_list params;
     
    4141        size_t len;
    4242        int st;
    43        
    44         va_start( params, fmt );
    45         out = g_strdup_vprintf( fmt, params );
    46         va_end( params );
    47        
    48         if( getenv( "BITLBEE_DEBUG" ) )
    49                 fprintf( stderr, "->SB%d:%s\n", sb->fd, out );
    50        
    51         len = strlen( out );
    52         st = write( sb->fd, out, len );
    53         g_free( out );
    54         if( st != len )
    55         {
    56                 msn_sb_destroy( sb );
     43
     44        va_start(params, fmt);
     45        out = g_strdup_vprintf(fmt, params);
     46        va_end(params);
     47
     48        if (getenv("BITLBEE_DEBUG")) {
     49                fprintf(stderr, "->SB%d:%s\n", sb->fd, out);
     50        }
     51
     52        len = strlen(out);
     53        st = write(sb->fd, out, len);
     54        g_free(out);
     55        if (st != len) {
     56                msn_sb_destroy(sb);
    5757                return 0;
    5858        }
    59        
     59
    6060        return 1;
    6161}
    6262
    63 int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m )
     63int msn_sb_write_msg(struct im_connection *ic, struct msn_message *m)
    6464{
    6565        struct msn_data *md = ic->proto_data;
     
    6767
    6868        /* FIXME: *CHECK* the reliability of using spare sb's! */
    69         if( ( sb = msn_sb_spare( ic ) ) )
    70         {
    71                 debug( "Trying to use a spare switchboard to message %s", m->who );
    72                
    73                 sb->who = g_strdup( m->who );
    74                 if( msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, m->who ) )
    75                 {
     69        if ((sb = msn_sb_spare(ic))) {
     70                debug("Trying to use a spare switchboard to message %s", m->who);
     71
     72                sb->who = g_strdup(m->who);
     73                if (msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, m->who)) {
    7674                        /* He/She should join the switchboard soon, let's queue the message. */
    77                         sb->msgq = g_slist_append( sb->msgq, m );
    78                         return( 1 );
    79                 }
    80         }
    81        
    82         debug( "Creating a new switchboard to message %s", m->who );
    83        
     75                        sb->msgq = g_slist_append(sb->msgq, m);
     76                        return(1);
     77                }
     78        }
     79
     80        debug("Creating a new switchboard to message %s", m->who);
     81
    8482        /* If we reach this line, there was no spare switchboard, so let's make one. */
    85         if( !msn_ns_write( ic, -1, "XFR %d SB\r\n", ++md->trId ) )
    86         {
    87                 g_free( m->who );
    88                 g_free( m->text );
    89                 g_free( m );
    90                
    91                 return( 0 );
    92         }
    93        
     83        if (!msn_ns_write(ic, -1, "XFR %d SB\r\n", ++md->trId)) {
     84                g_free(m->who);
     85                g_free(m->text);
     86                g_free(m);
     87
     88                return(0);
     89        }
     90
    9491        /* And queue the message to md. We'll pick it up when the switchboard comes up. */
    95         md->msgq = g_slist_append( md->msgq, m );
    96        
     92        md->msgq = g_slist_append(md->msgq, m);
     93
    9794        /* FIXME: If the switchboard creation fails, the message will not be sent. */
    98        
    99         return( 1 );
    100 }
    101 
    102 struct msn_switchboard *msn_sb_create( struct im_connection *ic, char *host, int port, char *key, int session )
     95
     96        return(1);
     97}
     98
     99struct msn_switchboard *msn_sb_create(struct im_connection *ic, char *host, int port, char *key, int session)
    103100{
    104101        struct msn_data *md = ic->proto_data;
    105         struct msn_switchboard *sb = g_new0( struct msn_switchboard, 1 );
    106        
    107         sb->fd = proxy_connect( host, port, msn_sb_connected, sb );
    108         if( sb->fd < 0 )
    109         {
    110                 g_free( sb );
    111                 return( NULL );
    112         }
    113        
     102        struct msn_switchboard *sb = g_new0(struct msn_switchboard, 1);
     103
     104        sb->fd = proxy_connect(host, port, msn_sb_connected, sb);
     105        if (sb->fd < 0) {
     106                g_free(sb);
     107                return(NULL);
     108        }
     109
    114110        sb->ic = ic;
    115         sb->key = g_strdup( key );
     111        sb->key = g_strdup(key);
    116112        sb->session = session;
    117        
    118         msn_switchboards = g_slist_append( msn_switchboards, sb );
    119         md->switchboards = g_slist_append( md->switchboards, sb );
    120        
    121         return( sb );
    122 }
    123 
    124 struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, const char *handle )
     113
     114        msn_switchboards = g_slist_append(msn_switchboards, sb);
     115        md->switchboards = g_slist_append(md->switchboards, sb);
     116
     117        return(sb);
     118}
     119
     120struct msn_switchboard *msn_sb_by_handle(struct im_connection *ic, const char *handle)
    125121{
    126122        struct msn_data *md = ic->proto_data;
    127123        struct msn_switchboard *sb;
    128124        GSList *l;
    129        
    130         for( l = md->switchboards; l; l = l->next )
    131         {
     125
     126        for (l = md->switchboards; l; l = l->next) {
    132127                sb = l->data;
    133                 if( sb->who && strcmp( sb->who, handle ) == 0 )
    134                         return( sb );
    135         }
    136        
    137         return( NULL );
    138 }
    139 
    140 struct msn_switchboard *msn_sb_by_chat( struct groupchat *c )
     128                if (sb->who && strcmp(sb->who, handle) == 0) {
     129                        return(sb);
     130                }
     131        }
     132
     133        return(NULL);
     134}
     135
     136struct msn_switchboard *msn_sb_by_chat(struct groupchat *c)
    141137{
    142138        struct msn_data *md = c->ic->proto_data;
    143139        struct msn_switchboard *sb;
    144140        GSList *l;
    145        
    146         for( l = md->switchboards; l; l = l->next )
    147         {
     141
     142        for (l = md->switchboards; l; l = l->next) {
    148143                sb = l->data;
    149                 if( sb->chat == c )
    150                         return( sb );
    151         }
    152        
    153         return( NULL );
    154 }
    155 
    156 struct msn_switchboard *msn_sb_spare( struct im_connection *ic )
     144                if (sb->chat == c) {
     145                        return(sb);
     146                }
     147        }
     148
     149        return(NULL);
     150}
     151
     152struct msn_switchboard *msn_sb_spare(struct im_connection *ic)
    157153{
    158154        struct msn_data *md = ic->proto_data;
    159155        struct msn_switchboard *sb;
    160156        GSList *l;
    161        
    162         for( l = md->switchboards; l; l = l->next )
    163         {
     157
     158        for (l = md->switchboards; l; l = l->next) {
    164159                sb = l->data;
    165                 if( !sb->who && !sb->chat )
    166                         return( sb );
    167         }
    168        
    169         return( NULL );
    170 }
    171 
    172 int msn_sb_sendmessage( struct msn_switchboard *sb, char *text )
    173 {
    174         if( sb->ready )
    175         {
     160                if (!sb->who && !sb->chat) {
     161                        return(sb);
     162                }
     163        }
     164
     165        return(NULL);
     166}
     167
     168int msn_sb_sendmessage(struct msn_switchboard *sb, char *text)
     169{
     170        if (sb->ready) {
    176171                char *buf;
    177172                int i, j;
    178                
     173
    179174                /* Build the message. Convert LF to CR-LF for normal messages. */
    180                 if( strcmp( text, TYPING_NOTIFICATION_MESSAGE ) == 0 )
    181                 {
    182                         i = strlen( MSN_TYPING_HEADERS ) + strlen( sb->ic->acc->user );
    183                         buf = g_new0( char, i );
    184                         i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user );
    185                 }
    186                 else if( strcmp( text, NUDGE_MESSAGE ) == 0 )
    187                 {
    188                         buf = g_strdup( MSN_NUDGE_HEADERS );
    189                         i = strlen( buf );
    190                 }
    191                 else if( strcmp( text, SB_KEEPALIVE_MESSAGE ) == 0 )
    192                 {
    193                         buf = g_strdup( MSN_SB_KEEPALIVE_HEADERS );
    194                         i = strlen( buf );
    195                 }
    196                 else if( strncmp( text, MSN_INVITE_HEADERS, sizeof( MSN_INVITE_HEADERS ) - 1 ) == 0 )
    197                 {
    198                         buf = g_strdup( text );
    199                         i = strlen( buf );
    200                 }
    201                 else
    202                 {
    203                         buf = g_new0( char, sizeof( MSN_MESSAGE_HEADERS ) + strlen( text ) * 2 + 1 );
    204                         i = strlen( MSN_MESSAGE_HEADERS );
    205                        
    206                         strcpy( buf, MSN_MESSAGE_HEADERS );
    207                         for( j = 0; text[j]; j ++ )
    208                         {
    209                                 if( text[j] == '\n' )
     175                if (strcmp(text, TYPING_NOTIFICATION_MESSAGE) == 0) {
     176                        i = strlen(MSN_TYPING_HEADERS) + strlen(sb->ic->acc->user);
     177                        buf = g_new0(char, i);
     178                        i = g_snprintf(buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user);
     179                } else if (strcmp(text, NUDGE_MESSAGE) == 0) {
     180                        buf = g_strdup(MSN_NUDGE_HEADERS);
     181                        i = strlen(buf);
     182                } else if (strcmp(text, SB_KEEPALIVE_MESSAGE) == 0) {
     183                        buf = g_strdup(MSN_SB_KEEPALIVE_HEADERS);
     184                        i = strlen(buf);
     185                } else if (strncmp(text, MSN_INVITE_HEADERS, sizeof(MSN_INVITE_HEADERS) - 1) == 0) {
     186                        buf = g_strdup(text);
     187                        i = strlen(buf);
     188                } else {
     189                        buf = g_new0(char, sizeof(MSN_MESSAGE_HEADERS) + strlen(text) * 2 + 1);
     190                        i = strlen(MSN_MESSAGE_HEADERS);
     191
     192                        strcpy(buf, MSN_MESSAGE_HEADERS);
     193                        for (j = 0; text[j]; j++) {
     194                                if (text[j] == '\n') {
    210195                                        buf[i++] = '\r';
    211                                
     196                                }
     197
    212198                                buf[i++] = text[j];
    213199                        }
    214200                }
    215                
     201
    216202                /* Build the final packet (MSG command + the message). */
    217                 if( msn_sb_write( sb, "MSG %d N %d\r\n%s", ++sb->trId, i, buf ) )
    218                 {
    219                         g_free( buf );
     203                if (msn_sb_write(sb, "MSG %d N %d\r\n%s", ++sb->trId, i, buf)) {
     204                        g_free(buf);
    220205                        return 1;
    221                 }
    222                 else
    223                 {
    224                         g_free( buf );
     206                } else {
     207                        g_free(buf);
    225208                        return 0;
    226209                }
    227         }
    228         else if( sb->who )
    229         {
    230                 struct msn_message *m = g_new0( struct msn_message, 1 );
    231                
    232                 m->who = g_strdup( "" );
    233                 m->text = g_strdup( text );
    234                 sb->msgq = g_slist_append( sb->msgq, m );
    235                
    236                 return( 1 );
    237         }
    238         else
    239         {
    240                 return( 0 );
    241         }
    242 }
    243 
    244 struct groupchat *msn_sb_to_chat( struct msn_switchboard *sb )
     210        } else if (sb->who) {
     211                struct msn_message *m = g_new0(struct msn_message, 1);
     212
     213                m->who = g_strdup("");
     214                m->text = g_strdup(text);
     215                sb->msgq = g_slist_append(sb->msgq, m);
     216
     217                return(1);
     218        } else {
     219                return(0);
     220        }
     221}
     222
     223struct groupchat *msn_sb_to_chat(struct msn_switchboard *sb)
    245224{
    246225        struct im_connection *ic = sb->ic;
    247226        struct groupchat *c = NULL;
    248227        char buf[1024];
    249        
     228
    250229        /* Create the groupchat structure. */
    251         g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
    252         if( sb->who )
    253                 c = bee_chat_by_title( ic->bee, ic, sb->who );
    254         if( c && !msn_sb_by_chat( c ) )
     230        g_snprintf(buf, sizeof(buf), "MSN groupchat session %d", sb->session);
     231        if (sb->who) {
     232                c = bee_chat_by_title(ic->bee, ic, sb->who);
     233        }
     234        if (c && !msn_sb_by_chat(c)) {
    255235                sb->chat = c;
    256         else
    257                 sb->chat = imcb_chat_new( ic, buf );
    258        
     236        } else {
     237                sb->chat = imcb_chat_new(ic, buf);
     238        }
     239
    259240        /* Populate the channel. */
    260         if( sb->who ) imcb_chat_add_buddy( sb->chat, sb->who );
    261         imcb_chat_add_buddy( sb->chat, ic->acc->user );
    262        
     241        if (sb->who) {
     242                imcb_chat_add_buddy(sb->chat, sb->who);
     243        }
     244        imcb_chat_add_buddy(sb->chat, ic->acc->user);
     245
    263246        /* And make sure the switchboard doesn't look like a regular chat anymore. */
    264         if( sb->who )
    265         {
    266                 g_free( sb->who );
     247        if (sb->who) {
     248                g_free(sb->who);
    267249                sb->who = NULL;
    268250        }
    269        
     251
    270252        return sb->chat;
    271253}
    272254
    273 void msn_sb_destroy( struct msn_switchboard *sb )
     255void msn_sb_destroy(struct msn_switchboard *sb)
    274256{
    275257        struct im_connection *ic = sb->ic;
    276258        struct msn_data *md = ic->proto_data;
    277        
    278         debug( "Destroying switchboard: %s", sb->who ? sb->who : sb->key ? sb->key : "" );
    279        
    280         msn_msgq_purge( ic, &sb->msgq );
    281         msn_sb_stop_keepalives( sb );
    282        
    283         if( sb->key ) g_free( sb->key );
    284         if( sb->who ) g_free( sb->who );
    285        
    286         if( sb->chat )
    287         {
    288                 imcb_chat_free( sb->chat );
    289         }
    290        
    291         if( sb->handler )
    292         {
    293                 if( sb->handler->rxq ) g_free( sb->handler->rxq );
    294                 if( sb->handler->cmd_text ) g_free( sb->handler->cmd_text );
    295                 g_free( sb->handler );
    296         }
    297        
    298         if( sb->inp ) b_event_remove( sb->inp );
    299         closesocket( sb->fd );
    300        
    301         msn_switchboards = g_slist_remove( msn_switchboards, sb );
    302         md->switchboards = g_slist_remove( md->switchboards, sb );
    303         g_free( sb );
    304 }
    305 
    306 gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond )
     259
     260        debug("Destroying switchboard: %s", sb->who ? sb->who : sb->key ? sb->key : "");
     261
     262        msn_msgq_purge(ic, &sb->msgq);
     263        msn_sb_stop_keepalives(sb);
     264
     265        if (sb->key) {
     266                g_free(sb->key);
     267        }
     268        if (sb->who) {
     269                g_free(sb->who);
     270        }
     271
     272        if (sb->chat) {
     273                imcb_chat_free(sb->chat);
     274        }
     275
     276        if (sb->handler) {
     277                if (sb->handler->rxq) {
     278                        g_free(sb->handler->rxq);
     279                }
     280                if (sb->handler->cmd_text) {
     281                        g_free(sb->handler->cmd_text);
     282                }
     283                g_free(sb->handler);
     284        }
     285
     286        if (sb->inp) {
     287                b_event_remove(sb->inp);
     288        }
     289        closesocket(sb->fd);
     290
     291        msn_switchboards = g_slist_remove(msn_switchboards, sb);
     292        md->switchboards = g_slist_remove(md->switchboards, sb);
     293        g_free(sb);
     294}
     295
     296gboolean msn_sb_connected(gpointer data, gint source, b_input_condition cond)
    307297{
    308298        struct msn_switchboard *sb = data;
     
    310300        struct msn_data *md;
    311301        char buf[1024];
    312        
     302
    313303        /* Are we still alive? */
    314         if( !g_slist_find( msn_switchboards, sb ) )
     304        if (!g_slist_find(msn_switchboards, sb)) {
    315305                return FALSE;
    316        
     306        }
     307
    317308        ic = sb->ic;
    318309        md = ic->proto_data;
    319        
    320         if( source != sb->fd )
    321         {
    322                 debug( "Error %d while connecting to switchboard server", 1 );
    323                 msn_sb_destroy( sb );
     310
     311        if (source != sb->fd) {
     312                debug("Error %d while connecting to switchboard server", 1);
     313                msn_sb_destroy(sb);
    324314                return FALSE;
    325315        }
    326        
     316
    327317        /* Prepare the callback */
    328         sb->handler = g_new0( struct msn_handler_data, 1 );
     318        sb->handler = g_new0(struct msn_handler_data, 1);
    329319        sb->handler->fd = sb->fd;
    330         sb->handler->rxq = g_new0( char, 1 );
     320        sb->handler->rxq = g_new0(char, 1);
    331321        sb->handler->data = sb;
    332322        sb->handler->exec_command = msn_sb_command;
    333323        sb->handler->exec_message = msn_sb_message;
    334        
    335         if( sb->session == MSN_SB_NEW )
    336                 g_snprintf( buf, sizeof( buf ), "USR %d %s;{%s} %s\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key );
    337         else
    338                 g_snprintf( buf, sizeof( buf ), "ANS %d %s;{%s} %s %d\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key, sb->session );
    339        
    340         if( msn_sb_write( sb, "%s", buf ) )
    341                 sb->inp = b_input_add( sb->fd, B_EV_IO_READ, msn_sb_callback, sb );
    342         else
    343                 debug( "Error %d while connecting to switchboard server", 2 );
    344        
     324
     325        if (sb->session == MSN_SB_NEW) {
     326                g_snprintf(buf, sizeof(buf), "USR %d %s;{%s} %s\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key);
     327        } else {
     328                g_snprintf(buf, sizeof(buf), "ANS %d %s;{%s} %s %d\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key,
     329                           sb->session);
     330        }
     331
     332        if (msn_sb_write(sb, "%s", buf)) {
     333                sb->inp = b_input_add(sb->fd, B_EV_IO_READ, msn_sb_callback, sb);
     334        } else {
     335                debug("Error %d while connecting to switchboard server", 2);
     336        }
     337
    345338        return FALSE;
    346339}
    347340
    348 static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond )
     341static gboolean msn_sb_callback(gpointer data, gint source, b_input_condition cond)
    349342{
    350343        struct msn_switchboard *sb = data;
    351344        struct im_connection *ic = sb->ic;
    352345        struct msn_data *md = ic->proto_data;
    353        
    354         if( msn_handler( sb->handler ) != -1 )
     346
     347        if (msn_handler(sb->handler) != -1) {
    355348                return TRUE;
    356        
    357         if( sb->msgq != NULL )
    358         {
    359                 time_t now = time( NULL );
    360                
    361                 if( now - md->first_sb_failure > 600 )
    362                 {
     349        }
     350
     351        if (sb->msgq != NULL) {
     352                time_t now = time(NULL);
     353
     354                if (now - md->first_sb_failure > 600) {
    363355                        /* It's not really the first one, but the start of this "series".
    364356                           With this, the warning below will be shown only if this happens
     
    368360                        md->sb_failures = 0;
    369361                }
    370                
    371                 debug( "Error: Switchboard died" );
    372                 if( ++ md->sb_failures >= 3 )
    373                         imcb_log( ic, "Warning: Many switchboard failures on MSN connection. "
    374                                       "There might be problems delivering your messages." );
    375                
    376                 if( md->msgq == NULL )
    377                 {
     362
     363                debug("Error: Switchboard died");
     364                if (++md->sb_failures >= 3) {
     365                        imcb_log(ic, "Warning: Many switchboard failures on MSN connection. "
     366                                 "There might be problems delivering your messages.");
     367                }
     368
     369                if (md->msgq == NULL) {
    378370                        md->msgq = sb->msgq;
    379                 }
    380                 else
    381                 {
     371                } else {
    382372                        GSList *l;
    383                        
    384                         for( l = md->msgq; l->next; l = l->next );
     373
     374                        for (l = md->msgq; l->next; l = l->next) {
     375                                ;
     376                        }
    385377                        l->next = sb->msgq;
    386378                }
    387379                sb->msgq = NULL;
    388                
    389                 debug( "Moved queued messages back to the main queue, "
    390                        "creating a new switchboard to retry." );
    391                 if( !msn_ns_write( ic, -1, "XFR %d SB\r\n", ++md->trId ) )
     380
     381                debug("Moved queued messages back to the main queue, "
     382                      "creating a new switchboard to retry.");
     383                if (!msn_ns_write(ic, -1, "XFR %d SB\r\n", ++md->trId)) {
    392384                        return FALSE;
    393         }
    394        
    395         msn_sb_destroy( sb );
     385                }
     386        }
     387
     388        msn_sb_destroy(sb);
    396389        return FALSE;
    397390}
    398391
    399 static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts )
     392static int msn_sb_command(struct msn_handler_data *handler, char **cmd, int num_parts)
    400393{
    401394        struct msn_switchboard *sb = handler->data;
    402395        struct im_connection *ic = sb->ic;
    403        
    404         if( !num_parts )
    405         {
     396
     397        if (!num_parts) {
    406398                /* Hrrm... Empty command...? Ignore? */
    407                 return( 1 );
    408         }
    409        
    410         if( strcmp( cmd[0], "XFR" ) == 0 )
    411         {
    412                 imcb_error( ic, "Received an XFR from a switchboard server, unable to comply! This is likely to be a bug, please report it!" );
    413                 imc_logout( ic, TRUE );
    414                 return( 0 );
    415         }
    416         else if( strcmp( cmd[0], "USR" ) == 0 )
    417         {
    418                 if( num_parts < 5 )
    419                 {
    420                         msn_sb_destroy( sb );
    421                         return( 0 );
    422                 }
    423                
    424                 if( strcmp( cmd[2], "OK" ) != 0 )
    425                 {
    426                         msn_sb_destroy( sb );
    427                         return( 0 );
    428                 }
    429                
    430                 if( sb->who )
    431                         return msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, sb->who );
    432                 else
    433                         debug( "Just created a switchboard, but I don't know what to do with it." );
    434         }
    435         else if( strcmp( cmd[0], "IRO" ) == 0 )
    436         {
     399                return(1);
     400        }
     401
     402        if (strcmp(cmd[0], "XFR") == 0) {
     403                imcb_error(ic,
     404                           "Received an XFR from a switchboard server, unable to comply! This is likely to be a bug, please report it!");
     405                imc_logout(ic, TRUE);
     406                return(0);
     407        } else if (strcmp(cmd[0], "USR") == 0) {
     408                if (num_parts < 5) {
     409                        msn_sb_destroy(sb);
     410                        return(0);
     411                }
     412
     413                if (strcmp(cmd[2], "OK") != 0) {
     414                        msn_sb_destroy(sb);
     415                        return(0);
     416                }
     417
     418                if (sb->who) {
     419                        return msn_sb_write(sb, "CAL %d %s\r\n", ++sb->trId, sb->who);
     420                } else {
     421                        debug("Just created a switchboard, but I don't know what to do with it.");
     422                }
     423        } else if (strcmp(cmd[0], "IRO") == 0) {
    437424                int num, tot;
    438                
    439                 if( num_parts < 6 )
    440                 {
    441                         msn_sb_destroy( sb );
    442                         return( 0 );
    443                 }
    444                
    445                 num = atoi( cmd[2] );
    446                 tot = atoi( cmd[3] );
    447                
    448                 if( tot <= 0 )
    449                 {
    450                         msn_sb_destroy( sb );
    451                         return( 0 );
    452                 }
    453                 else if( tot > 1 )
    454                 {
     425
     426                if (num_parts < 6) {
     427                        msn_sb_destroy(sb);
     428                        return(0);
     429                }
     430
     431                num = atoi(cmd[2]);
     432                tot = atoi(cmd[3]);
     433
     434                if (tot <= 0) {
     435                        msn_sb_destroy(sb);
     436                        return(0);
     437                } else if (tot > 1) {
    455438                        char buf[1024];
    456                        
     439
    457440                        /* For as much as I understand this MPOP stuff now, a
    458441                           switchboard has two (or more) roster entries per
    459442                           participant. One "bare JID" and one JID;UUID. Ignore
    460443                           the latter. */
    461                         if( !strchr( cmd[4], ';' ) )
    462                         {
     444                        if (!strchr(cmd[4], ';')) {
    463445                                /* HACK: Since even 1:1 chats now have >2 participants
    464446                                   (ourselves included) it gets hard to tell them apart
    465447                                   from rooms. Let's hope this is enough: */
    466                                 if( sb->chat == NULL && num != tot )
    467                                 {
    468                                         g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
    469                                         sb->chat = imcb_chat_new( ic, buf );
    470                                        
    471                                         g_free( sb->who );
     448                                if (sb->chat == NULL && num != tot) {
     449                                        g_snprintf(buf, sizeof(buf), "MSN groupchat session %d", sb->session);
     450                                        sb->chat = imcb_chat_new(ic, buf);
     451
     452                                        g_free(sb->who);
    472453                                        sb->who = NULL;
    473454                                }
    474                                
    475                                 if( sb->chat )
    476                                         imcb_chat_add_buddy( sb->chat, cmd[4] );
    477                         }
    478                        
     455
     456                                if (sb->chat) {
     457                                        imcb_chat_add_buddy(sb->chat, cmd[4]);
     458                                }
     459                        }
     460
    479461                        /* We have the full roster, start showing the channel to
    480462                           the user. */
    481                         if( num == tot && sb->chat )
    482                         {
    483                                 imcb_chat_add_buddy( sb->chat, ic->acc->user );
    484                         }
    485                 }
    486         }
    487         else if( strcmp( cmd[0], "ANS" ) == 0 )
    488         {
    489                 if( num_parts < 3 )
    490                 {
    491                         msn_sb_destroy( sb );
    492                         return( 0 );
    493                 }
    494                
    495                 if( strcmp( cmd[2], "OK" ) != 0 )
    496                 {
    497                         debug( "Switchboard server sent a negative ANS reply" );
    498                         msn_sb_destroy( sb );
    499                         return( 0 );
    500                 }
    501                
     463                        if (num == tot && sb->chat) {
     464                                imcb_chat_add_buddy(sb->chat, ic->acc->user);
     465                        }
     466                }
     467        } else if (strcmp(cmd[0], "ANS") == 0) {
     468                if (num_parts < 3) {
     469                        msn_sb_destroy(sb);
     470                        return(0);
     471                }
     472
     473                if (strcmp(cmd[2], "OK") != 0) {
     474                        debug("Switchboard server sent a negative ANS reply");
     475                        msn_sb_destroy(sb);
     476                        return(0);
     477                }
     478
    502479                sb->ready = 1;
    503                
    504                 msn_sb_start_keepalives( sb, FALSE );
    505         }
    506         else if( strcmp( cmd[0], "CAL" ) == 0 )
    507         {
    508                 if( num_parts < 4 || !g_ascii_isdigit( cmd[3][0] ) )
    509                 {
    510                         msn_sb_destroy( sb );
    511                         return( 0 );
    512                 }
    513                
    514                 sb->session = atoi( cmd[3] );
    515         }
    516         else if( strcmp( cmd[0], "JOI" ) == 0 )
    517         {
    518                 if( num_parts < 3 )
    519                 {
    520                         msn_sb_destroy( sb );
    521                         return( 0 );
    522                 }
    523                
     480
     481                msn_sb_start_keepalives(sb, FALSE);
     482        } else if (strcmp(cmd[0], "CAL") == 0) {
     483                if (num_parts < 4 || !g_ascii_isdigit(cmd[3][0])) {
     484                        msn_sb_destroy(sb);
     485                        return(0);
     486                }
     487
     488                sb->session = atoi(cmd[3]);
     489        } else if (strcmp(cmd[0], "JOI") == 0) {
     490                if (num_parts < 3) {
     491                        msn_sb_destroy(sb);
     492                        return(0);
     493                }
     494
    524495                /* See IRO above. Handle "bare JIDs" only. */
    525                 if( strchr( cmd[1], ';' ) )
     496                if (strchr(cmd[1], ';')) {
    526497                        return 1;
    527                
    528                 if( sb->who && g_strcasecmp( cmd[1], sb->who ) == 0 )
    529                 {
     498                }
     499
     500                if (sb->who && g_strcasecmp(cmd[1], sb->who) == 0) {
    530501                        /* The user we wanted to talk to is finally there, let's send the queued messages then. */
    531502                        struct msn_message *m;
    532503                        GSList *l;
    533504                        int st = 1;
    534                        
    535                         debug( "%s arrived in the switchboard session, now sending queued message(s)", cmd[1] );
    536                        
     505
     506                        debug("%s arrived in the switchboard session, now sending queued message(s)", cmd[1]);
     507
    537508                        /* Without this, sendmessage() will put everything back on the queue... */
    538509                        sb->ready = 1;
    539                        
    540                         while( ( l = sb->msgq ) )
    541                         {
     510
     511                        while ((l = sb->msgq)) {
    542512                                m = l->data;
    543                                 if( st )
    544                                 {
     513                                if (st) {
    545514                                        /* This hack is meant to convert a regular new chat into a groupchat */
    546                                         if( strcmp( m->text, GROUPCHAT_SWITCHBOARD_MESSAGE ) == 0 )
    547                                                 msn_sb_to_chat( sb );
    548                                         else
    549                                                 st = msn_sb_sendmessage( sb, m->text );
     515                                        if (strcmp(m->text, GROUPCHAT_SWITCHBOARD_MESSAGE) == 0) {
     516                                                msn_sb_to_chat(sb);
     517                                        } else {
     518                                                st = msn_sb_sendmessage(sb, m->text);
     519                                        }
    550520                                }
    551                                 g_free( m->text );
    552                                 g_free( m->who );
    553                                 g_free( m );
    554                                
    555                                 sb->msgq = g_slist_remove( sb->msgq, m );
    556                         }
    557                        
    558                         msn_sb_start_keepalives( sb, FALSE );
    559                        
    560                         return( st );
    561                 }
    562                 else if( strcmp( cmd[1], ic->acc->user ) == 0 )
    563                 {
     521                                g_free(m->text);
     522                                g_free(m->who);
     523                                g_free(m);
     524
     525                                sb->msgq = g_slist_remove(sb->msgq, m);
     526                        }
     527
     528                        msn_sb_start_keepalives(sb, FALSE);
     529
     530                        return(st);
     531                } else if (strcmp(cmd[1], ic->acc->user) == 0) {
    564532                        /* Well, gee thanks. Thanks for letting me know I've arrived.. */
    565                 }
    566                 else if( sb->who )
    567                 {
    568                         debug( "Converting chat with %s to a groupchat because %s joined the session.", sb->who, cmd[1] );
    569                        
     533                } else if (sb->who) {
     534                        debug("Converting chat with %s to a groupchat because %s joined the session.", sb->who, cmd[1]);
     535
    570536                        /* This SB is a one-to-one chat right now, but someone else is joining. */
    571                         msn_sb_to_chat( sb );
    572                        
    573                         imcb_chat_add_buddy( sb->chat, cmd[1] );
    574                 }
    575                 else if( sb->chat )
    576                 {
    577                         imcb_chat_add_buddy( sb->chat, cmd[1] );
     537                        msn_sb_to_chat(sb);
     538
     539                        imcb_chat_add_buddy(sb->chat, cmd[1]);
     540                } else if (sb->chat) {
     541                        imcb_chat_add_buddy(sb->chat, cmd[1]);
    578542                        sb->ready = 1;
    579                 }
    580                 else
    581                 {
     543                } else {
    582544                        /* PANIC! */
    583545                }
    584         }
    585         else if( strcmp( cmd[0], "MSG" ) == 0 )
    586         {
    587                 if( num_parts < 4 )
    588                 {
    589                         msn_sb_destroy( sb );
    590                         return( 0 );
    591                 }
    592                
    593                 sb->handler->msglen = atoi( cmd[3] );
    594                
    595                 if( sb->handler->msglen <= 0 )
    596                 {
    597                         debug( "Received a corrupted message on the switchboard, the switchboard will be closed" );
    598                         msn_sb_destroy( sb );
    599                         return( 0 );
    600                 }
    601         }
    602         else if( strcmp( cmd[0], "NAK" ) == 0 )
    603         {
    604                 if( sb->who )
    605                 {
    606                         imcb_log( ic, "The MSN servers could not deliver one of your messages to %s.", sb->who );
    607                 }
    608                 else
    609                 {
    610                         imcb_log( ic, "The MSN servers could not deliver one of your groupchat messages to all participants." );
    611                 }
    612         }
    613         else if( strcmp( cmd[0], "BYE" ) == 0 )
    614         {
    615                 if( num_parts < 2 )
    616                 {
    617                         msn_sb_destroy( sb );
    618                         return( 0 );
    619                 }
    620                
     546        } else if (strcmp(cmd[0], "MSG") == 0) {
     547                if (num_parts < 4) {
     548                        msn_sb_destroy(sb);
     549                        return(0);
     550                }
     551
     552                sb->handler->msglen = atoi(cmd[3]);
     553
     554                if (sb->handler->msglen <= 0) {
     555                        debug("Received a corrupted message on the switchboard, the switchboard will be closed");
     556                        msn_sb_destroy(sb);
     557                        return(0);
     558                }
     559        } else if (strcmp(cmd[0], "NAK") == 0) {
     560                if (sb->who) {
     561                        imcb_log(ic, "The MSN servers could not deliver one of your messages to %s.", sb->who);
     562                } else {
     563                        imcb_log(ic,
     564                                 "The MSN servers could not deliver one of your groupchat messages to all participants.");
     565                }
     566        } else if (strcmp(cmd[0], "BYE") == 0) {
     567                if (num_parts < 2) {
     568                        msn_sb_destroy(sb);
     569                        return(0);
     570                }
     571
    621572                /* if( cmd[2] && *cmd[2] == '1' ) -=> Chat is being cleaned up because of idleness */
    622                
    623                 if( sb->who )
    624                 {
    625                         msn_sb_stop_keepalives( sb );
    626                        
     573
     574                if (sb->who) {
     575                        msn_sb_stop_keepalives(sb);
     576
    627577                        /* This is a single-person chat, and the other person is leaving. */
    628                         g_free( sb->who );
     578                        g_free(sb->who);
    629579                        sb->who = NULL;
    630580                        sb->ready = 0;
    631                        
    632                         debug( "Person %s left the one-to-one switchboard connection. Keeping it around as a spare...", cmd[1] );
    633                        
     581
     582                        debug("Person %s left the one-to-one switchboard connection. Keeping it around as a spare...",
     583                              cmd[1]);
     584
    634585                        /* We could clean up the switchboard now, but keeping it around
    635586                           as a spare for a next conversation sounds more sane to me.
    636587                           The server will clean it up when it's idle for too long. */
    637                 }
    638                 else if( sb->chat && !strchr( cmd[1], ';' ) )
    639                 {
    640                         imcb_chat_remove_buddy( sb->chat, cmd[1], "" );
    641                 }
    642                 else
    643                 {
     588                } else if (sb->chat && !strchr(cmd[1], ';')) {
     589                        imcb_chat_remove_buddy(sb->chat, cmd[1], "");
     590                } else {
    644591                        /* PANIC! */
    645592                }
    646         }
    647         else if( g_ascii_isdigit( cmd[0][0] ) )
    648         {
    649                 int num = atoi( cmd[0] );
    650                 const struct msn_status_code *err = msn_status_by_number( num );
    651                
     593        } else if (g_ascii_isdigit(cmd[0][0])) {
     594                int num = atoi(cmd[0]);
     595                const struct msn_status_code *err = msn_status_by_number(num);
     596
    652597                /* If the person is offline, send an offline message instead,
    653598                   and don't report an error. */
    654                 if( num == 217 )
    655                         msn_ns_oim_send_queue( ic, &sb->msgq );
    656                 else
    657                         imcb_error( ic, "Error reported by switchboard server: %s", err->text );
    658                
    659                 if( err->flags & STATUS_SB_FATAL )
    660                 {
    661                         msn_sb_destroy( sb );
     599                if (num == 217) {
     600                        msn_ns_oim_send_queue(ic, &sb->msgq);
     601                } else {
     602                        imcb_error(ic, "Error reported by switchboard server: %s", err->text);
     603                }
     604
     605                if (err->flags & STATUS_SB_FATAL) {
     606                        msn_sb_destroy(sb);
    662607                        return 0;
    663                 }
    664                 else if( err->flags & STATUS_FATAL )
    665                 {
    666                         imc_logout( ic, TRUE );
     608                } else if (err->flags & STATUS_FATAL) {
     609                        imc_logout(ic, TRUE);
    667610                        return 0;
    668                 }
    669                 else if( err->flags & STATUS_SB_IM_SPARE )
    670                 {
    671                         if( sb->who )
    672                         {
     611                } else if (err->flags & STATUS_SB_IM_SPARE) {
     612                        if (sb->who) {
    673613                                /* Apparently some invitation failed. We might want to use this
    674614                                   board later, so keep it as a spare. */
    675                                 g_free( sb->who );
     615                                g_free(sb->who);
    676616                                sb->who = NULL;
    677                                
     617
    678618                                /* Also clear the msgq, otherwise someone else might get them. */
    679                                 msn_msgq_purge( ic, &sb->msgq );
    680                         }
    681                        
     619                                msn_msgq_purge(ic, &sb->msgq);
     620                        }
     621
    682622                        /* Do NOT return 0 here, we want to keep this sb. */
    683623                }
    684         }
    685         else
    686         {
     624        } else {
    687625                /* debug( "Received unknown command from switchboard server: %s", cmd[0] ); */
    688626        }
    689        
    690         return( 1 );
    691 }
    692 
    693 static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts )
     627
     628        return(1);
     629}
     630
     631static int msn_sb_message(struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts)
    694632{
    695633        struct msn_switchboard *sb = handler->data;
    696634        struct im_connection *ic = sb->ic;
    697635        char *body;
    698        
    699         if( !num_parts )
    700                 return( 1 );
    701        
    702         if( ( body = strstr( msg, "\r\n\r\n" ) ) )
     636
     637        if (!num_parts) {
     638                return(1);
     639        }
     640
     641        if ((body = strstr(msg, "\r\n\r\n"))) {
    703642                body += 4;
    704        
    705         if( strcmp( cmd[0], "MSG" ) == 0 )
    706         {
    707                 char *ct = get_rfc822_header( msg, "Content-Type:", msglen );
    708                
    709                 if( !ct )
    710                         return( 1 );
    711                
    712                 if( g_strncasecmp( ct, "text/plain", 10 ) == 0 )
    713                 {
    714                         g_free( ct );
    715                        
    716                         if( !body )
    717                                 return( 1 );
    718                        
    719                         if( sb->who )
    720                         {
    721                                 imcb_buddy_msg( ic, cmd[1], body, 0, 0 );
    722                         }
    723                         else if( sb->chat )
    724                         {
    725                                 imcb_chat_msg( sb->chat, cmd[1], body, 0, 0 );
    726                         }
    727                         else
    728                         {
     643        }
     644
     645        if (strcmp(cmd[0], "MSG") == 0) {
     646                char *ct = get_rfc822_header(msg, "Content-Type:", msglen);
     647
     648                if (!ct) {
     649                        return(1);
     650                }
     651
     652                if (g_strncasecmp(ct, "text/plain", 10) == 0) {
     653                        g_free(ct);
     654
     655                        if (!body) {
     656                                return(1);
     657                        }
     658
     659                        if (sb->who) {
     660                                imcb_buddy_msg(ic, cmd[1], body, 0, 0);
     661                        } else if (sb->chat) {
     662                                imcb_chat_msg(sb->chat, cmd[1], body, 0, 0);
     663                        } else {
    729664                                /* PANIC! */
    730665                        }
     
    732667#if 0
    733668                // Disable MSN ft support for now.
    734                 else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 )
    735                 {
    736                         char *command = get_rfc822_header( body, "Invitation-Command:", blen );
    737                         char *cookie = get_rfc822_header( body, "Invitation-Cookie:", blen );
     669                else if (g_strncasecmp(ct, "text/x-msmsgsinvite", 19) == 0) {
     670                        char *command = get_rfc822_header(body, "Invitation-Command:", blen);
     671                        char *cookie = get_rfc822_header(body, "Invitation-Cookie:", blen);
    738672                        unsigned int icookie;
    739                        
    740                         g_free( ct );
    741                        
     673
     674                        g_free(ct);
     675
    742676                        /* Every invite should have both a Command and Cookie header */
    743                         if( !command || !cookie ) {
    744                                 g_free( command );
    745                                 g_free( cookie );
    746                                 imcb_log( ic, "Warning: No command or cookie from %s", sb->who );
     677                        if (!command || !cookie) {
     678                                g_free(command);
     679                                g_free(cookie);
     680                                imcb_log(ic, "Warning: No command or cookie from %s", sb->who);
    747681                                return 1;
    748682                        }
    749                        
    750                         icookie = strtoul( cookie, NULL, 10 );
    751                         g_free( cookie );
    752                        
    753                         if( g_strncasecmp( command, "INVITE", 6 ) == 0 ) {
    754                                 msn_invitation_invite( sb, cmd[1], icookie, body, blen );
    755                         } else if( g_strncasecmp( command, "ACCEPT", 6 ) == 0 ) {
    756                                 msn_invitation_accept( sb, cmd[1], icookie, body, blen );
    757                         } else if( g_strncasecmp( command, "CANCEL", 6 ) == 0 ) {
    758                                 msn_invitation_cancel( sb, cmd[1], icookie, body, blen );
     683
     684                        icookie = strtoul(cookie, NULL, 10);
     685                        g_free(cookie);
     686
     687                        if (g_strncasecmp(command, "INVITE", 6) == 0) {
     688                                msn_invitation_invite(sb, cmd[1], icookie, body, blen);
     689                        } else if (g_strncasecmp(command, "ACCEPT", 6) == 0) {
     690                                msn_invitation_accept(sb, cmd[1], icookie, body, blen);
     691                        } else if (g_strncasecmp(command, "CANCEL", 6) == 0) {
     692                                msn_invitation_cancel(sb, cmd[1], icookie, body, blen);
    759693                        } else {
    760                                 imcb_log( ic, "Warning: Received invalid invitation with "
    761                                                 "command %s from %s", command, sb->who );
    762                         }
    763                        
    764                         g_free( command );
     694                                imcb_log(ic, "Warning: Received invalid invitation with "
     695                                         "command %s from %s", command, sb->who);
     696                        }
     697
     698                        g_free(command);
    765699                }
    766700#endif
    767                 else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 )
    768                 {
     701                else if (g_strncasecmp(ct, "application/x-msnmsgrp2p", 24) == 0) {
    769702                        /* Not currently implemented. Don't warn about it since
    770703                           this seems to be used for avatars now. */
    771                         g_free( ct );
    772                 }
    773                 else if( g_strncasecmp( ct, "text/x-msmsgscontrol", 20 ) == 0 )
    774                 {
    775                         char *who = get_rfc822_header( msg, "TypingUser:", msglen );
    776                        
    777                         if( who )
    778                         {
    779                                 imcb_buddy_typing( ic, who, OPT_TYPING );
    780                                 g_free( who );
    781                         }
    782                        
    783                         g_free( ct );
    784                 }
    785                 else
    786                 {
    787                         g_free( ct );
    788                 }
    789         }
    790        
    791         return( 1 );
    792 }
    793 
    794 static gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond )
     704                        g_free(ct);
     705                } else if (g_strncasecmp(ct, "text/x-msmsgscontrol", 20) == 0) {
     706                        char *who = get_rfc822_header(msg, "TypingUser:", msglen);
     707
     708                        if (who) {
     709                                imcb_buddy_typing(ic, who, OPT_TYPING);
     710                                g_free(who);
     711                        }
     712
     713                        g_free(ct);
     714                } else {
     715                        g_free(ct);
     716                }
     717        }
     718
     719        return(1);
     720}
     721
     722static gboolean msn_sb_keepalive(gpointer data, gint source, b_input_condition cond)
    795723{
    796724        struct msn_switchboard *sb = data;
    797         return sb->ready && msn_sb_sendmessage( sb, SB_KEEPALIVE_MESSAGE );
    798 }
    799 
    800 void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial )
     725
     726        return sb->ready && msn_sb_sendmessage(sb, SB_KEEPALIVE_MESSAGE);
     727}
     728
     729void msn_sb_start_keepalives(struct msn_switchboard *sb, gboolean initial)
    801730{
    802731        bee_user_t *bu;
    803        
    804         if( sb && sb->who && sb->keepalive == 0 &&
    805             ( bu = bee_user_by_handle( sb->ic->bee, sb->ic, sb->who ) ) &&
    806             !( bu->flags & BEE_USER_ONLINE ) &&
    807             set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) )
    808         {
    809                 if( initial )
    810                         msn_sb_keepalive( sb, 0, 0 );
    811                
    812                 sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb );
    813         }
    814 }
    815 
    816 void msn_sb_stop_keepalives( struct msn_switchboard *sb )
    817 {
    818         if( sb && sb->keepalive > 0 )
    819         {
    820                 b_event_remove( sb->keepalive );
     732
     733        if (sb && sb->who && sb->keepalive == 0 &&
     734            (bu = bee_user_by_handle(sb->ic->bee, sb->ic, sb->who)) &&
     735            !(bu->flags & BEE_USER_ONLINE) &&
     736            set_getbool(&sb->ic->acc->set, "switchboard_keepalives")) {
     737                if (initial) {
     738                        msn_sb_keepalive(sb, 0, 0);
     739                }
     740
     741                sb->keepalive = b_timeout_add(20000, msn_sb_keepalive, sb);
     742        }
     743}
     744
     745void msn_sb_stop_keepalives(struct msn_switchboard *sb)
     746{
     747        if (sb && sb->keepalive > 0) {
     748                b_event_remove(sb->keepalive);
    821749                sb->keepalive = 0;
    822750        }
Note: See TracChangeset for help on using the changeset viewer.