Changeset 5ebff60 for protocols/jabber


Ignore:
Timestamp:
2015-02-20T22:50:54Z (10 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.

Location:
protocols/jabber
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/conference.c

    raf359b4 r5ebff60  
    2525#include "sha1.h"
    2626
    27 static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    28 
    29 struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password )
     27static xt_status jabber_chat_join_failed(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     28
     29struct groupchat *jabber_chat_join(struct im_connection *ic, const char *room, const char *nick, const char *password)
    3030{
    3131        struct jabber_chat *jc;
     
    3333        struct groupchat *c;
    3434        char *roomjid;
    35        
    36         roomjid = g_strdup_printf( "%s/%s", room, nick );
    37         node = xt_new_node( "x", NULL, NULL );
    38         xt_add_attr( node, "xmlns", XMLNS_MUC );
    39         if( password )
    40                 xt_add_child( node, xt_new_node( "password", password, NULL ) );
    41         node = jabber_make_packet( "presence", NULL, roomjid, node );
    42         jabber_cache_add( ic, node, jabber_chat_join_failed );
    43        
    44         if( !jabber_write_packet( ic, node ) )
    45         {
    46                 g_free( roomjid );
     35
     36        roomjid = g_strdup_printf("%s/%s", room, nick);
     37        node = xt_new_node("x", NULL, NULL);
     38        xt_add_attr(node, "xmlns", XMLNS_MUC);
     39        if (password) {
     40                xt_add_child(node, xt_new_node("password", password, NULL));
     41        }
     42        node = jabber_make_packet("presence", NULL, roomjid, node);
     43        jabber_cache_add(ic, node, jabber_chat_join_failed);
     44
     45        if (!jabber_write_packet(ic, node)) {
     46                g_free(roomjid);
    4747                return NULL;
    4848        }
    49        
    50         jc = g_new0( struct jabber_chat, 1 );
    51         jc->name = jabber_normalize( room );
    52        
    53         if( ( jc->me = jabber_buddy_add( ic, roomjid ) ) == NULL )
    54         {
    55                 g_free( roomjid );
    56                 g_free( jc->name );
    57                 g_free( jc );
     49
     50        jc = g_new0(struct jabber_chat, 1);
     51        jc->name = jabber_normalize(room);
     52
     53        if ((jc->me = jabber_buddy_add(ic, roomjid)) == NULL) {
     54                g_free(roomjid);
     55                g_free(jc->name);
     56                g_free(jc);
    5857                return NULL;
    5958        }
    60        
     59
    6160        /* roomjid isn't normalized yet, and we need an original version
    6261           of the nick to send a proper presence update. */
    6362        jc->my_full_jid = roomjid;
    64        
    65         c = imcb_chat_new( ic, room );
     63
     64        c = imcb_chat_new(ic, room);
    6665        c->data = jc;
    67        
     66
    6867        return c;
    6968}
    7069
    71 struct groupchat *jabber_chat_with( struct im_connection *ic, char *who )
     70struct groupchat *jabber_chat_with(struct im_connection *ic, char *who)
    7271{
    7372        struct jabber_data *jd = ic->proto_data;
     
    7776        double now = gettime();
    7877        char *uuid, *rjid, *cserv;
    79        
    80         sha1_init( &sum );
    81         sha1_append( &sum, (uint8_t*) ic->acc->user, strlen( ic->acc->user ) );
    82         sha1_append( &sum, (uint8_t*) &now, sizeof( now ) );
    83         sha1_append( &sum, (uint8_t*) who, strlen( who ) );
    84         uuid = sha1_random_uuid( &sum );
    85        
    86         if( jd->flags & JFLAG_GTALK )
    87                 cserv = g_strdup( "groupchat.google.com" );
    88         else
     78
     79        sha1_init(&sum);
     80        sha1_append(&sum, (uint8_t *) ic->acc->user, strlen(ic->acc->user));
     81        sha1_append(&sum, (uint8_t *) &now, sizeof(now));
     82        sha1_append(&sum, (uint8_t *) who, strlen(who));
     83        uuid = sha1_random_uuid(&sum);
     84
     85        if (jd->flags & JFLAG_GTALK) {
     86                cserv = g_strdup("groupchat.google.com");
     87        } else {
    8988                /* Guess... */
    90                 cserv = g_strdup_printf( "conference.%s", jd->server );
    91        
    92         rjid = g_strdup_printf( "private-chat-%s@%s", uuid, cserv );
    93         g_free( uuid );
    94         g_free( cserv );
    95        
    96         c = jabber_chat_join( ic, rjid, jd->username, NULL );
    97         g_free( rjid );
    98         if( c == NULL )
     89                cserv = g_strdup_printf("conference.%s", jd->server);
     90        }
     91
     92        rjid = g_strdup_printf("private-chat-%s@%s", uuid, cserv);
     93        g_free(uuid);
     94        g_free(cserv);
     95
     96        c = jabber_chat_join(ic, rjid, jd->username, NULL);
     97        g_free(rjid);
     98        if (c == NULL) {
    9999                return NULL;
    100        
     100        }
     101
    101102        jc = c->data;
    102         jc->invite = g_strdup( who );
    103        
     103        jc->invite = g_strdup(who);
     104
    104105        return c;
    105106}
    106107
    107 static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     108static xt_status jabber_chat_join_failed(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    108109{
    109110        struct jabber_error *err;
    110111        struct jabber_buddy *bud;
    111112        char *room;
    112        
    113         room = xt_find_attr( orig, "to" );
    114         bud = jabber_buddy_by_jid( ic, room, 0 );
    115         err = jabber_error_parse( xt_find_node( node->children, "error" ), XMLNS_STANZA_ERROR );
    116         if( err )
    117         {
    118                 imcb_error( ic, "Error joining groupchat %s: %s%s%s", room, err->code,
    119                             err->text ? ": " : "", err->text ? err->text : "" );
    120                 jabber_error_free( err );
    121         }
    122         if( bud )
    123                 jabber_chat_free( jabber_chat_by_jid( ic, bud->bare_jid ) );
    124        
     113
     114        room = xt_find_attr(orig, "to");
     115        bud = jabber_buddy_by_jid(ic, room, 0);
     116        err = jabber_error_parse(xt_find_node(node->children, "error"), XMLNS_STANZA_ERROR);
     117        if (err) {
     118                imcb_error(ic, "Error joining groupchat %s: %s%s%s", room, err->code,
     119                           err->text ? ": " : "", err->text ? err->text : "");
     120                jabber_error_free(err);
     121        }
     122        if (bud) {
     123                jabber_chat_free(jabber_chat_by_jid(ic, bud->bare_jid));
     124        }
     125
    125126        return XT_HANDLED;
    126127}
    127128
    128 struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name )
    129 {
    130         char *normalized = jabber_normalize( name );
     129struct groupchat *jabber_chat_by_jid(struct im_connection *ic, const char *name)
     130{
     131        char *normalized = jabber_normalize(name);
    131132        GSList *l;
    132133        struct groupchat *ret;
    133134        struct jabber_chat *jc;
    134        
    135         for( l = ic->groupchats; l; l = l->next )
    136         {
     135
     136        for (l = ic->groupchats; l; l = l->next) {
    137137                ret = l->data;
    138138                jc = ret->data;
    139                 if( strcmp( normalized, jc->name ) == 0 )
     139                if (strcmp(normalized, jc->name) == 0) {
    140140                        break;
    141         }
    142         g_free( normalized );
    143        
     141                }
     142        }
     143        g_free(normalized);
     144
    144145        return l ? ret : NULL;
    145146}
    146147
    147 void jabber_chat_free( struct groupchat *c )
     148void jabber_chat_free(struct groupchat *c)
    148149{
    149150        struct jabber_chat *jc = c->data;
    150        
    151         jabber_buddy_remove_bare( c->ic, jc->name );
    152        
    153         g_free( jc->my_full_jid );
    154         g_free( jc->name );
    155         g_free( jc->invite );
    156         g_free( jc );
    157        
    158         imcb_chat_free( c );
    159 }
    160 
    161 int jabber_chat_msg( struct groupchat *c, char *message, int flags )
     151
     152        jabber_buddy_remove_bare(c->ic, jc->name);
     153
     154        g_free(jc->my_full_jid);
     155        g_free(jc->name);
     156        g_free(jc->invite);
     157        g_free(jc);
     158
     159        imcb_chat_free(c);
     160}
     161
     162int jabber_chat_msg(struct groupchat *c, char *message, int flags)
    162163{
    163164        struct im_connection *ic = c->ic;
    164165        struct jabber_chat *jc = c->data;
    165166        struct xt_node *node;
    166        
     167
    167168        jc->flags |= JCFLAG_MESSAGE_SENT;
    168        
    169         node = xt_new_node( "body", message, NULL );
    170         node = jabber_make_packet( "message", "groupchat", jc->name, node );
    171        
    172         if( !jabber_write_packet( ic, node ) )
    173         {
    174                 xt_free_node( node );
     169
     170        node = xt_new_node("body", message, NULL);
     171        node = jabber_make_packet("message", "groupchat", jc->name, node);
     172
     173        if (!jabber_write_packet(ic, node)) {
     174                xt_free_node(node);
    175175                return 0;
    176176        }
    177         xt_free_node( node );
    178        
     177        xt_free_node(node);
     178
    179179        return 1;
    180180}
    181181
    182 int jabber_chat_topic( struct groupchat *c, char *topic )
     182int jabber_chat_topic(struct groupchat *c, char *topic)
    183183{
    184184        struct im_connection *ic = c->ic;
    185185        struct jabber_chat *jc = c->data;
    186186        struct xt_node *node;
    187        
    188         node = xt_new_node( "subject", topic, NULL );
    189         node = jabber_make_packet( "message", "groupchat", jc->name, node );
    190        
    191         if( !jabber_write_packet( ic, node ) )
    192         {
    193                 xt_free_node( node );
     187
     188        node = xt_new_node("subject", topic, NULL);
     189        node = jabber_make_packet("message", "groupchat", jc->name, node);
     190
     191        if (!jabber_write_packet(ic, node)) {
     192                xt_free_node(node);
    194193                return 0;
    195194        }
    196         xt_free_node( node );
    197        
     195        xt_free_node(node);
     196
    198197        return 1;
    199198}
    200199
    201 int jabber_chat_leave( struct groupchat *c, const char *reason )
     200int jabber_chat_leave(struct groupchat *c, const char *reason)
    202201{
    203202        struct im_connection *ic = c->ic;
    204203        struct jabber_chat *jc = c->data;
    205204        struct xt_node *node;
    206        
    207         node = xt_new_node( "x", NULL, NULL );
    208         xt_add_attr( node, "xmlns", XMLNS_MUC );
    209         node = jabber_make_packet( "presence", "unavailable", jc->my_full_jid, node );
    210        
    211         if( !jabber_write_packet( ic, node ) )
    212         {
    213                 xt_free_node( node );
     205
     206        node = xt_new_node("x", NULL, NULL);
     207        xt_add_attr(node, "xmlns", XMLNS_MUC);
     208        node = jabber_make_packet("presence", "unavailable", jc->my_full_jid, node);
     209
     210        if (!jabber_write_packet(ic, node)) {
     211                xt_free_node(node);
    214212                return 0;
    215213        }
    216         xt_free_node( node );
    217        
     214        xt_free_node(node);
     215
    218216        return 1;
    219217}
    220218
    221 void jabber_chat_invite( struct groupchat *c, char *who, char *message )
     219void jabber_chat_invite(struct groupchat *c, char *who, char *message)
    222220{
    223221        struct xt_node *node;
     
    225223        struct jabber_chat *jc = c->data;
    226224
    227         node = xt_new_node( "reason", message, NULL );
    228 
    229         node = xt_new_node( "invite", NULL, node );
    230         xt_add_attr( node, "to", who );
    231 
    232         node = xt_new_node( "x", NULL, node );
    233         xt_add_attr( node, "xmlns", XMLNS_MUC_USER );
    234        
    235         node = jabber_make_packet( "message", NULL, jc->name, node );
    236 
    237         jabber_write_packet( ic, node );
    238 
    239         xt_free_node( node );
     225        node = xt_new_node("reason", message, NULL);
     226
     227        node = xt_new_node("invite", NULL, node);
     228        xt_add_attr(node, "to", who);
     229
     230        node = xt_new_node("x", NULL, node);
     231        xt_add_attr(node, "xmlns", XMLNS_MUC_USER);
     232
     233        node = jabber_make_packet("message", NULL, jc->name, node);
     234
     235        jabber_write_packet(ic, node);
     236
     237        xt_free_node(node);
    240238}
    241239
     
    244242   parameters so we won't have to repeat too many things done by the caller
    245243   already. */
    246 void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node )
     244void jabber_chat_pkt_presence(struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node)
    247245{
    248246        struct groupchat *chat;
    249247        struct xt_node *c;
    250         char *type = xt_find_attr( node, "type" );
     248        char *type = xt_find_attr(node, "type");
    251249        struct jabber_data *jd = ic->proto_data;
    252250        struct jabber_chat *jc;
    253251        char *s;
    254        
    255         if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) ) == NULL )
    256         {
     252
     253        if ((chat = jabber_chat_by_jid(ic, bud->bare_jid)) == NULL) {
    257254                /* How could this happen?? We could do kill( self, 11 )
    258255                   now or just wait for the OS to do it. :-) */
    259256                return;
    260257        }
    261        
     258
    262259        jc = chat->data;
    263        
    264         if( type == NULL && !( bud->flags & JBFLAG_IS_CHATROOM ) )
    265         {
     260
     261        if (type == NULL && !(bud->flags & JBFLAG_IS_CHATROOM)) {
    266262                bud->flags |= JBFLAG_IS_CHATROOM;
    267263                /* If this one wasn't set yet, this buddy just joined the chat.
    268264                   Slightly hackish way of finding out eh? ;-) */
    269                
     265
    270266                /* This is pretty messy... Here it sets ext_jid to the real
    271267                   JID of the participant. Works for non-anonymized channels.
    272268                   Might break if someone joins a chat twice, though. */
    273                 for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
    274                         if( ( s = xt_find_attr( c, "xmlns" ) ) &&
    275                             ( strcmp( s, XMLNS_MUC_USER ) == 0 ) )
    276                         {
     269                for (c = node->children; (c = xt_find_node(c, "x")); c = c->next) {
     270                        if ((s = xt_find_attr(c, "xmlns")) &&
     271                            (strcmp(s, XMLNS_MUC_USER) == 0)) {
    277272                                struct xt_node *item;
    278                                
    279                                 item = xt_find_node( c->children, "item" );
    280                                 if( ( s = xt_find_attr( item, "jid" ) ) )
    281                                 {
     273
     274                                item = xt_find_node(c->children, "item");
     275                                if ((s = xt_find_attr(item, "jid"))) {
    282276                                        /* Yay, found what we need. :-) */
    283                                         bud->ext_jid = jabber_normalize( s );
     277                                        bud->ext_jid = jabber_normalize(s);
    284278                                        break;
    285279                                }
    286280                        }
    287                
     281                }
     282
    288283                /* Make up some other handle, if necessary. */
    289                 if( bud->ext_jid == NULL )
    290                 {
    291                         if( bud == jc->me )
    292                         {
    293                                 bud->ext_jid = g_strdup( jd->me );
    294                         }
    295                         else
    296                         {
     284                if (bud->ext_jid == NULL) {
     285                        if (bud == jc->me) {
     286                                bud->ext_jid = g_strdup(jd->me);
     287                        } else {
    297288                                int i;
    298                                
     289
    299290                                /* Don't want the nick to be at the end, so let's
    300291                                   think of some slightly different notation to use
    301292                                   for anonymous groupchat participants in BitlBee. */
    302                                 bud->ext_jid = g_strdup_printf( "%s=%s", bud->resource, bud->bare_jid );
    303                                
     293                                bud->ext_jid = g_strdup_printf("%s=%s", bud->resource, bud->bare_jid);
     294
    304295                                /* And strip any unwanted characters. */
    305                                 for( i = 0; bud->resource[i]; i ++ )
    306                                         if( bud->ext_jid[i] == '=' || bud->ext_jid[i] == '@' )
     296                                for (i = 0; bud->resource[i]; i++) {
     297                                        if (bud->ext_jid[i] == '=' || bud->ext_jid[i] == '@') {
    307298                                                bud->ext_jid[i] = '_';
    308                                
     299                                        }
     300                                }
     301
    309302                                /* Some program-specific restrictions. */
    310                                 imcb_clean_handle( ic, bud->ext_jid );
     303                                imcb_clean_handle(ic, bud->ext_jid);
    311304                        }
    312305                        bud->flags |= JBFLAG_IS_ANONYMOUS;
    313306                }
    314                
    315                 if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS )
    316                 {
     307
     308                if (bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS) {
    317309                        /* If JIDs are anonymized, add them to the local
    318310                           list for the duration of this chat. */
    319                         imcb_add_buddy( ic, bud->ext_jid, NULL );
    320                         imcb_buddy_nick_hint( ic, bud->ext_jid, bud->resource );
    321                 }
    322                
    323                 if( bud == jc->me && jc->invite != NULL )
    324                 {
    325                         char *msg = g_strdup_printf( "Please join me in room %s", jc->name );
    326                         jabber_chat_invite( chat, jc->invite, msg );
    327                         g_free( jc->invite );
    328                         g_free( msg );
     311                        imcb_add_buddy(ic, bud->ext_jid, NULL);
     312                        imcb_buddy_nick_hint(ic, bud->ext_jid, bud->resource);
     313                }
     314
     315                if (bud == jc->me && jc->invite != NULL) {
     316                        char *msg = g_strdup_printf("Please join me in room %s", jc->name);
     317                        jabber_chat_invite(chat, jc->invite, msg);
     318                        g_free(jc->invite);
     319                        g_free(msg);
    329320                        jc->invite = NULL;
    330321                }
    331                
    332                 s = strchr( bud->ext_jid, '/' );
    333                 if( s ) *s = 0; /* Should NEVER be NULL, but who knows... */
    334                 imcb_chat_add_buddy( chat, bud->ext_jid );
    335                 if( s ) *s = '/';
    336         }
    337         else if( type ) /* type can only be NULL or "unavailable" in this function */
    338         {
    339                 if( ( bud->flags & JBFLAG_IS_CHATROOM ) && bud->ext_jid )
    340                 {
    341                         s = strchr( bud->ext_jid, '/' );
    342                         if( s ) *s = 0;
    343                         imcb_chat_remove_buddy( chat, bud->ext_jid, NULL );
    344                         if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS )
    345                                 imcb_remove_buddy( ic, bud->ext_jid, NULL );
    346                         if( s ) *s = '/';
    347                 }
    348                
    349                 if( bud == jc->me )
    350                         jabber_chat_free( chat );
    351         }
    352 }
    353 
    354 void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node )
    355 {
    356         struct xt_node *subject = xt_find_node( node->children, "subject" );
    357         struct xt_node *body = xt_find_node( node->children, "body" );
    358         struct groupchat *chat = bud ? jabber_chat_by_jid( ic, bud->bare_jid ) : NULL;
     322
     323                s = strchr(bud->ext_jid, '/');
     324                if (s) {
     325                        *s = 0; /* Should NEVER be NULL, but who knows... */
     326                }
     327                imcb_chat_add_buddy(chat, bud->ext_jid);
     328                if (s) {
     329                        *s = '/';
     330                }
     331        } else if (type) { /* type can only be NULL or "unavailable" in this function */
     332                if ((bud->flags & JBFLAG_IS_CHATROOM) && bud->ext_jid) {
     333                        s = strchr(bud->ext_jid, '/');
     334                        if (s) {
     335                                *s = 0;
     336                        }
     337                        imcb_chat_remove_buddy(chat, bud->ext_jid, NULL);
     338                        if (bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS) {
     339                                imcb_remove_buddy(ic, bud->ext_jid, NULL);
     340                        }
     341                        if (s) {
     342                                *s = '/';
     343                        }
     344                }
     345
     346                if (bud == jc->me) {
     347                        jabber_chat_free(chat);
     348                }
     349        }
     350}
     351
     352void jabber_chat_pkt_message(struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node)
     353{
     354        struct xt_node *subject = xt_find_node(node->children, "subject");
     355        struct xt_node *body = xt_find_node(node->children, "body");
     356        struct groupchat *chat = bud ? jabber_chat_by_jid(ic, bud->bare_jid) : NULL;
    359357        struct jabber_chat *jc = chat ? chat->data : NULL;
    360358        char *s;
    361        
    362         if( subject && chat )
    363         {
    364                 s = bud ? strchr( bud->ext_jid, '/' ) : NULL;
    365                 if( s ) *s = 0;
    366                 imcb_chat_topic( chat, bud ? bud->ext_jid : NULL, subject->text_len > 0 ?
    367                                  subject->text : NULL, jabber_get_timestamp( node ) );
    368                 if( s ) *s = '/';
    369         }
    370        
    371         if( bud == NULL || ( jc && ~jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me ) )
    372         {
     359
     360        if (subject && chat) {
     361                s = bud ? strchr(bud->ext_jid, '/') : NULL;
     362                if (s) {
     363                        *s = 0;
     364                }
     365                imcb_chat_topic(chat, bud ? bud->ext_jid : NULL, subject->text_len > 0 ?
     366                                subject->text : NULL, jabber_get_timestamp(node));
     367                if (s) {
     368                        *s = '/';
     369                }
     370        }
     371
     372        if (bud == NULL || (jc && ~jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me)) {
    373373                char *nick;
    374                
    375                 if( body == NULL || body->text_len == 0 )
     374
     375                if (body == NULL || body->text_len == 0) {
    376376                        /* Meh. Empty messages aren't very interesting, no matter
    377377                           how much some servers love to send them. */
    378378                        return;
    379                
    380                 s = xt_find_attr( node, "from" ); /* pkt_message() already NULL-checked this one. */
    381                 nick = strchr( s, '/' );
    382                 if( nick )
    383                 {
     379                }
     380
     381                s = xt_find_attr(node, "from");   /* pkt_message() already NULL-checked this one. */
     382                nick = strchr(s, '/');
     383                if (nick) {
    384384                        /* If this message included a resource/nick we don't know,
    385385                           we might still know the groupchat itself. */
    386386                        *nick = 0;
    387                         chat = jabber_chat_by_jid( ic, s );
     387                        chat = jabber_chat_by_jid(ic, s);
    388388                        *nick = '/';
    389                        
    390                         nick ++;
    391                 }
    392                 else
    393                 {
     389
     390                        nick++;
     391                } else {
    394392                        /* message.c uses the EXACT_JID option, so bud should
    395393                           always be NULL here for bare JIDs. */
    396                         chat = jabber_chat_by_jid( ic, s );
    397                 }
    398                
    399                 if( nick == NULL )
    400                 {
     394                        chat = jabber_chat_by_jid(ic, s);
     395                }
     396
     397                if (nick == NULL) {
    401398                        /* This is fine, the groupchat itself isn't in jd->buddies. */
    402                         if( chat )
    403                                 imcb_chat_log( chat, "From conference server: %s", body->text );
    404                         else
    405                                 imcb_log( ic, "System message from unknown groupchat %s: %s", s, body->text );
    406                 }
    407                 else
    408                 {
     399                        if (chat) {
     400                                imcb_chat_log(chat, "From conference server: %s", body->text);
     401                        } else {
     402                                imcb_log(ic, "System message from unknown groupchat %s: %s", s, body->text);
     403                        }
     404                } else {
    409405                        /* This can happen too, at least when receiving a backlog when
    410406                           just joining a channel. */
    411                         if( chat )
    412                                 imcb_chat_log( chat, "Message from unknown participant %s: %s", nick, body->text );
    413                         else
    414                                 imcb_log( ic, "Groupchat message from unknown JID %s: %s", s, body->text );
    415                 }
    416                
     407                        if (chat) {
     408                                imcb_chat_log(chat, "Message from unknown participant %s: %s", nick, body->text);
     409                        } else {
     410                                imcb_log(ic, "Groupchat message from unknown JID %s: %s", s, body->text);
     411                        }
     412                }
     413
    417414                return;
    418         }
    419         else if( chat == NULL )
    420         {
     415        } else if (chat == NULL) {
    421416                /* How could this happen?? We could do kill( self, 11 )
    422417                   now or just wait for the OS to do it. :-) */
    423418                return;
    424419        }
    425         if( body && body->text_len > 0 )
    426         {
    427                 s = strchr( bud->ext_jid, '/' );
    428                 if( s ) *s = 0;
    429                 imcb_chat_msg( chat, bud->ext_jid, body->text, 0, jabber_get_timestamp( node ) );
    430                 if( s ) *s = '/';
    431         }
    432 }
     420        if (body && body->text_len > 0) {
     421                s = strchr(bud->ext_jid, '/');
     422                if (s) {
     423                        *s = 0;
     424                }
     425                imcb_chat_msg(chat, bud->ext_jid, body->text, 0, jabber_get_timestamp(node));
     426                if (s) {
     427                        *s = '/';
     428                }
     429        }
     430}
  • protocols/jabber/io.c

    raf359b4 r5ebff60  
    2525#include "ssl_client.h"
    2626
    27 static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond );
    28 static gboolean jabber_write_queue( struct im_connection *ic );
    29 
    30 int jabber_write_packet( struct im_connection *ic, struct xt_node *node )
     27static gboolean jabber_write_callback(gpointer data, gint fd, b_input_condition cond);
     28static gboolean jabber_write_queue(struct im_connection *ic);
     29
     30int jabber_write_packet(struct im_connection *ic, struct xt_node *node)
    3131{
    3232        char *buf;
    3333        int st;
    34        
    35         buf = xt_to_string( node );
    36         st = jabber_write( ic, buf, strlen( buf ) );
    37         g_free( buf );
    38        
     34
     35        buf = xt_to_string(node);
     36        st = jabber_write(ic, buf, strlen(buf));
     37        g_free(buf);
     38
    3939        return st;
    4040}
    4141
    42 int jabber_write( struct im_connection *ic, char *buf, int len )
     42int jabber_write(struct im_connection *ic, char *buf, int len)
    4343{
    4444        struct jabber_data *jd = ic->proto_data;
    4545        gboolean ret;
    46        
    47         if( jd->flags & JFLAG_XMLCONSOLE && !( ic->flags & OPT_LOGGING_OUT ) )
    48         {
     46
     47        if (jd->flags & JFLAG_XMLCONSOLE && !(ic->flags & OPT_LOGGING_OUT)) {
    4948                char *msg, *s;
    50                
    51                 msg = g_strdup_printf( "TX: %s", buf );
     49
     50                msg = g_strdup_printf("TX: %s", buf);
    5251                /* Don't include auth info in XML logs. */
    53                 if( strncmp( msg, "TX: <auth ", 10 ) == 0 && ( s = strchr( msg, '>' ) ) )
    54                 {
     52                if (strncmp(msg, "TX: <auth ", 10) == 0 && (s = strchr(msg, '>'))) {
    5553                        s++;
    56                         while( *s && *s != '<' )
     54                        while (*s && *s != '<') {
    5755                                *(s++) = '*';
    58                 }
    59                 imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 );
    60                 g_free( msg );
    61         }
    62        
    63         if( jd->tx_len == 0 )
    64         {
     56                        }
     57                }
     58                imcb_buddy_msg(ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0);
     59                g_free(msg);
     60        }
     61
     62        if (jd->tx_len == 0) {
    6563                /* If the queue is empty, allocate a new buffer. */
    6664                jd->tx_len = len;
    67                 jd->txq = g_memdup( buf, len );
    68                
     65                jd->txq = g_memdup(buf, len);
     66
    6967                /* Try if we can write it immediately so we don't have to do
    7068                   it via the event handler. If not, add the handler. (In
    7169                   most cases it probably won't be necessary.) */
    72                 if( ( ret = jabber_write_queue( ic ) ) && jd->tx_len > 0 )
    73                         jd->w_inpa = b_input_add( jd->fd, B_EV_IO_WRITE, jabber_write_callback, ic );
    74         }
    75         else
    76         {
     70                if ((ret = jabber_write_queue(ic)) && jd->tx_len > 0) {
     71                        jd->w_inpa = b_input_add(jd->fd, B_EV_IO_WRITE, jabber_write_callback, ic);
     72                }
     73        } else {
    7774                /* Just add it to the buffer if it's already filled. The
    7875                   event handler is already set. */
    79                 jd->txq = g_renew( char, jd->txq, jd->tx_len + len );
    80                 memcpy( jd->txq + jd->tx_len, buf, len );
     76                jd->txq = g_renew(char, jd->txq, jd->tx_len + len);
     77                memcpy(jd->txq + jd->tx_len, buf, len);
    8178                jd->tx_len += len;
    82                
     79
    8380                /* The return value for write() doesn't necessarily mean
    8481                   that everything got sent, it mainly means that the
     
    8784                ret = TRUE;
    8885        }
    89        
     86
    9087        return ret;
    9188}
     
    9491   to use in the function above to escape from having to wait for the event
    9592   handler to call us, if possible.
    96    
     93
    9794   Two different functions are necessary because of the return values: The
    9895   callback should only return TRUE if the write was successful AND if the
    9996   buffer is not empty yet (ie. if the handler has to be called again when
    10097   the socket is ready for more data). */
    101 static gboolean jabber_write_callback( gpointer data, gint fd, b_input_condition cond )
    102 {
    103         struct jabber_data *jd = ((struct im_connection *)data)->proto_data;
    104        
     98static gboolean jabber_write_callback(gpointer data, gint fd, b_input_condition cond)
     99{
     100        struct jabber_data *jd = ((struct im_connection *) data)->proto_data;
     101
    105102        return jd->fd != -1 &&
    106                jabber_write_queue( data ) &&
     103               jabber_write_queue(data) &&
    107104               jd->tx_len > 0;
    108105}
    109106
    110 static gboolean jabber_write_queue( struct im_connection *ic )
     107static gboolean jabber_write_queue(struct im_connection *ic)
    111108{
    112109        struct jabber_data *jd = ic->proto_data;
    113110        int st;
    114        
    115         if( jd->ssl )
    116                 st = ssl_write( jd->ssl, jd->txq, jd->tx_len );
    117         else
    118                 st = write( jd->fd, jd->txq, jd->tx_len );
    119        
    120         if( st == jd->tx_len )
    121         {
     111
     112        if (jd->ssl) {
     113                st = ssl_write(jd->ssl, jd->txq, jd->tx_len);
     114        } else {
     115                st = write(jd->fd, jd->txq, jd->tx_len);
     116        }
     117
     118        if (st == jd->tx_len) {
    122119                /* We wrote everything, clear the buffer. */
    123                 g_free( jd->txq );
     120                g_free(jd->txq);
    124121                jd->txq = NULL;
    125122                jd->tx_len = 0;
    126                
     123
    127124                return TRUE;
    128         }
    129         else if( st == 0 || ( st < 0 && !ssl_sockerr_again( jd->ssl ) ) )
    130         {
     125        } else if (st == 0 || (st < 0 && !ssl_sockerr_again(jd->ssl))) {
    131126                /* Set fd to -1 to make sure we won't write to it anymore. */
    132                 closesocket( jd->fd );  /* Shouldn't be necessary after errors? */
     127                closesocket(jd->fd);    /* Shouldn't be necessary after errors? */
    133128                jd->fd = -1;
    134                
    135                 imcb_error( ic, "Short write() to server" );
    136                 imc_logout( ic, TRUE );
    137                 return FALSE;
    138         }
    139         else if( st > 0 )
    140         {
     129
     130                imcb_error(ic, "Short write() to server");
     131                imc_logout(ic, TRUE);
     132                return FALSE;
     133        } else if (st > 0) {
    141134                char *s;
    142                
    143                 s = g_memdup( jd->txq + st, jd->tx_len - st );
     135
     136                s = g_memdup(jd->txq + st, jd->tx_len - st);
    144137                jd->tx_len -= st;
    145                 g_free( jd->txq );
     138                g_free(jd->txq);
    146139                jd->txq = s;
    147                
     140
    148141                return TRUE;
    149         }
    150         else
    151         {
     142        } else {
    152143                /* Just in case we had EINPROGRESS/EAGAIN: */
    153                
     144
    154145                return TRUE;
    155146        }
    156147}
    157148
    158 static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition cond )
     149static gboolean jabber_read_callback(gpointer data, gint fd, b_input_condition cond)
    159150{
    160151        struct im_connection *ic = data;
     
    162153        char buf[512];
    163154        int st;
    164        
    165         if( jd->fd == -1 )
    166                 return FALSE;
    167        
    168         if( jd->ssl )
    169                 st = ssl_read( jd->ssl, buf, sizeof( buf ) );
    170         else
    171                 st = read( jd->fd, buf, sizeof( buf ) );
    172        
    173         if( st > 0 )
    174         {
     155
     156        if (jd->fd == -1) {
     157                return FALSE;
     158        }
     159
     160        if (jd->ssl) {
     161                st = ssl_read(jd->ssl, buf, sizeof(buf));
     162        } else {
     163                st = read(jd->fd, buf, sizeof(buf));
     164        }
     165
     166        if (st > 0) {
    175167                /* Parse. */
    176                 if( xt_feed( jd->xt, buf, st ) < 0 )
    177                 {
    178                         imcb_error( ic, "XML stream error" );
    179                         imc_logout( ic, TRUE );
     168                if (xt_feed(jd->xt, buf, st) < 0) {
     169                        imcb_error(ic, "XML stream error");
     170                        imc_logout(ic, TRUE);
    180171                        return FALSE;
    181172                }
    182                
     173
    183174                /* Execute all handlers. */
    184                 if( !xt_handle( jd->xt, NULL, 1 ) )
    185                 {
     175                if (!xt_handle(jd->xt, NULL, 1)) {
    186176                        /* Don't do anything, the handlers should have
    187177                           aborted the connection already. */
    188178                        return FALSE;
    189179                }
    190                
    191                 if( jd->flags & JFLAG_STREAM_RESTART )
    192                 {
     180
     181                if (jd->flags & JFLAG_STREAM_RESTART) {
    193182                        jd->flags &= ~JFLAG_STREAM_RESTART;
    194                         jabber_start_stream( ic );
    195                 }
    196                
     183                        jabber_start_stream(ic);
     184                }
     185
    197186                /* Garbage collection. */
    198                 xt_cleanup( jd->xt, NULL, 1 );
    199                
     187                xt_cleanup(jd->xt, NULL, 1);
     188
    200189                /* This is a bit hackish, unfortunately. Although xmltree
    201190                   has nifty event handler stuff, it only calls handlers
     
    203192                   send an opening <stream:stream> tag, we have to check
    204193                   this by hand. :-( */
    205                 if( !( jd->flags & JFLAG_STREAM_STARTED ) && jd->xt && jd->xt->root )
    206                 {
    207                         if( g_strcasecmp( jd->xt->root->name, "stream:stream" ) == 0 )
    208                         {
     194                if (!(jd->flags & JFLAG_STREAM_STARTED) && jd->xt && jd->xt->root) {
     195                        if (g_strcasecmp(jd->xt->root->name, "stream:stream") == 0) {
    209196                                jd->flags |= JFLAG_STREAM_STARTED;
    210                                
     197
    211198                                /* If there's no version attribute, assume
    212199                                   this is an old server that can't do SASL
    213200                                   authentication. */
    214                                 if( !set_getbool( &ic->acc->set, "sasl") || !sasl_supported( ic ) )
    215                                 {
     201                                if (!set_getbool(&ic->acc->set, "sasl") || !sasl_supported(ic)) {
    216202                                        /* If there's no version= tag, we suppose
    217203                                           this server does NOT implement: XMPP 1.0,
    218204                                           SASL and TLS. */
    219                                         if( set_getbool( &ic->acc->set, "tls" ) )
    220                                         {
    221                                                 imcb_error( ic, "TLS is turned on for this "
    222                                                           "account, but is not supported by this server" );
    223                                                 imc_logout( ic, FALSE );
     205                                        if (set_getbool(&ic->acc->set, "tls")) {
     206                                                imcb_error(ic, "TLS is turned on for this "
     207                                                           "account, but is not supported by this server");
     208                                                imc_logout(ic, FALSE);
    224209                                                return FALSE;
    225                                         }
    226                                         else
    227                                         {
    228                                                 return jabber_init_iq_auth( ic );
     210                                        } else {
     211                                                return jabber_init_iq_auth(ic);
    229212                                        }
    230213                                }
    231                         }
    232                         else
    233                         {
    234                                 imcb_error( ic, "XML stream error" );
    235                                 imc_logout( ic, TRUE );
     214                        } else {
     215                                imcb_error(ic, "XML stream error");
     216                                imc_logout(ic, TRUE);
    236217                                return FALSE;
    237218                        }
    238219                }
    239         }
    240         else if( st == 0 || ( st < 0 && !ssl_sockerr_again( jd->ssl ) ) )
    241         {
    242                 closesocket( jd->fd );
     220        } else if (st == 0 || (st < 0 && !ssl_sockerr_again(jd->ssl))) {
     221                closesocket(jd->fd);
    243222                jd->fd = -1;
    244                
    245                 imcb_error( ic, "Error while reading from server" );
    246                 imc_logout( ic, TRUE );
    247                 return FALSE;
    248         }
    249        
    250         if( ssl_pending( jd->ssl ) )
     223
     224                imcb_error(ic, "Error while reading from server");
     225                imc_logout(ic, TRUE);
     226                return FALSE;
     227        }
     228
     229        if (ssl_pending(jd->ssl)) {
    251230                /* OpenSSL empties the TCP buffers completely but may keep some
    252231                   data in its internap buffers. select() won't see that, but
    253232                   ssl_pending() does. */
    254                 return jabber_read_callback( data, fd, cond );
    255         else
     233                return jabber_read_callback(data, fd, cond);
     234        } else {
    256235                return TRUE;
    257 }
    258 
    259 gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond )
    260 {
    261         struct im_connection *ic = data;
    262        
    263         if( g_slist_find( jabber_connections, ic ) == NULL )
    264                 return FALSE;
    265        
    266         if( source == -1 )
    267         {
    268                 imcb_error( ic, "Could not connect to server" );
    269                 imc_logout( ic, TRUE );
    270                 return FALSE;
    271         }
    272        
    273         imcb_log( ic, "Connected to server, logging in" );
    274        
    275         return jabber_start_stream( ic );
    276 }
    277 
    278 gboolean jabber_connected_ssl( gpointer data, int returncode, void *source, b_input_condition cond )
     236        }
     237}
     238
     239gboolean jabber_connected_plain(gpointer data, gint source, b_input_condition cond)
     240{
     241        struct im_connection *ic = data;
     242
     243        if (g_slist_find(jabber_connections, ic) == NULL) {
     244                return FALSE;
     245        }
     246
     247        if (source == -1) {
     248                imcb_error(ic, "Could not connect to server");
     249                imc_logout(ic, TRUE);
     250                return FALSE;
     251        }
     252
     253        imcb_log(ic, "Connected to server, logging in");
     254
     255        return jabber_start_stream(ic);
     256}
     257
     258gboolean jabber_connected_ssl(gpointer data, int returncode, void *source, b_input_condition cond)
    279259{
    280260        struct im_connection *ic = data;
    281261        struct jabber_data *jd;
    282        
    283         if( g_slist_find( jabber_connections, ic ) == NULL )
    284                 return FALSE;
    285        
     262
     263        if (g_slist_find(jabber_connections, ic) == NULL) {
     264                return FALSE;
     265        }
     266
    286267        jd = ic->proto_data;
    287        
    288         if( source == NULL )
    289         {
     268
     269        if (source == NULL) {
    290270                /* The SSL connection will be cleaned up by the SSL lib
    291271                   already, set it to NULL here to prevent a double cleanup: */
    292272                jd->ssl = NULL;
    293                
    294                 if( returncode != 0 )
    295                 {
    296                         char *err = ssl_verify_strerror( returncode );
    297                         imcb_error( ic, "Certificate verification problem 0x%x: %s",
    298                                     returncode, err ? err : "Unknown" );
    299                         g_free( err );
    300                         imc_logout( ic, FALSE );
    301                 }
    302                 else
    303                 {
    304                         imcb_error( ic, "Could not connect to server" );
    305                         imc_logout( ic, TRUE );
    306                 }
    307                
    308                 return FALSE;
    309         }
    310        
    311         imcb_log( ic, "Connected to server, logging in" );
    312        
    313         return jabber_start_stream( ic );
    314 }
    315 
    316 static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data )
    317 {
    318         imc_logout( data, TRUE );
     273
     274                if (returncode != 0) {
     275                        char *err = ssl_verify_strerror(returncode);
     276                        imcb_error(ic, "Certificate verification problem 0x%x: %s",
     277                                   returncode, err ? err : "Unknown");
     278                        g_free(err);
     279                        imc_logout(ic, FALSE);
     280                } else {
     281                        imcb_error(ic, "Could not connect to server");
     282                        imc_logout(ic, TRUE);
     283                }
     284
     285                return FALSE;
     286        }
     287
     288        imcb_log(ic, "Connected to server, logging in");
     289
     290        return jabber_start_stream(ic);
     291}
     292
     293static xt_status jabber_end_of_stream(struct xt_node *node, gpointer data)
     294{
     295        imc_logout(data, TRUE);
    319296        return XT_ABORT;
    320297}
    321298
    322 static xt_status jabber_pkt_features( struct xt_node *node, gpointer data )
     299static xt_status jabber_pkt_features(struct xt_node *node, gpointer data)
    323300{
    324301        struct im_connection *ic = data;
     
    326303        struct xt_node *c, *reply;
    327304        int trytls;
    328        
    329         trytls = g_strcasecmp( set_getstr( &ic->acc->set, "tls" ), "try" ) == 0;
    330         c = xt_find_node( node->children, "starttls" );
    331         if( c && !jd->ssl )
    332         {
     305
     306        trytls = g_strcasecmp(set_getstr(&ic->acc->set, "tls"), "try") == 0;
     307        c = xt_find_node(node->children, "starttls");
     308        if (c && !jd->ssl) {
    333309                /* If the server advertises the STARTTLS feature and if we're
    334310                   not in a secure connection already: */
    335                
    336                 c = xt_find_node( c->children, "required" );
    337                
    338                 if( c && ( !trytls && !set_getbool( &ic->acc->set, "tls" ) ) )
    339                 {
    340                         imcb_error( ic, "Server requires TLS connections, but TLS is turned off for this account" );
    341                         imc_logout( ic, FALSE );
    342                        
     311
     312                c = xt_find_node(c->children, "required");
     313
     314                if (c && (!trytls && !set_getbool(&ic->acc->set, "tls"))) {
     315                        imcb_error(ic, "Server requires TLS connections, but TLS is turned off for this account");
     316                        imc_logout(ic, FALSE);
     317
    343318                        return XT_ABORT;
    344319                }
    345                
     320
    346321                /* Only run this if the tls setting is set to true or try: */
    347                 if( ( trytls || set_getbool( &ic->acc->set, "tls" ) ) )
    348                 {
    349                         reply = xt_new_node( "starttls", NULL, NULL );
    350                         xt_add_attr( reply, "xmlns", XMLNS_TLS );
    351                         if( !jabber_write_packet( ic, reply ) )
    352                         {
    353                                 xt_free_node( reply );
     322                if ((trytls || set_getbool(&ic->acc->set, "tls"))) {
     323                        reply = xt_new_node("starttls", NULL, NULL);
     324                        xt_add_attr(reply, "xmlns", XMLNS_TLS);
     325                        if (!jabber_write_packet(ic, reply)) {
     326                                xt_free_node(reply);
    354327                                return XT_ABORT;
    355328                        }
    356                         xt_free_node( reply );
    357                        
     329                        xt_free_node(reply);
     330
    358331                        return XT_HANDLED;
    359332                }
    360         }
    361         else if( !c && !jd->ssl )
    362         {
     333        } else if (!c && !jd->ssl) {
    363334                /* If the server does not advertise the STARTTLS feature and
    364335                   we're not in a secure connection already: (Servers have a
    365336                   habit of not advertising <starttls/> anymore when already
    366337                   using SSL/TLS. */
    367                
    368                 if( !trytls && set_getbool( &ic->acc->set, "tls" ) )
    369                 {
    370                         imcb_error( ic, "TLS is turned on for this account, but is not supported by this server" );
    371                         imc_logout( ic, FALSE );
    372                        
     338
     339                if (!trytls && set_getbool(&ic->acc->set, "tls")) {
     340                        imcb_error(ic, "TLS is turned on for this account, but is not supported by this server");
     341                        imc_logout(ic, FALSE);
     342
    373343                        return XT_ABORT;
    374344                }
    375345        }
    376        
     346
    377347        /* This one used to be in jabber_handlers[], but it has to be done
    378348           from here to make sure the TLS session will be initialized
    379349           properly before we attempt SASL authentication. */
    380         if( ( c = xt_find_node( node->children, "mechanisms" ) ) )
    381         {
    382                 if( sasl_pkt_mechanisms( c, data ) == XT_ABORT )
     350        if ((c = xt_find_node(node->children, "mechanisms"))) {
     351                if (sasl_pkt_mechanisms(c, data) == XT_ABORT) {
    383352                        return XT_ABORT;
     353                }
    384354        }
    385355        /* If the server *SEEMS* to support SASL authentication but doesn't
     
    387357           other way. jabber.com doesn't seem to do SASL while it pretends
    388358           to be XMPP 1.0 compliant! */
    389         else if( !( jd->flags & JFLAG_AUTHENTICATED ) && set_getbool( &ic->acc->set, "sasl") && sasl_supported( ic ) )
    390         {
    391                 if( !jabber_init_iq_auth( ic ) )
     359        else if (!(jd->flags & JFLAG_AUTHENTICATED) && set_getbool(&ic->acc->set, "sasl") && sasl_supported(ic)) {
     360                if (!jabber_init_iq_auth(ic)) {
    392361                        return XT_ABORT;
    393         }
    394        
    395         if( ( c = xt_find_node( node->children, "bind" ) ) )
     362                }
     363        }
     364
     365        if ((c = xt_find_node(node->children, "bind"))) {
    396366                jd->flags |= JFLAG_WANT_BIND;
    397        
    398         if( ( c = xt_find_node( node->children, "session" ) ) )
     367        }
     368
     369        if ((c = xt_find_node(node->children, "session"))) {
    399370                jd->flags |= JFLAG_WANT_SESSION;
    400        
    401         if( jd->flags & JFLAG_AUTHENTICATED )
    402                 return jabber_pkt_bind_sess( ic, NULL, NULL );
    403        
     371        }
     372
     373        if (jd->flags & JFLAG_AUTHENTICATED) {
     374                return jabber_pkt_bind_sess(ic, NULL, NULL);
     375        }
     376
    404377        return XT_HANDLED;
    405378}
    406379
    407 static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data )
     380static xt_status jabber_pkt_proceed_tls(struct xt_node *node, gpointer data)
    408381{
    409382        struct im_connection *ic = data;
    410383        struct jabber_data *jd = ic->proto_data;
    411384        char *xmlns, *tlsname;
    412        
    413         xmlns = xt_find_attr( node, "xmlns" );
    414        
     385
     386        xmlns = xt_find_attr(node, "xmlns");
     387
    415388        /* Just ignore it when it doesn't seem to be TLS-related (is that at
    416389           all possible??). */
    417         if( !xmlns || strcmp( xmlns, XMLNS_TLS ) != 0 )
     390        if (!xmlns || strcmp(xmlns, XMLNS_TLS) != 0) {
    418391                return XT_HANDLED;
    419        
     392        }
     393
    420394        /* We don't want event handlers to touch our TLS session while it's
    421395           still initializing! */
    422         b_event_remove( jd->r_inpa );
    423         if( jd->tx_len > 0 )
    424         {
     396        b_event_remove(jd->r_inpa);
     397        if (jd->tx_len > 0) {
    425398                /* Actually the write queue should be empty here, but just
    426399                   to be sure... */
    427                 b_event_remove( jd->w_inpa );
    428                 g_free( jd->txq );
     400                b_event_remove(jd->w_inpa);
     401                g_free(jd->txq);
    429402                jd->txq = NULL;
    430403                jd->tx_len = 0;
    431404        }
    432405        jd->w_inpa = jd->r_inpa = 0;
    433        
    434         imcb_log( ic, "Converting stream to TLS" );
    435        
     406
     407        imcb_log(ic, "Converting stream to TLS");
     408
    436409        jd->flags |= JFLAG_STARTTLS_DONE;
    437410
    438         /* If the user specified a server for the account, use this server as the 
    439          * hostname in the certificate verification. Else we use the domain from 
     411        /* If the user specified a server for the account, use this server as the
     412         * hostname in the certificate verification. Else we use the domain from
    440413         * the username. */
    441         if( ic->acc->server && *ic->acc->server )
     414        if (ic->acc->server && *ic->acc->server) {
    442415                tlsname = ic->acc->server;
    443         else
     416        } else {
    444417                tlsname = jd->server;
    445        
    446         jd->ssl = ssl_starttls( jd->fd, tlsname, set_getbool( &ic->acc->set, "tls_verify" ),
    447                                 jabber_connected_ssl, ic );
    448        
     418        }
     419
     420        jd->ssl = ssl_starttls(jd->fd, tlsname, set_getbool(&ic->acc->set, "tls_verify"),
     421                               jabber_connected_ssl, ic);
     422
    449423        return XT_HANDLED;
    450424}
    451425
    452 static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data )
     426static xt_status jabber_pkt_stream_error(struct xt_node *node, gpointer data)
    453427{
    454428        struct im_connection *ic = data;
     
    457431        struct jabber_error *err;
    458432        struct xt_node *host;
    459        
    460         if( !( ic->flags & OPT_LOGGED_IN ) &&
    461             ( host = xt_find_node( node->children, "see-other-host" ) ) &&
    462             host->text )
    463         {
     433
     434        if (!(ic->flags & OPT_LOGGED_IN) &&
     435            (host = xt_find_node(node->children, "see-other-host")) &&
     436            host->text) {
    464437                char *s;
    465                 int port = set_getint( &ic->acc->set, "port" );
    466                
     438                int port = set_getint(&ic->acc->set, "port");
     439
    467440                /* Let's try to obey this request, if we're not logged
    468441                   in yet (i.e. not have too much state yet). */
    469                 if( jd->ssl )
    470                         ssl_disconnect( jd->ssl );
    471                 closesocket( jd->fd );
    472                 b_event_remove( jd->r_inpa );
    473                 b_event_remove( jd->w_inpa );
    474                
     442                if (jd->ssl) {
     443                        ssl_disconnect(jd->ssl);
     444                }
     445                closesocket(jd->fd);
     446                b_event_remove(jd->r_inpa);
     447                b_event_remove(jd->w_inpa);
     448
    475449                jd->ssl = NULL;
    476450                jd->r_inpa = jd->w_inpa = 0;
    477451                jd->flags &= JFLAG_XMLCONSOLE;
    478                
    479                 s = strchr( host->text, ':' );
    480                 if( s != NULL )
    481                         sscanf( s + 1, "%d", &port );
    482                
    483                 imcb_log( ic, "Redirected to %s", host->text );
    484                 jd->fd = proxy_connect( host->text, port, jabber_connected_plain, ic );
    485                
     452
     453                s = strchr(host->text, ':');
     454                if (s != NULL) {
     455                        sscanf(s + 1, "%d", &port);
     456                }
     457
     458                imcb_log(ic, "Redirected to %s", host->text);
     459                jd->fd = proxy_connect(host->text, port, jabber_connected_plain, ic);
     460
    486461                return XT_ABORT;
    487462        }
    488        
    489         err = jabber_error_parse( node, XMLNS_STREAM_ERROR );
    490        
     463
     464        err = jabber_error_parse(node, XMLNS_STREAM_ERROR);
     465
    491466        /* Tssk... */
    492         if( err->code == NULL )
    493         {
    494                 imcb_error( ic, "Unknown stream error reported by server" );
    495                 imc_logout( ic, allow_reconnect );
    496                 jabber_error_free( err );
     467        if (err->code == NULL) {
     468                imcb_error(ic, "Unknown stream error reported by server");
     469                imc_logout(ic, allow_reconnect);
     470                jabber_error_free(err);
    497471                return XT_ABORT;
    498472        }
    499        
     473
    500474        /* We know that this is a fatal error. If it's a "conflict" error, we
    501475           should turn off auto-reconnect to make sure we won't get some nasty
    502476           infinite loop! */
    503         if( strcmp( err->code, "conflict" ) == 0 )
    504         {
    505                 imcb_error( ic, "Account and resource used from a different location" );
     477        if (strcmp(err->code, "conflict") == 0) {
     478                imcb_error(ic, "Account and resource used from a different location");
    506479                allow_reconnect = FALSE;
    507         }
    508         else if( strcmp( err->code, "not-authorized" ) == 0 )
    509         {
    510                 imcb_error( ic, "Not authorized" );
     480        } else if (strcmp(err->code, "not-authorized") == 0) {
     481                imcb_error(ic, "Not authorized");
    511482                allow_reconnect = FALSE;
    512         }
    513         else
    514         {
    515                 imcb_error( ic, "Stream error: %s%s%s", err->code, err->text ? ": " : "",
    516                             err->text ? err->text : "" );
    517         }
    518        
    519         jabber_error_free( err );
    520         imc_logout( ic, allow_reconnect );
    521        
     483        } else {
     484                imcb_error(ic, "Stream error: %s%s%s", err->code, err->text ? ": " : "",
     485                           err->text ? err->text : "");
     486        }
     487
     488        jabber_error_free(err);
     489        imc_logout(ic, allow_reconnect);
     490
    522491        return XT_ABORT;
    523492}
    524493
    525 static xt_status jabber_xmlconsole( struct xt_node *node, gpointer data )
    526 {
    527         struct im_connection *ic = data;
    528         struct jabber_data *jd = ic->proto_data;
    529        
    530         if( jd->flags & JFLAG_XMLCONSOLE )
    531         {
     494static xt_status jabber_xmlconsole(struct xt_node *node, gpointer data)
     495{
     496        struct im_connection *ic = data;
     497        struct jabber_data *jd = ic->proto_data;
     498
     499        if (jd->flags & JFLAG_XMLCONSOLE) {
    532500                char *msg, *pkt;
    533                
    534                 pkt = xt_to_string( node );
    535                 msg = g_strdup_printf( "RX: %s", pkt );
    536                 imcb_buddy_msg( ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0 );
    537                 g_free( msg );
    538                 g_free( pkt );
    539         }
    540        
     501
     502                pkt = xt_to_string(node);
     503                msg = g_strdup_printf("RX: %s", pkt);
     504                imcb_buddy_msg(ic, JABBER_XMLCONSOLE_HANDLE, msg, 0, 0);
     505                g_free(msg);
     506                g_free(pkt);
     507        }
     508
    541509        return XT_NEXT;
    542510}
     
    557525};
    558526
    559 gboolean jabber_start_stream( struct im_connection *ic )
     527gboolean jabber_start_stream(struct im_connection *ic)
    560528{
    561529        struct jabber_data *jd = ic->proto_data;
    562530        int st;
    563531        char *greet;
    564        
     532
    565533        /* We'll start our stream now, so prepare everything to receive one
    566534           from the server too. */
    567         xt_free( jd->xt );      /* In case we're RE-starting. */
    568         jd->xt = xt_new( jabber_handlers, ic );
    569        
    570         if( jd->r_inpa <= 0 )
    571                 jd->r_inpa = b_input_add( jd->fd, B_EV_IO_READ, jabber_read_callback, ic );
    572        
    573         greet = g_strdup_printf( "%s<stream:stream to=\"%s\" xmlns=\"jabber:client\" "
    574                                   "xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\">",
    575                                   ( jd->flags & JFLAG_STARTTLS_DONE ) ? "" : "<?xml version='1.0' ?>",
    576                                   jd->server );
    577        
    578         st = jabber_write( ic, greet, strlen( greet ) );
    579        
    580         g_free( greet );
    581        
     535        xt_free(jd->xt);        /* In case we're RE-starting. */
     536        jd->xt = xt_new(jabber_handlers, ic);
     537
     538        if (jd->r_inpa <= 0) {
     539                jd->r_inpa = b_input_add(jd->fd, B_EV_IO_READ, jabber_read_callback, ic);
     540        }
     541
     542        greet = g_strdup_printf("%s<stream:stream to=\"%s\" xmlns=\"jabber:client\" "
     543                                "xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\">",
     544                                (jd->flags & JFLAG_STARTTLS_DONE) ? "" : "<?xml version='1.0' ?>",
     545                                jd->server);
     546
     547        st = jabber_write(ic, greet, strlen(greet));
     548
     549        g_free(greet);
     550
    582551        return st;
    583552}
    584553
    585 void jabber_end_stream( struct im_connection *ic )
    586 {
    587         struct jabber_data *jd = ic->proto_data;
    588        
     554void jabber_end_stream(struct im_connection *ic)
     555{
     556        struct jabber_data *jd = ic->proto_data;
     557
    589558        /* Let's only do this if the queue is currently empty, otherwise it'd
    590559           take too long anyway. */
    591         if( jd->tx_len == 0 )
    592         {
     560        if (jd->tx_len == 0) {
    593561                char eos[] = "</stream:stream>";
    594562                struct xt_node *node;
    595563                int st = 1;
    596                
    597                 if( ic->flags & OPT_LOGGED_IN )
    598                 {
    599                         node = jabber_make_packet( "presence", "unavailable", NULL, NULL );
    600                         st = jabber_write_packet( ic, node );
    601                         xt_free_node( node );
    602                 }
    603                
    604                 if( st )
    605                         jabber_write( ic, eos, strlen( eos ) );
    606         }
    607 }
     564
     565                if (ic->flags & OPT_LOGGED_IN) {
     566                        node = jabber_make_packet("presence", "unavailable", NULL, NULL);
     567                        st = jabber_write_packet(ic, node);
     568                        xt_free_node(node);
     569                }
     570
     571                if (st) {
     572                        jabber_write(ic, eos, strlen(eos));
     573                }
     574        }
     575}
  • protocols/jabber/iq.c

    raf359b4 r5ebff60  
    2525#include "sha1.h"
    2626
    27 static xt_status jabber_parse_roster( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    28 static xt_status jabber_iq_display_vcard( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    29 static int jabber_iq_disco_server( struct im_connection *ic );
    30 
    31 xt_status jabber_pkt_iq( struct xt_node *node, gpointer data )
     27static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     28static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     29static int jabber_iq_disco_server(struct im_connection *ic);
     30
     31xt_status jabber_pkt_iq(struct xt_node *node, gpointer data)
    3232{
    3333        struct im_connection *ic = data;
     
    3636        char *type, *s;
    3737        int st, pack = 1;
    38        
    39         type = xt_find_attr( node, "type" );
    40        
    41         if( !type )
    42         {
    43                 imcb_error( ic, "Received IQ packet without type." );
    44                 imc_logout( ic, TRUE );
     38
     39        type = xt_find_attr(node, "type");
     40
     41        if (!type) {
     42                imcb_error(ic, "Received IQ packet without type.");
     43                imc_logout(ic, TRUE);
    4544                return XT_ABORT;
    4645        }
    47        
    48         if( strcmp( type, "result" ) == 0 || strcmp( type, "error" ) == 0 )
    49         {
    50                 return jabber_cache_handle_packet( ic, node );
    51         }
    52         else if( strcmp( type, "get" ) == 0 )
    53         {
    54                 if( !( ( c = xt_find_node( node->children, "query" ) ) ||
    55                        ( c = xt_find_node( node->children, "ping" ) ) ||
    56                        ( c = xt_find_node( node->children, "time" ) ) ) ||
    57                     !( s = xt_find_attr( c, "xmlns" ) ) )
    58                 {
     46
     47        if (strcmp(type, "result") == 0 || strcmp(type, "error") == 0) {
     48                return jabber_cache_handle_packet(ic, node);
     49        } else if (strcmp(type, "get") == 0) {
     50                if (!((c = xt_find_node(node->children, "query")) ||
     51                      (c = xt_find_node(node->children, "ping")) ||
     52                      (c = xt_find_node(node->children, "time"))) ||
     53                    !(s = xt_find_attr(c, "xmlns"))) {
    5954                        /* Sigh. Who decided to suddenly invent new elements
    6055                           instead of just sticking with <query/>? */
    6156                        return XT_HANDLED;
    6257                }
    63                
    64                 reply = xt_new_node( "query", NULL, NULL );
    65                 xt_add_attr( reply, "xmlns", s );
    66                
     58
     59                reply = xt_new_node("query", NULL, NULL);
     60                xt_add_attr(reply, "xmlns", s);
     61
    6762                /* Of course this is a very essential query to support. ;-) */
    68                 if( strcmp( s, XMLNS_VERSION ) == 0 )
    69                 {
    70                         xt_add_child( reply, xt_new_node( "name", set_getstr( &ic->acc->set, "user_agent" ), NULL ) );
    71                         xt_add_child( reply, xt_new_node( "version", BITLBEE_VERSION, NULL ) );
    72                         xt_add_child( reply, xt_new_node( "os", ARCH, NULL ) );
    73                 }
    74                 else if( strcmp( s, XMLNS_TIME_OLD ) == 0 )
    75                 {
     63                if (strcmp(s, XMLNS_VERSION) == 0) {
     64                        xt_add_child(reply, xt_new_node("name", set_getstr(&ic->acc->set, "user_agent"), NULL));
     65                        xt_add_child(reply, xt_new_node("version", BITLBEE_VERSION, NULL));
     66                        xt_add_child(reply, xt_new_node("os", ARCH, NULL));
     67                } else if (strcmp(s, XMLNS_TIME_OLD) == 0) {
    7668                        time_t time_ep;
    7769                        char buf[1024];
    78                        
    79                         buf[sizeof(buf)-1] = 0;
    80                         time_ep = time( NULL );
    81                        
    82                         strftime( buf, sizeof( buf ) - 1, "%Y%m%dT%H:%M:%S", gmtime( &time_ep ) );
    83                         xt_add_child( reply, xt_new_node( "utc", buf, NULL ) );
    84                        
    85                         strftime( buf, sizeof( buf ) - 1, "%Z", localtime( &time_ep ) );
    86                         xt_add_child( reply, xt_new_node( "tz", buf, NULL ) );
    87                 }
    88                 else if( strcmp( s, XMLNS_TIME ) == 0 )
    89                 {
     70
     71                        buf[sizeof(buf) - 1] = 0;
     72                        time_ep = time(NULL);
     73
     74                        strftime(buf, sizeof(buf) - 1, "%Y%m%dT%H:%M:%S", gmtime(&time_ep));
     75                        xt_add_child(reply, xt_new_node("utc", buf, NULL));
     76
     77                        strftime(buf, sizeof(buf) - 1, "%Z", localtime(&time_ep));
     78                        xt_add_child(reply, xt_new_node("tz", buf, NULL));
     79                } else if (strcmp(s, XMLNS_TIME) == 0) {
    9080                        time_t time_ep;
    9181                        char buf[1024];
    92                        
    93                         buf[sizeof(buf)-1] = 0;
    94                         time_ep = time( NULL );
    95                        
    96                         xt_free_node( reply );
    97                         reply = xt_new_node( "time", NULL, NULL );
    98                         xt_add_attr( reply, "xmlns", XMLNS_TIME );
    99                        
    100                         strftime( buf, sizeof( buf ) - 1, "%Y%m%dT%H:%M:%SZ", gmtime( &time_ep ) );
    101                         xt_add_child( reply, xt_new_node( "utc", buf, NULL ) );
    102                        
    103                         strftime( buf, sizeof( buf ) - 1, "%z", localtime( &time_ep ) );
    104                         if( strlen( buf ) >= 5 )
    105                         {
     82
     83                        buf[sizeof(buf) - 1] = 0;
     84                        time_ep = time(NULL);
     85
     86                        xt_free_node(reply);
     87                        reply = xt_new_node("time", NULL, NULL);
     88                        xt_add_attr(reply, "xmlns", XMLNS_TIME);
     89
     90                        strftime(buf, sizeof(buf) - 1, "%Y%m%dT%H:%M:%SZ", gmtime(&time_ep));
     91                        xt_add_child(reply, xt_new_node("utc", buf, NULL));
     92
     93                        strftime(buf, sizeof(buf) - 1, "%z", localtime(&time_ep));
     94                        if (strlen(buf) >= 5) {
    10695                                buf[6] = '\0';
    10796                                buf[5] = buf[4];
     
    10998                                buf[3] = ':';
    11099                        }
    111                         xt_add_child( reply, xt_new_node( "tzo", buf, NULL ) );
    112                 }
    113                 else if( strcmp( s, XMLNS_PING ) == 0 )
    114                 {
    115                         xt_free_node( reply );
    116                         reply = jabber_make_packet( "iq", "result", xt_find_attr( node, "from" ), NULL );
    117                         if( ( s = xt_find_attr( node, "id" ) ) )
    118                                 xt_add_attr( reply, "id", s );
     100                        xt_add_child(reply, xt_new_node("tzo", buf, NULL));
     101                } else if (strcmp(s, XMLNS_PING) == 0) {
     102                        xt_free_node(reply);
     103                        reply = jabber_make_packet("iq", "result", xt_find_attr(node, "from"), NULL);
     104                        if ((s = xt_find_attr(node, "id"))) {
     105                                xt_add_attr(reply, "id", s);
     106                        }
    119107                        pack = 0;
    120                 }
    121                 else if( strcmp( s, XMLNS_DISCO_INFO ) == 0 )
    122                 {
     108                } else if (strcmp(s, XMLNS_DISCO_INFO) == 0) {
    123109                        const char *features[] = { XMLNS_DISCO_INFO,
    124                                                    XMLNS_VERSION,
    125                                                    XMLNS_TIME_OLD,
    126                                                    XMLNS_TIME,
    127                                                    XMLNS_CHATSTATES,
    128                                                    XMLNS_MUC,
    129                                                    XMLNS_PING,
    130                                                    XMLNS_RECEIPTS,
    131                                                    XMLNS_SI,
    132                                                    XMLNS_BYTESTREAMS,
    133                                                    XMLNS_FILETRANSFER,
    134                                                    NULL };
     110                                                   XMLNS_VERSION,
     111                                                   XMLNS_TIME_OLD,
     112                                                   XMLNS_TIME,
     113                                                   XMLNS_CHATSTATES,
     114                                                   XMLNS_MUC,
     115                                                   XMLNS_PING,
     116                                                   XMLNS_RECEIPTS,
     117                                                   XMLNS_SI,
     118                                                   XMLNS_BYTESTREAMS,
     119                                                   XMLNS_FILETRANSFER,
     120                                                   NULL };
    135121                        const char **f;
    136                        
    137                         c = xt_new_node( "identity", NULL, NULL );
    138                         xt_add_attr( c, "category", "client" );
    139                         xt_add_attr( c, "type", "pc" );
    140                         xt_add_attr( c, "name", set_getstr( &ic->acc->set, "user_agent" ) );
    141                         xt_add_child( reply, c );
    142                        
    143                         for( f = features; *f; f ++ )
    144                         {
    145                                 c = xt_new_node( "feature", NULL, NULL );
    146                                 xt_add_attr( c, "var", *f );
    147                                 xt_add_child( reply, c );
    148                         }
    149                 }
    150                 else
    151                 {
    152                         xt_free_node( reply );
    153                         reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL );
     122
     123                        c = xt_new_node("identity", NULL, NULL);
     124                        xt_add_attr(c, "category", "client");
     125                        xt_add_attr(c, "type", "pc");
     126                        xt_add_attr(c, "name", set_getstr(&ic->acc->set, "user_agent"));
     127                        xt_add_child(reply, c);
     128
     129                        for (f = features; *f; f++) {
     130                                c = xt_new_node("feature", NULL, NULL);
     131                                xt_add_attr(c, "var", *f);
     132                                xt_add_child(reply, c);
     133                        }
     134                } else {
     135                        xt_free_node(reply);
     136                        reply = jabber_make_error_packet(node, "feature-not-implemented", "cancel", NULL);
    154137                        pack = 0;
    155138                }
    156         }
    157         else if( strcmp( type, "set" ) == 0 )
    158         {
    159                 if( ( c = xt_find_node( node->children, "si" ) ) &&
    160                     ( s = xt_find_attr( c, "xmlns" ) ) &&
    161                     ( strcmp( s, XMLNS_SI ) == 0 ) )
    162                 {
    163                         return jabber_si_handle_request( ic, node, c );
    164                 }
    165                 else if( !( c = xt_find_node( node->children, "query" ) ) ||
    166                          !( s = xt_find_attr( c, "xmlns" ) ) )
    167                 {
     139        } else if (strcmp(type, "set") == 0) {
     140                if ((c = xt_find_node(node->children, "si")) &&
     141                    (s = xt_find_attr(c, "xmlns")) &&
     142                    (strcmp(s, XMLNS_SI) == 0)) {
     143                        return jabber_si_handle_request(ic, node, c);
     144                } else if (!(c = xt_find_node(node->children, "query")) ||
     145                           !(s = xt_find_attr(c, "xmlns"))) {
    168146                        return XT_HANDLED;
    169                 }
    170                 else if( strcmp( s, XMLNS_ROSTER ) == 0 )
    171                 {
    172                 /* This is a roster push. XMPP servers send this when someone
    173                    was added to (or removed from) the buddy list. AFAIK they're
    174                    sent even if we added this buddy in our own session. */
    175                         int bare_len = strlen( jd->me );
    176                        
    177                         if( ( s = xt_find_attr( node, "from" ) ) == NULL ||
    178                             ( strncmp( s, jd->me, bare_len ) == 0 &&
    179                               ( s[bare_len] == 0 || s[bare_len] == '/' ) ) )
    180                         {
    181                                 jabber_parse_roster( ic, node, NULL );
    182                                
     147                } else if (strcmp(s, XMLNS_ROSTER) == 0) {
     148                        /* This is a roster push. XMPP servers send this when someone
     149                           was added to (or removed from) the buddy list. AFAIK they're
     150                           sent even if we added this buddy in our own session. */
     151                        int bare_len = strlen(jd->me);
     152
     153                        if ((s = xt_find_attr(node, "from")) == NULL ||
     154                            (strncmp(s, jd->me, bare_len) == 0 &&
     155                             (s[bare_len] == 0 || s[bare_len] == '/'))) {
     156                                jabber_parse_roster(ic, node, NULL);
     157
    183158                                /* Should we generate a reply here? Don't think it's
    184159                                   very important... */
    185                         }
    186                         else
    187                         {
    188                                 imcb_log( ic, "Warning: %s tried to fake a roster push!", s ? s : "(unknown)" );
    189                                
    190                                 xt_free_node( reply );
    191                                 reply = jabber_make_error_packet( node, "not-allowed", "cancel", NULL );
     160                        } else {
     161                                imcb_log(ic, "Warning: %s tried to fake a roster push!", s ? s : "(unknown)");
     162
     163                                xt_free_node(reply);
     164                                reply = jabber_make_error_packet(node, "not-allowed", "cancel", NULL);
    192165                                pack = 0;
    193166                        }
    194                 }
    195                 else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 )
    196                 {
     167                } else if (strcmp(s, XMLNS_BYTESTREAMS) == 0) {
    197168                        /* Bytestream Request (stage 2 of file transfer) */
    198                         return jabber_bs_recv_request( ic, node, c );
    199                 }
    200                 else
    201                 {
    202                         xt_free_node( reply );
    203                         reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL );
     169                        return jabber_bs_recv_request(ic, node, c);
     170                } else {
     171                        xt_free_node(reply);
     172                        reply = jabber_make_error_packet(node, "feature-not-implemented", "cancel", NULL);
    204173                        pack = 0;
    205174                }
    206175        }
    207        
     176
    208177        /* If we recognized the xmlns and managed to generate a reply,
    209178           finish and send it. */
    210         if( reply )
    211         {
     179        if (reply) {
    212180                /* Normally we still have to pack it into an iq-result
    213181                   packet, but for errors, for example, we don't. */
    214                 if( pack )
    215                 {
    216                         reply = jabber_make_packet( "iq", "result", xt_find_attr( node, "from" ), reply );
    217                         if( ( s = xt_find_attr( node, "id" ) ) )
    218                                 xt_add_attr( reply, "id", s );
    219                 }
    220                
    221                 st = jabber_write_packet( ic, reply );
    222                 xt_free_node( reply );
    223                 if( !st )
     182                if (pack) {
     183                        reply = jabber_make_packet("iq", "result", xt_find_attr(node, "from"), reply);
     184                        if ((s = xt_find_attr(node, "id"))) {
     185                                xt_add_attr(reply, "id", s);
     186                        }
     187                }
     188
     189                st = jabber_write_packet(ic, reply);
     190                xt_free_node(reply);
     191                if (!st) {
    224192                        return XT_ABORT;
    225         }
    226        
    227         return XT_HANDLED;
    228 }
    229 
    230 static xt_status jabber_do_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    231 static xt_status jabber_finish_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    232 
    233 int jabber_init_iq_auth( struct im_connection *ic )
     193                }
     194        }
     195
     196        return XT_HANDLED;
     197}
     198
     199static xt_status jabber_do_iq_auth(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     200static xt_status jabber_finish_iq_auth(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     201
     202int jabber_init_iq_auth(struct im_connection *ic)
    234203{
    235204        struct jabber_data *jd = ic->proto_data;
    236205        struct xt_node *node;
    237206        int st;
    238        
    239         node = xt_new_node( "query", NULL, xt_new_node( "username", jd->username, NULL ) );
    240         xt_add_attr( node, "xmlns", XMLNS_AUTH );
    241         node = jabber_make_packet( "iq", "get", NULL, node );
    242        
    243         jabber_cache_add( ic, node, jabber_do_iq_auth );
    244         st = jabber_write_packet( ic, node );
    245        
     207
     208        node = xt_new_node("query", NULL, xt_new_node("username", jd->username, NULL));
     209        xt_add_attr(node, "xmlns", XMLNS_AUTH);
     210        node = jabber_make_packet("iq", "get", NULL, node);
     211
     212        jabber_cache_add(ic, node, jabber_do_iq_auth);
     213        st = jabber_write_packet(ic, node);
     214
    246215        return st;
    247216}
    248217
    249 static xt_status jabber_do_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     218static xt_status jabber_do_iq_auth(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    250219{
    251220        struct jabber_data *jd = ic->proto_data;
     
    253222        xt_status st;
    254223        char *s;
    255        
    256         if( !( query = xt_find_node( node->children, "query" ) ) )
    257         {
    258                 imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" );
    259                 imc_logout( ic, FALSE );
    260                 return XT_HANDLED;
    261         }
    262        
     224
     225        if (!(query = xt_find_node(node->children, "query"))) {
     226                imcb_log(ic, "Warning: Received incomplete IQ packet while authenticating");
     227                imc_logout(ic, FALSE);
     228                return XT_HANDLED;
     229        }
     230
    263231        /* Time to authenticate ourselves! */
    264         reply = xt_new_node( "query", NULL, NULL );
    265         xt_add_attr( reply, "xmlns", XMLNS_AUTH );
    266         xt_add_child( reply, xt_new_node( "username", jd->username, NULL ) );
    267         xt_add_child( reply, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) );
    268        
    269         if( xt_find_node( query->children, "digest" ) && ( s = xt_find_attr( jd->xt->root, "id" ) ) )
    270         {
     232        reply = xt_new_node("query", NULL, NULL);
     233        xt_add_attr(reply, "xmlns", XMLNS_AUTH);
     234        xt_add_child(reply, xt_new_node("username", jd->username, NULL));
     235        xt_add_child(reply, xt_new_node("resource", set_getstr(&ic->acc->set, "resource"), NULL));
     236
     237        if (xt_find_node(query->children, "digest") && (s = xt_find_attr(jd->xt->root, "id"))) {
    271238                /* We can do digest authentication, it seems, and of
    272239                   course we prefer that. */
     
    275242                unsigned char hash[20];
    276243                int i;
    277                
    278                 sha1_init( &sha );
    279                 sha1_append( &sha, (unsigned char*) s, strlen( s ) );
    280                 sha1_append( &sha, (unsigned char*) ic->acc->pass, strlen( ic->acc->pass ) );
    281                 sha1_finish( &sha, hash );
    282                
    283                 for( i = 0; i < 20; i ++ )
    284                         sprintf( hash_hex + i * 2, "%02x", hash[i] );
    285                
    286                 xt_add_child( reply, xt_new_node( "digest", hash_hex, NULL ) );
    287         }
    288         else if( xt_find_node( query->children, "password" ) )
    289         {
     244
     245                sha1_init(&sha);
     246                sha1_append(&sha, (unsigned char *) s, strlen(s));
     247                sha1_append(&sha, (unsigned char *) ic->acc->pass, strlen(ic->acc->pass));
     248                sha1_finish(&sha, hash);
     249
     250                for (i = 0; i < 20; i++) {
     251                        sprintf(hash_hex + i * 2, "%02x", hash[i]);
     252                }
     253
     254                xt_add_child(reply, xt_new_node("digest", hash_hex, NULL));
     255        } else if (xt_find_node(query->children, "password")) {
    290256                /* We'll have to stick with plaintext. Let's hope we're using SSL/TLS... */
    291                 xt_add_child( reply, xt_new_node( "password", ic->acc->pass, NULL ) );
    292         }
    293         else
    294         {
    295                 xt_free_node( reply );
    296                
    297                 imcb_error( ic, "Can't find suitable authentication method" );
    298                 imc_logout( ic, FALSE );
     257                xt_add_child(reply, xt_new_node("password", ic->acc->pass, NULL));
     258        } else {
     259                xt_free_node(reply);
     260
     261                imcb_error(ic, "Can't find suitable authentication method");
     262                imc_logout(ic, FALSE);
    299263                return XT_ABORT;
    300264        }
    301        
    302         reply = jabber_make_packet( "iq", "set", NULL, reply );
    303         jabber_cache_add( ic, reply, jabber_finish_iq_auth );
    304         st = jabber_write_packet( ic, reply );
    305        
     265
     266        reply = jabber_make_packet("iq", "set", NULL, reply);
     267        jabber_cache_add(ic, reply, jabber_finish_iq_auth);
     268        st = jabber_write_packet(ic, reply);
     269
    306270        return st ? XT_HANDLED : XT_ABORT;
    307271}
    308272
    309 static xt_status jabber_finish_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     273static xt_status jabber_finish_iq_auth(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    310274{
    311275        struct jabber_data *jd = ic->proto_data;
    312276        char *type;
    313        
    314         if( !( type = xt_find_attr( node, "type" ) ) )
    315         {
    316                 imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" );
    317                 imc_logout( ic, FALSE );
    318                 return XT_HANDLED;
    319         }
    320        
    321         if( strcmp( type, "error" ) == 0 )
    322         {
    323                 imcb_error( ic, "Authentication failure" );
    324                 imc_logout( ic, FALSE );
     277
     278        if (!(type = xt_find_attr(node, "type"))) {
     279                imcb_log(ic, "Warning: Received incomplete IQ packet while authenticating");
     280                imc_logout(ic, FALSE);
     281                return XT_HANDLED;
     282        }
     283
     284        if (strcmp(type, "error") == 0) {
     285                imcb_error(ic, "Authentication failure");
     286                imc_logout(ic, FALSE);
    325287                return XT_ABORT;
    326         }
    327         else if( strcmp( type, "result" ) == 0 )
    328         {
     288        } else if (strcmp(type, "result") == 0) {
    329289                /* This happens when we just successfully authenticated the
    330290                   old (non-SASL) way. */
    331291                jd->flags |= JFLAG_AUTHENTICATED;
    332                 if( !jabber_get_roster( ic ) )
     292                if (!jabber_get_roster(ic)) {
    333293                        return XT_ABORT;
    334                 if( !jabber_iq_disco_server( ic ) )
     294                }
     295                if (!jabber_iq_disco_server(ic)) {
    335296                        return XT_ABORT;
    336         }
    337        
    338         return XT_HANDLED;
    339 }
    340 
    341 xt_status jabber_pkt_bind_sess( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     297                }
     298        }
     299
     300        return XT_HANDLED;
     301}
     302
     303xt_status jabber_pkt_bind_sess(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    342304{
    343305        struct jabber_data *jd = ic->proto_data;
    344306        struct xt_node *c, *reply = NULL;
    345307        char *s;
    346        
    347         if( node && ( c = xt_find_node( node->children, "bind" ) ) )
    348         {
    349                 c = xt_find_node( c->children, "jid" );
    350                 if( !c || !c->text )
    351                 {
     308
     309        if (node && (c = xt_find_node(node->children, "bind"))) {
     310                c = xt_find_node(c->children, "jid");
     311                if (!c || !c->text) {
    352312                        /* Server is crap, but this is no disaster. */
    353                 }
    354                 else if( jabber_compare_jid( jd->me, c->text ) == 0 )
    355                 {
    356                         s = strchr( c->text, '/' );
    357                         if( s )
     313                } else if (jabber_compare_jid(jd->me, c->text) == 0) {
     314                        s = strchr(c->text, '/');
     315                        if (s) {
    358316                                *s = '\0';
    359                         jabber_set_me( ic, c->text );
    360                         if( s )
     317                        }
     318                        jabber_set_me(ic, c->text);
     319                        if (s) {
    361320                                *s = '/';
    362                 }
    363                 else if( c && c->text_len && ( s = strchr( c->text, '/' ) ) &&
    364                          strcmp( s + 1, set_getstr( &ic->acc->set, "resource" ) ) != 0 )
    365                         imcb_log( ic, "Server changed session resource string to `%s'", s + 1 );
    366         }
    367        
    368         if( jd->flags & JFLAG_WANT_BIND )
    369         {
    370                 reply = xt_new_node( "bind", NULL, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) );
    371                 xt_add_attr( reply, "xmlns", XMLNS_BIND );
     321                        }
     322                } else if (c && c->text_len && (s = strchr(c->text, '/')) &&
     323                           strcmp(s + 1, set_getstr(&ic->acc->set, "resource")) != 0) {
     324                        imcb_log(ic, "Server changed session resource string to `%s'", s + 1);
     325                }
     326        }
     327
     328        if (jd->flags & JFLAG_WANT_BIND) {
     329                reply = xt_new_node("bind", NULL, xt_new_node("resource", set_getstr(&ic->acc->set, "resource"), NULL));
     330                xt_add_attr(reply, "xmlns", XMLNS_BIND);
    372331                jd->flags &= ~JFLAG_WANT_BIND;
    373         }
    374         else if( jd->flags & JFLAG_WANT_SESSION )
    375         {
    376                 reply = xt_new_node( "session", NULL, NULL );
    377                 xt_add_attr( reply, "xmlns", XMLNS_SESSION );
     332        } else if (jd->flags & JFLAG_WANT_SESSION) {
     333                reply = xt_new_node("session", NULL, NULL);
     334                xt_add_attr(reply, "xmlns", XMLNS_SESSION);
    378335                jd->flags &= ~JFLAG_WANT_SESSION;
    379336        }
    380        
    381         if( reply != NULL )
    382         {
    383                 reply = jabber_make_packet( "iq", "set", NULL, reply );
    384                 jabber_cache_add( ic, reply, jabber_pkt_bind_sess );
    385                
    386                 if( !jabber_write_packet( ic, reply ) )
     337
     338        if (reply != NULL) {
     339                reply = jabber_make_packet("iq", "set", NULL, reply);
     340                jabber_cache_add(ic, reply, jabber_pkt_bind_sess);
     341
     342                if (!jabber_write_packet(ic, reply)) {
    387343                        return XT_ABORT;
    388         }
    389         else if( ( jd->flags & ( JFLAG_WANT_BIND | JFLAG_WANT_SESSION ) ) == 0 )
    390         {
    391                 if( !jabber_get_roster( ic ) )
     344                }
     345        } else if ((jd->flags & (JFLAG_WANT_BIND | JFLAG_WANT_SESSION)) == 0) {
     346                if (!jabber_get_roster(ic)) {
    392347                        return XT_ABORT;
    393                 if( !jabber_iq_disco_server( ic ) )
     348                }
     349                if (!jabber_iq_disco_server(ic)) {
    394350                        return XT_ABORT;
    395         }
    396        
    397         return XT_HANDLED;
    398 }
    399 
    400 int jabber_get_roster( struct im_connection *ic )
     351                }
     352        }
     353
     354        return XT_HANDLED;
     355}
     356
     357int jabber_get_roster(struct im_connection *ic)
    401358{
    402359        struct xt_node *node;
    403360        int st;
    404        
    405         imcb_log( ic, "Authenticated, requesting buddy list" );
    406        
    407         node = xt_new_node( "query", NULL, NULL );
    408         xt_add_attr( node, "xmlns", XMLNS_ROSTER );
    409         node = jabber_make_packet( "iq", "get", NULL, node );
    410        
    411         jabber_cache_add( ic, node, jabber_parse_roster );
    412         st = jabber_write_packet( ic, node );
    413        
     361
     362        imcb_log(ic, "Authenticated, requesting buddy list");
     363
     364        node = xt_new_node("query", NULL, NULL);
     365        xt_add_attr(node, "xmlns", XMLNS_ROSTER);
     366        node = jabber_make_packet("iq", "get", NULL, node);
     367
     368        jabber_cache_add(ic, node, jabber_parse_roster);
     369        st = jabber_write_packet(ic, node);
     370
    414371        return st;
    415372}
    416373
    417 static xt_status jabber_parse_roster( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     374static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    418375{
    419376        struct xt_node *query, *c;
    420         int initial = ( orig != NULL );
    421        
    422         if( !( query = xt_find_node( node->children, "query" ) ) )
    423         {
    424                 imcb_log( ic, "Warning: Received NULL roster packet" );
    425                 return XT_HANDLED;
    426         }
    427        
     377        int initial = (orig != NULL);
     378
     379        if (!(query = xt_find_node(node->children, "query"))) {
     380                imcb_log(ic, "Warning: Received NULL roster packet");
     381                return XT_HANDLED;
     382        }
     383
    428384        c = query->children;
    429         while( ( c = xt_find_node( c, "item" ) ) )
    430         {
    431                 struct xt_node *group = xt_find_node( c->children, "group" );
    432                 char *jid = xt_find_attr( c, "jid" );
    433                 char *name = xt_find_attr( c, "name" );
    434                 char *sub = xt_find_attr( c, "subscription" );
    435                
    436                 if( jid && sub )
    437                 {
    438                         if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) )
    439                         {
    440                                 imcb_add_buddy( ic, jid, ( group && group->text_len ) ?
    441                                                            group->text : NULL );
    442                                
    443                                 if( name )
    444                                         imcb_rename_buddy( ic, jid, name );
    445                         }
    446                         else if( strcmp( sub, "remove" ) == 0 )
    447                         {
    448                                 jabber_buddy_remove_bare( ic, jid );
    449                                 imcb_remove_buddy( ic, jid, NULL );
    450                         }
    451                 }
    452                
     385        while ((c = xt_find_node(c, "item"))) {
     386                struct xt_node *group = xt_find_node(c->children, "group");
     387                char *jid = xt_find_attr(c, "jid");
     388                char *name = xt_find_attr(c, "name");
     389                char *sub = xt_find_attr(c, "subscription");
     390
     391                if (jid && sub) {
     392                        if ((strcmp(sub, "both") == 0 || strcmp(sub, "to") == 0)) {
     393                                imcb_add_buddy(ic, jid, (group && group->text_len) ?
     394                                               group->text : NULL);
     395
     396                                if (name) {
     397                                        imcb_rename_buddy(ic, jid, name);
     398                                }
     399                        } else if (strcmp(sub, "remove") == 0) {
     400                                jabber_buddy_remove_bare(ic, jid);
     401                                imcb_remove_buddy(ic, jid, NULL);
     402                        }
     403                }
     404
    453405                c = c->next;
    454406        }
    455        
    456         if( initial )
    457                 imcb_connected( ic );
    458        
    459         return XT_HANDLED;
    460 }
    461 
    462 int jabber_get_vcard( struct im_connection *ic, char *bare_jid )
     407
     408        if (initial) {
     409                imcb_connected(ic);
     410        }
     411
     412        return XT_HANDLED;
     413}
     414
     415int jabber_get_vcard(struct im_connection *ic, char *bare_jid)
    463416{
    464417        struct xt_node *node;
    465        
    466         if( strchr( bare_jid, '/' ) )
    467                 return 1;       /* This was an error, but return 0 should only be done if the connection died... */
    468        
    469         node = xt_new_node( "vCard", NULL, NULL );
    470         xt_add_attr( node, "xmlns", XMLNS_VCARD );
    471         node = jabber_make_packet( "iq", "get", bare_jid, node );
    472        
    473         jabber_cache_add( ic, node, jabber_iq_display_vcard );
    474         return jabber_write_packet( ic, node );
    475 }
    476 
    477 static xt_status jabber_iq_display_vcard( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     418
     419        if (strchr(bare_jid, '/')) {
     420                return 1;       /* This was an error, but return 0 should only be done if the connection died... */
     421
     422        }
     423        node = xt_new_node("vCard", NULL, NULL);
     424        xt_add_attr(node, "xmlns", XMLNS_VCARD);
     425        node = jabber_make_packet("iq", "get", bare_jid, node);
     426
     427        jabber_cache_add(ic, node, jabber_iq_display_vcard);
     428        return jabber_write_packet(ic, node);
     429}
     430
     431static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    478432{
    479433        struct xt_node *vc, *c, *sc; /* subchild, ic is already in use ;-) */
    480434        GString *reply;
    481435        char *s;
    482        
    483         if( ( s = xt_find_attr( node, "type" ) ) == NULL ||
    484             strcmp( s, "result" ) != 0 ||
    485             ( vc = xt_find_node( node->children, "vCard" ) ) == NULL )
    486         {
    487                 s = xt_find_attr( orig, "to" ); /* If this returns NULL something's wrong.. */
    488                 imcb_log( ic, "Could not retrieve vCard of %s", s ? s : "(NULL)" );
    489                 return XT_HANDLED;
    490         }
    491        
    492         s = xt_find_attr( orig, "to" );
    493         reply = g_string_new( "vCard information for " );
    494         reply = g_string_append( reply, s ? s : "(NULL)" );
    495         reply = g_string_append( reply, ":\n" );
    496        
     436
     437        if ((s = xt_find_attr(node, "type")) == NULL ||
     438            strcmp(s, "result") != 0 ||
     439            (vc = xt_find_node(node->children, "vCard")) == NULL) {
     440                s = xt_find_attr(orig, "to");   /* If this returns NULL something's wrong.. */
     441                imcb_log(ic, "Could not retrieve vCard of %s", s ? s : "(NULL)");
     442                return XT_HANDLED;
     443        }
     444
     445        s = xt_find_attr(orig, "to");
     446        reply = g_string_new("vCard information for ");
     447        reply = g_string_append(reply, s ? s : "(NULL)");
     448        reply = g_string_append(reply, ":\n");
     449
    497450        /* I hate this format, I really do... */
    498        
    499         if( ( c = xt_find_node( vc->children, "FN" ) ) && c->text_len )
    500                 g_string_append_printf( reply, "Name: %s\n", c->text );
    501        
    502         if( ( c = xt_find_node( vc->children, "N" ) ) && c->children )
    503         {
    504                 reply = g_string_append( reply, "Full name:" );
    505                
    506                 if( ( sc = xt_find_node( c->children, "PREFIX" ) ) && sc->text_len )
    507                         g_string_append_printf( reply, " %s", sc->text );
    508                 if( ( sc = xt_find_node( c->children, "GIVEN" ) ) && sc->text_len )
    509                         g_string_append_printf( reply, " %s", sc->text );
    510                 if( ( sc = xt_find_node( c->children, "MIDDLE" ) ) && sc->text_len )
    511                         g_string_append_printf( reply, " %s", sc->text );
    512                 if( ( sc = xt_find_node( c->children, "FAMILY" ) ) && sc->text_len )
    513                         g_string_append_printf( reply, " %s", sc->text );
    514                 if( ( sc = xt_find_node( c->children, "SUFFIX" ) ) && sc->text_len )
    515                         g_string_append_printf( reply, " %s", sc->text );
    516                
    517                 reply = g_string_append_c( reply, '\n' );
    518         }
    519        
    520         if( ( c = xt_find_node( vc->children, "NICKNAME" ) ) && c->text_len )
    521                 g_string_append_printf( reply, "Nickname: %s\n", c->text );
    522        
    523         if( ( c = xt_find_node( vc->children, "BDAY" ) ) && c->text_len )
    524                 g_string_append_printf( reply, "Date of birth: %s\n", c->text );
    525        
     451
     452        if ((c = xt_find_node(vc->children, "FN")) && c->text_len) {
     453                g_string_append_printf(reply, "Name: %s\n", c->text);
     454        }
     455
     456        if ((c = xt_find_node(vc->children, "N")) && c->children) {
     457                reply = g_string_append(reply, "Full name:");
     458
     459                if ((sc = xt_find_node(c->children, "PREFIX")) && sc->text_len) {
     460                        g_string_append_printf(reply, " %s", sc->text);
     461                }
     462                if ((sc = xt_find_node(c->children, "GIVEN")) && sc->text_len) {
     463                        g_string_append_printf(reply, " %s", sc->text);
     464                }
     465                if ((sc = xt_find_node(c->children, "MIDDLE")) && sc->text_len) {
     466                        g_string_append_printf(reply, " %s", sc->text);
     467                }
     468                if ((sc = xt_find_node(c->children, "FAMILY")) && sc->text_len) {
     469                        g_string_append_printf(reply, " %s", sc->text);
     470                }
     471                if ((sc = xt_find_node(c->children, "SUFFIX")) && sc->text_len) {
     472                        g_string_append_printf(reply, " %s", sc->text);
     473                }
     474
     475                reply = g_string_append_c(reply, '\n');
     476        }
     477
     478        if ((c = xt_find_node(vc->children, "NICKNAME")) && c->text_len) {
     479                g_string_append_printf(reply, "Nickname: %s\n", c->text);
     480        }
     481
     482        if ((c = xt_find_node(vc->children, "BDAY")) && c->text_len) {
     483                g_string_append_printf(reply, "Date of birth: %s\n", c->text);
     484        }
     485
    526486        /* Slightly alternative use of for... ;-) */
    527         for( c = vc->children; ( c = xt_find_node( c, "EMAIL" ) ); c = c->next )
    528         {
    529                 if( ( sc = xt_find_node( c->children, "USERID" ) ) == NULL || sc->text_len == 0 )
     487        for (c = vc->children; (c = xt_find_node(c, "EMAIL")); c = c->next) {
     488                if ((sc = xt_find_node(c->children, "USERID")) == NULL || sc->text_len == 0) {
    530489                        continue;
    531                
    532                 if( xt_find_node( c->children, "HOME" ) )
     490                }
     491
     492                if (xt_find_node(c->children, "HOME")) {
    533493                        s = "Home";
    534                 else if( xt_find_node( c->children, "WORK" ) )
     494                } else if (xt_find_node(c->children, "WORK")) {
    535495                        s = "Work";
    536                 else
     496                } else {
    537497                        s = "Misc.";
    538                
    539                 g_string_append_printf( reply, "%s e-mail address: %s\n", s, sc->text );
    540         }
    541        
    542         if( ( c = xt_find_node( vc->children, "URL" ) ) && c->text_len )
    543                 g_string_append_printf( reply, "Homepage: %s\n", c->text );
    544        
     498                }
     499
     500                g_string_append_printf(reply, "%s e-mail address: %s\n", s, sc->text);
     501        }
     502
     503        if ((c = xt_find_node(vc->children, "URL")) && c->text_len) {
     504                g_string_append_printf(reply, "Homepage: %s\n", c->text);
     505        }
     506
    545507        /* Slightly alternative use of for... ;-) */
    546         for( c = vc->children; ( c = xt_find_node( c, "ADR" ) ); c = c->next )
    547         {
    548                 if( xt_find_node( c->children, "HOME" ) )
     508        for (c = vc->children; (c = xt_find_node(c, "ADR")); c = c->next) {
     509                if (xt_find_node(c->children, "HOME")) {
    549510                        s = "Home";
    550                 else if( xt_find_node( c->children, "WORK" ) )
     511                } else if (xt_find_node(c->children, "WORK")) {
    551512                        s = "Work";
    552                 else
     513                } else {
    553514                        s = "Misc.";
    554                
    555                 g_string_append_printf( reply, "%s address: ", s );
    556                
    557                 if( ( sc = xt_find_node( c->children, "STREET" ) ) && sc->text_len )
    558                         g_string_append_printf( reply, "%s ", sc->text );
    559                 if( ( sc = xt_find_node( c->children, "EXTADR" ) ) && sc->text_len )
    560                         g_string_append_printf( reply, "%s, ", sc->text );
    561                 if( ( sc = xt_find_node( c->children, "PCODE" ) ) && sc->text_len )
    562                         g_string_append_printf( reply, "%s, ", sc->text );
    563                 if( ( sc = xt_find_node( c->children, "LOCALITY" ) ) && sc->text_len )
    564                         g_string_append_printf( reply, "%s, ", sc->text );
    565                 if( ( sc = xt_find_node( c->children, "REGION" ) ) && sc->text_len )
    566                         g_string_append_printf( reply, "%s, ", sc->text );
    567                 if( ( sc = xt_find_node( c->children, "CTRY" ) ) && sc->text_len )
    568                         g_string_append_printf( reply, "%s", sc->text );
    569                
    570                 if( reply->str[reply->len-2] == ',' )
    571                         reply = g_string_truncate( reply, reply->len-2 );
    572                
    573                 reply = g_string_append_c( reply, '\n' );
    574         }
    575        
    576         for( c = vc->children; ( c = xt_find_node( c, "TEL" ) ); c = c->next )
    577         {
    578                 if( ( sc = xt_find_node( c->children, "NUMBER" ) ) == NULL || sc->text_len == 0 )
     515                }
     516
     517                g_string_append_printf(reply, "%s address: ", s);
     518
     519                if ((sc = xt_find_node(c->children, "STREET")) && sc->text_len) {
     520                        g_string_append_printf(reply, "%s ", sc->text);
     521                }
     522                if ((sc = xt_find_node(c->children, "EXTADR")) && sc->text_len) {
     523                        g_string_append_printf(reply, "%s, ", sc->text);
     524                }
     525                if ((sc = xt_find_node(c->children, "PCODE")) && sc->text_len) {
     526                        g_string_append_printf(reply, "%s, ", sc->text);
     527                }
     528                if ((sc = xt_find_node(c->children, "LOCALITY")) && sc->text_len) {
     529                        g_string_append_printf(reply, "%s, ", sc->text);
     530                }
     531                if ((sc = xt_find_node(c->children, "REGION")) && sc->text_len) {
     532                        g_string_append_printf(reply, "%s, ", sc->text);
     533                }
     534                if ((sc = xt_find_node(c->children, "CTRY")) && sc->text_len) {
     535                        g_string_append_printf(reply, "%s", sc->text);
     536                }
     537
     538                if (reply->str[reply->len - 2] == ',') {
     539                        reply = g_string_truncate(reply, reply->len - 2);
     540                }
     541
     542                reply = g_string_append_c(reply, '\n');
     543        }
     544
     545        for (c = vc->children; (c = xt_find_node(c, "TEL")); c = c->next) {
     546                if ((sc = xt_find_node(c->children, "NUMBER")) == NULL || sc->text_len == 0) {
    579547                        continue;
    580                
    581                 if( xt_find_node( c->children, "HOME" ) )
     548                }
     549
     550                if (xt_find_node(c->children, "HOME")) {
    582551                        s = "Home";
    583                 else if( xt_find_node( c->children, "WORK" ) )
     552                } else if (xt_find_node(c->children, "WORK")) {
    584553                        s = "Work";
    585                 else
     554                } else {
    586555                        s = "Misc.";
    587                
    588                 g_string_append_printf( reply, "%s phone number: %s\n", s, sc->text );
    589         }
    590        
    591         if( ( c = xt_find_node( vc->children, "DESC" ) ) && c->text_len )
    592                 g_string_append_printf( reply, "Other information:\n%s", c->text );
    593        
     556                }
     557
     558                g_string_append_printf(reply, "%s phone number: %s\n", s, sc->text);
     559        }
     560
     561        if ((c = xt_find_node(vc->children, "DESC")) && c->text_len) {
     562                g_string_append_printf(reply, "Other information:\n%s", c->text);
     563        }
     564
    594565        /* *sigh* */
    595        
    596         imcb_log( ic, "%s", reply->str );
    597         g_string_free( reply, TRUE );
    598        
    599         return XT_HANDLED;
    600 }
    601 
    602 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    603 
    604 int jabber_add_to_roster( struct im_connection *ic, const char *handle, const char *name, const char *group )
     566
     567        imcb_log(ic, "%s", reply->str);
     568        g_string_free(reply, TRUE);
     569
     570        return XT_HANDLED;
     571}
     572
     573static xt_status jabber_add_to_roster_callback(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     574
     575int jabber_add_to_roster(struct im_connection *ic, const char *handle, const char *name, const char *group)
    605576{
    606577        struct xt_node *node;
    607578        int st;
    608        
     579
    609580        /* Build the item entry */
    610         node = xt_new_node( "item", NULL, NULL );
    611         xt_add_attr( node, "jid", handle );
    612         if( name )
    613                 xt_add_attr( node, "name", name );
    614         if( group )
    615                 xt_add_child( node, xt_new_node( "group", group, NULL ) );
    616        
     581        node = xt_new_node("item", NULL, NULL);
     582        xt_add_attr(node, "jid", handle);
     583        if (name) {
     584                xt_add_attr(node, "name", name);
     585        }
     586        if (group) {
     587                xt_add_child(node, xt_new_node("group", group, NULL));
     588        }
     589
    617590        /* And pack it into a roster-add packet */
    618         node = xt_new_node( "query", NULL, node );
    619         xt_add_attr( node, "xmlns", XMLNS_ROSTER );
    620         node = jabber_make_packet( "iq", "set", NULL, node );
    621         jabber_cache_add( ic, node, jabber_add_to_roster_callback );
    622        
    623         st = jabber_write_packet( ic, node );
    624        
     591        node = xt_new_node("query", NULL, node);
     592        xt_add_attr(node, "xmlns", XMLNS_ROSTER);
     593        node = jabber_make_packet("iq", "set", NULL, node);
     594        jabber_cache_add(ic, node, jabber_add_to_roster_callback);
     595
     596        st = jabber_write_packet(ic, node);
     597
    625598        return st;
    626599}
    627600
    628 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     601static xt_status jabber_add_to_roster_callback(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    629602{
    630603        char *s, *jid = NULL;
    631604        struct xt_node *c;
    632        
    633         if( ( c = xt_find_node( orig->children, "query" ) ) &&
    634             ( c = xt_find_node( c->children, "item" ) ) &&
    635             ( jid = xt_find_attr( c, "jid" ) ) &&
    636             ( s = xt_find_attr( node, "type" ) ) &&
    637             strcmp( s, "result" ) == 0 )
    638         {
    639                 if( bee_user_by_handle( ic->bee, ic, jid ) == NULL )
    640                         imcb_add_buddy( ic, jid, NULL );
    641         }
    642         else
    643         {
    644                 imcb_log( ic, "Error while adding `%s' to your contact list.",
    645                           jid ? jid : "(unknown handle)" );
    646         }
    647        
    648         return XT_HANDLED;
    649 }
    650 
    651 int jabber_remove_from_roster( struct im_connection *ic, char *handle )
     605
     606        if ((c = xt_find_node(orig->children, "query")) &&
     607            (c = xt_find_node(c->children, "item")) &&
     608            (jid = xt_find_attr(c, "jid")) &&
     609            (s = xt_find_attr(node, "type")) &&
     610            strcmp(s, "result") == 0) {
     611                if (bee_user_by_handle(ic->bee, ic, jid) == NULL) {
     612                        imcb_add_buddy(ic, jid, NULL);
     613                }
     614        } else {
     615                imcb_log(ic, "Error while adding `%s' to your contact list.",
     616                         jid ? jid : "(unknown handle)");
     617        }
     618
     619        return XT_HANDLED;
     620}
     621
     622int jabber_remove_from_roster(struct im_connection *ic, char *handle)
    652623{
    653624        struct xt_node *node;
    654625        int st;
    655        
     626
    656627        /* Build the item entry */
    657         node = xt_new_node( "item", NULL, NULL );
    658         xt_add_attr( node, "jid", handle );
    659         xt_add_attr( node, "subscription", "remove" );
    660        
     628        node = xt_new_node("item", NULL, NULL);
     629        xt_add_attr(node, "jid", handle);
     630        xt_add_attr(node, "subscription", "remove");
     631
    661632        /* And pack it into a roster-add packet */
    662         node = xt_new_node( "query", NULL, node );
    663         xt_add_attr( node, "xmlns", XMLNS_ROSTER );
    664         node = jabber_make_packet( "iq", "set", NULL, node );
    665        
    666         st = jabber_write_packet( ic, node );
    667        
    668         xt_free_node( node );
     633        node = xt_new_node("query", NULL, node);
     634        xt_add_attr(node, "xmlns", XMLNS_ROSTER);
     635        node = jabber_make_packet("iq", "set", NULL, node);
     636
     637        st = jabber_write_packet(ic, node);
     638
     639        xt_free_node(node);
    669640        return st;
    670641}
    671642
    672 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    673 
    674 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid )
     643xt_status jabber_iq_parse_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     644
     645xt_status jabber_iq_query_features(struct im_connection *ic, char *bare_jid)
    675646{
    676647        struct xt_node *node, *query;
    677648        struct jabber_buddy *bud;
    678        
    679         if( ( bud = jabber_buddy_by_jid( ic, bare_jid , 0 ) ) == NULL )
    680         {
     649
     650        if ((bud = jabber_buddy_by_jid(ic, bare_jid, 0)) == NULL) {
    681651                /* Who cares about the unknown... */
    682                 imcb_log( ic, "Couldn't find buddy: %s", bare_jid);
    683                 return XT_HANDLED;
    684         }
    685        
    686         if( bud->features ) /* been here already */
    687                 return XT_HANDLED;
    688        
    689         node = xt_new_node( "query", NULL, NULL );
    690         xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO );
    691        
    692         if( !( query = jabber_make_packet( "iq", "get", bare_jid, node ) ) )
    693         {
    694                 imcb_log( ic, "WARNING: Couldn't generate feature query" );
    695                 xt_free_node( node );
    696                 return XT_HANDLED;
    697         }
    698 
    699         jabber_cache_add( ic, query, jabber_iq_parse_features );
    700 
    701         return jabber_write_packet( ic, query ) ? XT_HANDLED : XT_ABORT;
    702 }
    703 
    704 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     652                imcb_log(ic, "Couldn't find buddy: %s", bare_jid);
     653                return XT_HANDLED;
     654        }
     655
     656        if (bud->features) { /* been here already */
     657                return XT_HANDLED;
     658        }
     659
     660        node = xt_new_node("query", NULL, NULL);
     661        xt_add_attr(node, "xmlns", XMLNS_DISCO_INFO);
     662
     663        if (!(query = jabber_make_packet("iq", "get", bare_jid, node))) {
     664                imcb_log(ic, "WARNING: Couldn't generate feature query");
     665                xt_free_node(node);
     666                return XT_HANDLED;
     667        }
     668
     669        jabber_cache_add(ic, query, jabber_iq_parse_features);
     670
     671        return jabber_write_packet(ic, query) ? XT_HANDLED : XT_ABORT;
     672}
     673
     674xt_status jabber_iq_parse_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    705675{
    706676        struct xt_node *c;
     
    708678        char *feature, *xmlns, *from;
    709679
    710         if( !( from = xt_find_attr( node, "from" ) ) ||
    711             !( c = xt_find_node( node->children, "query" ) ) ||
    712             !( xmlns = xt_find_attr( c, "xmlns" ) ) ||
    713             !( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 ) )
    714         {
    715                 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" );
    716                 return XT_HANDLED;
    717         }
    718         if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL )
    719         {
     680        if (!(from = xt_find_attr(node, "from")) ||
     681            !(c = xt_find_node(node->children, "query")) ||
     682            !(xmlns = xt_find_attr(c, "xmlns")) ||
     683            !(strcmp(xmlns, XMLNS_DISCO_INFO) == 0)) {
     684                imcb_log(ic, "WARNING: Received incomplete IQ-result packet for discover");
     685                return XT_HANDLED;
     686        }
     687        if ((bud = jabber_buddy_by_jid(ic, from, 0)) == NULL) {
    720688                /* Who cares about the unknown... */
    721                 imcb_log( ic, "Couldn't find buddy: %s", from );
    722                 return XT_HANDLED;
    723         }
    724        
     689                imcb_log(ic, "Couldn't find buddy: %s", from);
     690                return XT_HANDLED;
     691        }
     692
    725693        c = c->children;
    726         while( ( c = xt_find_node( c, "feature" ) ) )
    727         {
    728                 feature = xt_find_attr( c, "var" );
    729                 if( feature )
    730                         bud->features = g_slist_append( bud->features, g_strdup( feature ) );
     694        while ((c = xt_find_node(c, "feature"))) {
     695                feature = xt_find_attr(c, "var");
     696                if (feature) {
     697                        bud->features = g_slist_append(bud->features, g_strdup(feature));
     698                }
    731699                c = c->next;
    732700        }
     
    735703}
    736704
    737 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    738 
    739 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns )
     705xt_status jabber_iq_parse_server_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     706
     707xt_status jabber_iq_query_server(struct im_connection *ic, char *jid, char *xmlns)
    740708{
    741709        struct xt_node *node, *query;
    742710        struct jabber_data *jd = ic->proto_data;
    743        
    744         node = xt_new_node( "query", NULL, NULL );
    745         xt_add_attr( node, "xmlns", xmlns );
    746        
    747         if( !( query = jabber_make_packet( "iq", "get", jid, node ) ) )
    748         {
    749                 imcb_log( ic, "WARNING: Couldn't generate server query" );
    750                 xt_free_node( node );
     711
     712        node = xt_new_node("query", NULL, NULL);
     713        xt_add_attr(node, "xmlns", xmlns);
     714
     715        if (!(query = jabber_make_packet("iq", "get", jid, node))) {
     716                imcb_log(ic, "WARNING: Couldn't generate server query");
     717                xt_free_node(node);
    751718        }
    752719
    753720        jd->have_streamhosts--;
    754         jabber_cache_add( ic, query, jabber_iq_parse_server_features );
    755 
    756         return jabber_write_packet( ic, query ) ? XT_HANDLED : XT_ABORT;
     721        jabber_cache_add(ic, query, jabber_iq_parse_server_features);
     722
     723        return jabber_write_packet(ic, query) ? XT_HANDLED : XT_ABORT;
    757724}
    758725
     
    760727 * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info
    761728 */
    762 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     729xt_status jabber_iq_parse_server_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    763730{
    764731        struct xt_node *c;
     
    766733        char *xmlns, *from;
    767734
    768         if( !( c = xt_find_node( node->children, "query" ) ) ||
    769             !( from = xt_find_attr( node, "from" ) ) ||
    770             !( xmlns = xt_find_attr( c, "xmlns" ) ) )
    771         {
    772                 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" );
     735        if (!(c = xt_find_node(node->children, "query")) ||
     736            !(from = xt_find_attr(node, "from")) ||
     737            !(xmlns = xt_find_attr(c, "xmlns"))) {
     738                imcb_log(ic, "WARNING: Received incomplete IQ-result packet for discover");
    773739                return XT_HANDLED;
    774740        }
     
    776742        jd->have_streamhosts++;
    777743
    778         if( strcmp( xmlns, XMLNS_DISCO_ITEMS ) == 0 )
    779         {
     744        if (strcmp(xmlns, XMLNS_DISCO_ITEMS) == 0) {
    780745                char *itemjid;
    781746
    782747                /* answer from server */
    783        
     748
    784749                c = c->children;
    785                 while( ( c = xt_find_node( c, "item" ) ) )
    786                 {
    787                         itemjid = xt_find_attr( c, "jid" );
    788                        
    789                         if( itemjid )
    790                                 jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO );
     750                while ((c = xt_find_node(c, "item"))) {
     751                        itemjid = xt_find_attr(c, "jid");
     752
     753                        if (itemjid) {
     754                                jabber_iq_query_server(ic, itemjid, XMLNS_DISCO_INFO);
     755                        }
    791756
    792757                        c = c->next;
    793758                }
    794         }
    795         else if( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 )
    796         {
     759        } else if (strcmp(xmlns, XMLNS_DISCO_INFO) == 0) {
    797760                char *category, *type;
    798761
     
    800763
    801764                c = c->children;
    802                 while( ( c = xt_find_node( c, "identity" ) ) )
    803                 {
    804                         category = xt_find_attr( c, "category" );
    805                         type = xt_find_attr( c, "type" );
    806 
    807                         if( type && ( strcmp( type, "bytestreams" ) == 0 ) &&
    808                             category && ( strcmp( category, "proxy" ) == 0 ) )
    809                                 jabber_iq_query_server( ic, from, XMLNS_BYTESTREAMS );
     765                while ((c = xt_find_node(c, "identity"))) {
     766                        category = xt_find_attr(c, "category");
     767                        type = xt_find_attr(c, "type");
     768
     769                        if (type && (strcmp(type, "bytestreams") == 0) &&
     770                            category && (strcmp(category, "proxy") == 0)) {
     771                                jabber_iq_query_server(ic, from, XMLNS_BYTESTREAMS);
     772                        }
    810773
    811774                        c = c->next;
    812775                }
    813         }
    814         else if( strcmp( xmlns, XMLNS_BYTESTREAMS ) == 0 )
    815         {
     776        } else if (strcmp(xmlns, XMLNS_BYTESTREAMS) == 0) {
    816777                char *host, *jid, *port_s;
    817778                int port;
     
    819780                /* answer from proxy */
    820781
    821                 if( ( c = xt_find_node( c->children, "streamhost" ) ) &&
    822                     ( host = xt_find_attr( c, "host" ) ) &&
    823                     ( port_s = xt_find_attr( c, "port" ) ) &&
    824                     ( sscanf( port_s, "%d", &port ) == 1 ) &&
    825                     ( jid = xt_find_attr( c, "jid" ) ) )
    826                 {
    827                         jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 );
    828                        
    829                         sh->jid = g_strdup( jid );
    830                         sh->host = g_strdup( host );
    831                         g_snprintf( sh->port, sizeof( sh->port ), "%u", port );
    832 
    833                         imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port );
    834                         jd->streamhosts = g_slist_append( jd->streamhosts, sh );
    835                 }
    836         }
    837 
    838         if( jd->have_streamhosts == 0 )
     782                if ((c = xt_find_node(c->children, "streamhost")) &&
     783                    (host = xt_find_attr(c, "host")) &&
     784                    (port_s = xt_find_attr(c, "port")) &&
     785                    (sscanf(port_s, "%d", &port) == 1) &&
     786                    (jid = xt_find_attr(c, "jid"))) {
     787                        jabber_streamhost_t *sh = g_new0(jabber_streamhost_t, 1);
     788
     789                        sh->jid = g_strdup(jid);
     790                        sh->host = g_strdup(host);
     791                        g_snprintf(sh->port, sizeof(sh->port), "%u", port);
     792
     793                        imcb_log(ic, "Proxy found: jid %s host %s port %u", jid, host, port);
     794                        jd->streamhosts = g_slist_append(jd->streamhosts, sh);
     795                }
     796        }
     797
     798        if (jd->have_streamhosts == 0) {
    839799                jd->have_streamhosts++;
    840 
    841         return XT_HANDLED;
    842 }
    843 
    844 static xt_status jabber_iq_version_response( struct im_connection *ic,
    845         struct xt_node *node, struct xt_node *orig );
    846 
    847 void jabber_iq_version_send( struct im_connection *ic, struct jabber_buddy *bud, void *data )
     800        }
     801
     802        return XT_HANDLED;
     803}
     804
     805static xt_status jabber_iq_version_response(struct im_connection *ic,
     806                                            struct xt_node *node, struct xt_node *orig);
     807
     808void jabber_iq_version_send(struct im_connection *ic, struct jabber_buddy *bud, void *data)
    848809{
    849810        struct xt_node *node, *query;
    850        
    851         node = xt_new_node( "query", NULL, NULL );
    852         xt_add_attr( node, "xmlns", XMLNS_VERSION );
    853         query = jabber_make_packet( "iq", "get", bud->full_jid, node );
    854         jabber_cache_add( ic, query, jabber_iq_version_response );
    855 
    856         jabber_write_packet( ic, query );
    857 }
    858 
    859 static xt_status jabber_iq_version_response( struct im_connection *ic,
    860         struct xt_node *node, struct xt_node *orig )
     811
     812        node = xt_new_node("query", NULL, NULL);
     813        xt_add_attr(node, "xmlns", XMLNS_VERSION);
     814        query = jabber_make_packet("iq", "get", bud->full_jid, node);
     815        jabber_cache_add(ic, query, jabber_iq_version_response);
     816
     817        jabber_write_packet(ic, query);
     818}
     819
     820static xt_status jabber_iq_version_response(struct im_connection *ic,
     821                                            struct xt_node *node, struct xt_node *orig)
    861822{
    862823        struct xt_node *query;
     
    866827        bee_user_t *bu;
    867828        struct jabber_buddy *bud = NULL;
    868        
    869         if( ( s = xt_find_attr( node, "from" ) ) &&
    870             ( bud = jabber_buddy_by_jid( ic, s, 0 ) ) &&
    871             ( query = xt_find_node( node->children, "query" ) ) &&
    872             ( bu = bee_user_by_handle( ic->bee, ic, bud->bare_jid ) ) )
    873         {
    874                 rets = g_string_new( "Resource " );
    875                 g_string_append( rets, bud->resource );
    876         }
    877         else
    878                 return XT_HANDLED;
    879        
    880         for( query = query->children; query; query = query->next )
    881                 if( query->text_len > 0 )
    882                         g_string_append_printf( rets, " %s: %s,", query->name, query->text );
    883        
    884         g_string_truncate( rets, rets->len - 1 );
     829
     830        if ((s = xt_find_attr(node, "from")) &&
     831            (bud = jabber_buddy_by_jid(ic, s, 0)) &&
     832            (query = xt_find_node(node->children, "query")) &&
     833            (bu = bee_user_by_handle(ic->bee, ic, bud->bare_jid))) {
     834                rets = g_string_new("Resource ");
     835                g_string_append(rets, bud->resource);
     836        } else {
     837                return XT_HANDLED;
     838        }
     839
     840        for (query = query->children; query; query = query->next) {
     841                if (query->text_len > 0) {
     842                        g_string_append_printf(rets, " %s: %s,", query->name, query->text);
     843                }
     844        }
     845
     846        g_string_truncate(rets, rets->len - 1);
    885847        ret[0] = rets->str;
    886         imcb_buddy_action_response( bu, "VERSION", ret, NULL );
    887         g_string_free( rets, TRUE );
    888        
    889         return XT_HANDLED;
    890 }
    891 
    892 static xt_status jabber_iq_disco_server_response( struct im_connection *ic,
    893         struct xt_node *node, struct xt_node *orig );
    894 
    895 static int jabber_iq_disco_server( struct im_connection *ic )
     848        imcb_buddy_action_response(bu, "VERSION", ret, NULL);
     849        g_string_free(rets, TRUE);
     850
     851        return XT_HANDLED;
     852}
     853
     854static xt_status jabber_iq_disco_server_response(struct im_connection *ic,
     855                                                 struct xt_node *node, struct xt_node *orig);
     856
     857static int jabber_iq_disco_server(struct im_connection *ic)
    896858{
    897859        struct xt_node *node, *iq;
    898860        struct jabber_data *jd = ic->proto_data;
    899        
    900         node = xt_new_node( "query", NULL, NULL );
    901         xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO );
    902         iq = jabber_make_packet( "iq", "get", jd->server, node );
    903        
    904         jabber_cache_add( ic, iq, jabber_iq_disco_server_response );
    905         return jabber_write_packet( ic, iq );
    906 }
    907 
    908 static xt_status jabber_iq_disco_server_response( struct im_connection *ic,
    909         struct xt_node *node, struct xt_node *orig )
     861
     862        node = xt_new_node("query", NULL, NULL);
     863        xt_add_attr(node, "xmlns", XMLNS_DISCO_INFO);
     864        iq = jabber_make_packet("iq", "get", jd->server, node);
     865
     866        jabber_cache_add(ic, iq, jabber_iq_disco_server_response);
     867        return jabber_write_packet(ic, iq);
     868}
     869
     870static xt_status jabber_iq_disco_server_response(struct im_connection *ic,
     871                                                 struct xt_node *node, struct xt_node *orig)
    910872{
    911873        struct jabber_data *jd = ic->proto_data;
    912874        struct xt_node *id;
    913        
    914         if( ( id = xt_find_path( node, "query/identity" ) ) )
    915         {
     875
     876        if ((id = xt_find_path(node, "query/identity"))) {
    916877                char *cat, *type, *name;
    917                
    918                 if( !( cat = xt_find_attr( id, "category" ) ) ||
    919                     !( type = xt_find_attr( id, "type" ) ) ||
    920                     !( name = xt_find_attr( id, "name" ) ) )
     878
     879                if (!(cat = xt_find_attr(id, "category")) ||
     880                    !(type = xt_find_attr(id, "type")) ||
     881                    !(name = xt_find_attr(id, "name"))) {
    921882                        return XT_HANDLED;
    922                
    923                 if( strcmp( cat, "server" ) == 0 && strcmp( type, "im" ) == 0 &&
    924                     strstr( name, "Google" ) != NULL )
     883                }
     884
     885                if (strcmp(cat, "server") == 0 && strcmp(type, "im") == 0 &&
     886                    strstr(name, "Google") != NULL) {
    925887                        jd->flags |= JFLAG_GTALK;
    926         }
    927        
    928         return XT_HANDLED;
    929 }
     888                }
     889        }
     890
     891        return XT_HANDLED;
     892}
  • protocols/jabber/jabber.c

    raf359b4 r5ebff60  
    5454};
    5555
    56 static void jabber_init( account_t *acc )
     56static void jabber_init(account_t *acc)
    5757{
    5858        set_t *s;
    5959        char str[16];
    60        
    61         s = set_add( &acc->set, "activity_timeout", "600", set_eval_int, acc );
    62        
    63         s = set_add( &acc->set, "oauth", "false", set_eval_oauth, acc );
    64 
    65         s = set_add( &acc->set, "display_name", NULL, NULL, acc );
    66        
    67         g_snprintf( str, sizeof( str ), "%d", jabber_port_list[0] );
    68         s = set_add( &acc->set, "port", str, set_eval_int, acc );
     60
     61        s = set_add(&acc->set, "activity_timeout", "600", set_eval_int, acc);
     62
     63        s = set_add(&acc->set, "oauth", "false", set_eval_oauth, acc);
     64
     65        s = set_add(&acc->set, "display_name", NULL, NULL, acc);
     66
     67        g_snprintf(str, sizeof(str), "%d", jabber_port_list[0]);
     68        s = set_add(&acc->set, "port", str, set_eval_int, acc);
    6969        s->flags |= ACC_SET_OFFLINE_ONLY;
    70        
    71         s = set_add( &acc->set, "priority", "0", set_eval_priority, acc );
    72 
    73         s = set_add( &acc->set, "proxy", "<local>;<auto>", NULL, acc );
    74        
    75         s = set_add( &acc->set, "resource", "BitlBee", NULL, acc );
     70
     71        s = set_add(&acc->set, "priority", "0", set_eval_priority, acc);
     72
     73        s = set_add(&acc->set, "proxy", "<local>;<auto>", NULL, acc);
     74
     75        s = set_add(&acc->set, "resource", "BitlBee", NULL, acc);
    7676        s->flags |= ACC_SET_OFFLINE_ONLY;
    77        
    78         s = set_add( &acc->set, "resource_select", "activity", NULL, acc );
    79        
    80         s = set_add( &acc->set, "sasl", "true", set_eval_bool, acc );
     77
     78        s = set_add(&acc->set, "resource_select", "activity", NULL, acc);
     79
     80        s = set_add(&acc->set, "sasl", "true", set_eval_bool, acc);
    8181        s->flags |= ACC_SET_OFFLINE_ONLY | SET_HIDDEN_DEFAULT;
    82        
    83         s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
     82
     83        s = set_add(&acc->set, "server", NULL, set_eval_account, acc);
    8484        s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK;
    85        
    86         s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc );
     85
     86        s = set_add(&acc->set, "ssl", "false", set_eval_bool, acc);
    8787        s->flags |= ACC_SET_OFFLINE_ONLY;
    88        
    89         s = set_add( &acc->set, "tls", "true", set_eval_tls, acc );
     88
     89        s = set_add(&acc->set, "tls", "true", set_eval_tls, acc);
    9090        s->flags |= ACC_SET_OFFLINE_ONLY;
    91        
    92         s = set_add( &acc->set, "tls_verify", "true", set_eval_bool, acc );
     91
     92        s = set_add(&acc->set, "tls_verify", "true", set_eval_bool, acc);
    9393        s->flags |= ACC_SET_OFFLINE_ONLY;
    9494
    95         s = set_add( &acc->set, "user_agent", "BitlBee", NULL, acc );
    96        
    97         s = set_add( &acc->set, "xmlconsole", "false", set_eval_bool, acc );
     95        s = set_add(&acc->set, "user_agent", "BitlBee", NULL, acc);
     96
     97        s = set_add(&acc->set, "xmlconsole", "false", set_eval_bool, acc);
    9898        s->flags |= ACC_SET_OFFLINE_ONLY;
    99        
     99
    100100        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
    101101                      ACC_FLAG_HANDLE_DOMAINS;
    102102}
    103103
    104 static void jabber_generate_id_hash( struct jabber_data *jd );
    105 
    106 static void jabber_login( account_t *acc )
    107 {
    108         struct im_connection *ic = imcb_new( acc );
    109         struct jabber_data *jd = g_new0( struct jabber_data, 1 );
     104static void jabber_generate_id_hash(struct jabber_data *jd);
     105
     106static void jabber_login(account_t *acc)
     107{
     108        struct im_connection *ic = imcb_new(acc);
     109        struct jabber_data *jd = g_new0(struct jabber_data, 1);
    110110        char *s;
    111        
     111
    112112        /* For now this is needed in the _connected() handlers if using
    113113           GLib event handling, to make sure we're not handling events
    114114           on dead connections. */
    115         jabber_connections = g_slist_prepend( jabber_connections, ic );
    116        
     115        jabber_connections = g_slist_prepend(jabber_connections, ic);
     116
    117117        jd->ic = ic;
    118118        ic->proto_data = jd;
    119        
    120         jabber_set_me( ic, acc->user );
    121        
     119
     120        jabber_set_me(ic, acc->user);
     121
    122122        jd->fd = jd->r_inpa = jd->w_inpa = -1;
    123        
    124         if( jd->server == NULL )
    125         {
    126                 imcb_error( ic, "Incomplete account name (format it like <username@jabberserver.name>)" );
    127                 imc_logout( ic, FALSE );
     123
     124        if (jd->server == NULL) {
     125                imcb_error(ic, "Incomplete account name (format it like <username@jabberserver.name>)");
     126                imc_logout(ic, FALSE);
    128127                return;
    129128        }
    130        
    131         if( ( s = strchr( jd->server, '/' ) ) )
    132         {
     129
     130        if ((s = strchr(jd->server, '/'))) {
    133131                *s = 0;
    134                 set_setstr( &acc->set, "resource", s + 1 );
    135                
     132                set_setstr(&acc->set, "resource", s + 1);
     133
    136134                /* Also remove the /resource from the original variable so we
    137135                   won't have to do this again every time. */
    138                 s = strchr( acc->user, '/' );
     136                s = strchr(acc->user, '/');
    139137                *s = 0;
    140138        }
    141        
    142         jd->node_cache = g_hash_table_new_full( g_str_hash, g_str_equal, NULL, jabber_cache_entry_free );
    143         jd->buddies = g_hash_table_new( g_str_hash, g_str_equal );
    144        
    145         if( set_getbool( &acc->set, "oauth" ) )
    146         {
     139
     140        jd->node_cache = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, jabber_cache_entry_free);
     141        jd->buddies = g_hash_table_new(g_str_hash, g_str_equal);
     142
     143        if (set_getbool(&acc->set, "oauth")) {
    147144                GSList *p_in = NULL;
    148145                const char *tok;
    149                
     146
    150147                jd->fd = jd->r_inpa = jd->w_inpa = -1;
    151                
    152                 if( strstr( jd->server, ".facebook.com" ) )
     148
     149                if (strstr(jd->server, ".facebook.com")) {
    153150                        jd->oauth2_service = &oauth2_service_facebook;
    154                 else
     151                } else {
    155152                        jd->oauth2_service = &oauth2_service_google;
    156                
    157                 oauth_params_parse( &p_in, ic->acc->pass );
    158                
     153                }
     154
     155                oauth_params_parse(&p_in, ic->acc->pass);
     156
    159157                /* First see if we have a refresh token, in which case any
    160158                   access token we *might* have has probably expired already
    161159                   anyway. */
    162                 if( ( tok = oauth_params_get( &p_in, "refresh_token" ) ) )
    163                 {
    164                         sasl_oauth2_refresh( ic, tok );
     160                if ((tok = oauth_params_get(&p_in, "refresh_token"))) {
     161                        sasl_oauth2_refresh(ic, tok);
    165162                }
    166163                /* If we don't have a refresh token, let's hope the access
    167164                   token is still usable. */
    168                 else if( ( tok = oauth_params_get( &p_in, "access_token" ) ) )
    169                 {
    170                         jd->oauth2_access_token = g_strdup( tok );
    171                         jabber_connect( ic );
     165                else if ((tok = oauth_params_get(&p_in, "access_token"))) {
     166                        jd->oauth2_access_token = g_strdup(tok);
     167                        jabber_connect(ic);
    172168                }
    173169                /* If we don't have any, start the OAuth process now. Don't
    174170                   even open an XMPP connection yet. */
    175                 else
    176                 {
    177                         sasl_oauth2_init( ic );
     171                else {
     172                        sasl_oauth2_init(ic);
    178173                        ic->flags |= OPT_SLOW_LOGIN;
    179174                }
    180                
    181                 oauth_params_free( &p_in );
    182         }
    183         else
    184                 jabber_connect( ic );
     175
     176                oauth_params_free(&p_in);
     177        } else {
     178                jabber_connect(ic);
     179        }
    185180}
    186181
    187182/* Separate this from jabber_login() so we can do OAuth first if necessary.
    188183   Putting this in io.c would probably be more correct. */
    189 void jabber_connect( struct im_connection *ic )
     184void jabber_connect(struct im_connection *ic)
    190185{
    191186        account_t *acc = ic->acc;
     
    194189        char *connect_to;
    195190        struct ns_srv_reply **srvl = NULL, *srv = NULL;
    196        
     191
    197192        /* Figure out the hostname to connect to. */
    198         if( acc->server && *acc->server )
     193        if (acc->server && *acc->server) {
    199194                connect_to = acc->server;
    200         else if( ( srvl = srv_lookup( "xmpp-client", "tcp", jd->server ) ) ||
    201                  ( srvl = srv_lookup( "jabber-client", "tcp", jd->server ) ) )
    202         {
     195        } else if ((srvl = srv_lookup("xmpp-client", "tcp", jd->server)) ||
     196                   (srvl = srv_lookup("jabber-client", "tcp", jd->server))) {
    203197                /* Find the lowest-priority one. These usually come
    204198                   back in random/shuffled order. Not looking at
    205199                   weights etc for now. */
    206200                srv = *srvl;
    207                 for( i = 1; srvl[i]; i ++ )
    208                         if( srvl[i]->prio < srv->prio )
     201                for (i = 1; srvl[i]; i++) {
     202                        if (srvl[i]->prio < srv->prio) {
    209203                                srv = srvl[i];
    210                
     204                        }
     205                }
     206
    211207                connect_to = srv->name;
    212         }
    213         else
     208        } else {
    214209                connect_to = jd->server;
    215        
    216         imcb_log( ic, "Connecting" );
    217        
    218         for( i = 0; jabber_port_list[i] > 0; i ++ )
    219                 if( set_getint( &acc->set, "port" ) == jabber_port_list[i] )
     210        }
     211
     212        imcb_log(ic, "Connecting");
     213
     214        for (i = 0; jabber_port_list[i] > 0; i++) {
     215                if (set_getint(&acc->set, "port") == jabber_port_list[i]) {
    220216                        break;
    221 
    222         if( jabber_port_list[i] == 0 )
    223         {
    224                 imcb_log( ic, "Illegal port number" );
    225                 imc_logout( ic, FALSE );
     217                }
     218        }
     219
     220        if (jabber_port_list[i] == 0) {
     221                imcb_log(ic, "Illegal port number");
     222                imc_logout(ic, FALSE);
    226223                return;
    227224        }
    228        
     225
    229226        /* For non-SSL connections we can try to use the port # from the SRV
    230227           reply, but let's not do that when using SSL, SSL usually runs on
    231228           non-standard ports... */
    232         if( set_getbool( &acc->set, "ssl" ) )
    233         {
    234                 jd->ssl = ssl_connect( connect_to, set_getint( &acc->set, "port" ), set_getbool( &acc->set, "tls_verify" ), jabber_connected_ssl, ic );
    235                 jd->fd = jd->ssl ? ssl_getfd( jd->ssl ) : -1;
    236         }
    237         else
    238         {
    239                 jd->fd = proxy_connect( connect_to, srv ? srv->port : set_getint( &acc->set, "port" ), jabber_connected_plain, ic );
    240         }
    241         srv_free( srvl );
    242        
    243         if( jd->fd == -1 )
    244         {
    245                 imcb_error( ic, "Could not connect to server" );
    246                 imc_logout( ic, TRUE );
    247                
     229        if (set_getbool(&acc->set, "ssl")) {
     230                jd->ssl = ssl_connect(connect_to, set_getint(&acc->set, "port"), set_getbool(&acc->set,
     231                                                                                             "tls_verify"), jabber_connected_ssl,
     232                                      ic);
     233                jd->fd = jd->ssl ? ssl_getfd(jd->ssl) : -1;
     234        } else {
     235                jd->fd = proxy_connect(connect_to, srv ? srv->port : set_getint(&acc->set,
     236                                                                                "port"), jabber_connected_plain, ic);
     237        }
     238        srv_free(srvl);
     239
     240        if (jd->fd == -1) {
     241                imcb_error(ic, "Could not connect to server");
     242                imc_logout(ic, TRUE);
     243
    248244                return;
    249245        }
    250        
    251         if( set_getbool( &acc->set, "xmlconsole" ) )
    252         {
     246
     247        if (set_getbool(&acc->set, "xmlconsole")) {
    253248                jd->flags |= JFLAG_XMLCONSOLE;
    254249                /* Shouldn't really do this at this stage already, maybe. But
    255250                   I think this shouldn't break anything. */
    256                 imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
    257         }
    258        
    259         jabber_generate_id_hash( jd );
     251                imcb_add_buddy(ic, JABBER_XMLCONSOLE_HANDLE, NULL);
     252        }
     253
     254        jabber_generate_id_hash(jd);
    260255}
    261256
    262257/* This generates an unfinished md5_state_t variable. Every time we generate
    263258   an ID, we finish the state by adding a sequence number and take the hash. */
    264 static void jabber_generate_id_hash( struct jabber_data *jd )
     259static void jabber_generate_id_hash(struct jabber_data *jd)
    265260{
    266261        md5_byte_t binbuf[4];
    267262        char *s;
    268        
    269         md5_init( &jd->cached_id_prefix );
    270         md5_append( &jd->cached_id_prefix, (unsigned char *) jd->username, strlen( jd->username ) );
    271         md5_append( &jd->cached_id_prefix, (unsigned char *) jd->server, strlen( jd->server ) );
    272         s = set_getstr( &jd->ic->acc->set, "resource" );
    273         md5_append( &jd->cached_id_prefix, (unsigned char *) s, strlen( s ) );
    274         random_bytes( binbuf, 4 );
    275         md5_append( &jd->cached_id_prefix, binbuf, 4 );
    276 }
    277 
    278 static void jabber_logout( struct im_connection *ic )
    279 {
    280         struct jabber_data *jd = ic->proto_data;
    281        
    282         while( jd->filetransfers )
    283                 imcb_file_canceled( ic, ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" );
    284 
    285         while( jd->streamhosts )
    286         {
     263
     264        md5_init(&jd->cached_id_prefix);
     265        md5_append(&jd->cached_id_prefix, (unsigned char *) jd->username, strlen(jd->username));
     266        md5_append(&jd->cached_id_prefix, (unsigned char *) jd->server, strlen(jd->server));
     267        s = set_getstr(&jd->ic->acc->set, "resource");
     268        md5_append(&jd->cached_id_prefix, (unsigned char *) s, strlen(s));
     269        random_bytes(binbuf, 4);
     270        md5_append(&jd->cached_id_prefix, binbuf, 4);
     271}
     272
     273static void jabber_logout(struct im_connection *ic)
     274{
     275        struct jabber_data *jd = ic->proto_data;
     276
     277        while (jd->filetransfers) {
     278                imcb_file_canceled(ic, (( struct jabber_transfer *) jd->filetransfers->data)->ft, "Logging out");
     279        }
     280
     281        while (jd->streamhosts) {
    287282                jabber_streamhost_t *sh = jd->streamhosts->data;
    288                 jd->streamhosts = g_slist_remove( jd->streamhosts, sh );
    289                 g_free( sh->jid );
    290                 g_free( sh->host );
    291                 g_free( sh );
    292         }
    293 
    294         if( jd->fd >= 0 )
    295                 jabber_end_stream( ic );
    296        
    297         while( ic->groupchats )
    298                 jabber_chat_free( ic->groupchats->data );
    299        
    300         if( jd->r_inpa >= 0 )
    301                 b_event_remove( jd->r_inpa );
    302         if( jd->w_inpa >= 0 )
    303                 b_event_remove( jd->w_inpa );
    304        
    305         if( jd->ssl )
    306                 ssl_disconnect( jd->ssl );
    307         if( jd->fd >= 0 )
    308                 closesocket( jd->fd );
    309        
    310         if( jd->tx_len )
    311                 g_free( jd->txq );
    312        
    313         if( jd->node_cache )
    314                 g_hash_table_destroy( jd->node_cache );
    315        
    316         jabber_buddy_remove_all( ic );
    317        
    318         xt_free( jd->xt );
    319 
    320         md5_free( &jd->cached_id_prefix );
    321        
    322         g_free( jd->oauth2_access_token );
    323         g_free( jd->away_message );
    324         g_free( jd->internal_jid );
    325         g_free( jd->username );
    326         g_free( jd->me );
    327         g_free( jd );
    328        
    329         jabber_connections = g_slist_remove( jabber_connections, ic );
    330 }
    331 
    332 static int jabber_buddy_msg( struct im_connection *ic, char *who, char *message, int flags )
     283                jd->streamhosts = g_slist_remove(jd->streamhosts, sh);
     284                g_free(sh->jid);
     285                g_free(sh->host);
     286                g_free(sh);
     287        }
     288
     289        if (jd->fd >= 0) {
     290                jabber_end_stream(ic);
     291        }
     292
     293        while (ic->groupchats) {
     294                jabber_chat_free(ic->groupchats->data);
     295        }
     296
     297        if (jd->r_inpa >= 0) {
     298                b_event_remove(jd->r_inpa);
     299        }
     300        if (jd->w_inpa >= 0) {
     301                b_event_remove(jd->w_inpa);
     302        }
     303
     304        if (jd->ssl) {
     305                ssl_disconnect(jd->ssl);
     306        }
     307        if (jd->fd >= 0) {
     308                closesocket(jd->fd);
     309        }
     310
     311        if (jd->tx_len) {
     312                g_free(jd->txq);
     313        }
     314
     315        if (jd->node_cache) {
     316                g_hash_table_destroy(jd->node_cache);
     317        }
     318
     319        jabber_buddy_remove_all(ic);
     320
     321        xt_free(jd->xt);
     322
     323        md5_free(&jd->cached_id_prefix);
     324
     325        g_free(jd->oauth2_access_token);
     326        g_free(jd->away_message);
     327        g_free(jd->internal_jid);
     328        g_free(jd->username);
     329        g_free(jd->me);
     330        g_free(jd);
     331
     332        jabber_connections = g_slist_remove(jabber_connections, ic);
     333}
     334
     335static int jabber_buddy_msg(struct im_connection *ic, char *who, char *message, int flags)
    333336{
    334337        struct jabber_data *jd = ic->proto_data;
     
    337340        char *s;
    338341        int st;
    339        
    340         if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
    341                 return jabber_write( ic, message, strlen( message ) );
    342        
    343         if( g_strcasecmp( who, JABBER_OAUTH_HANDLE ) == 0 &&
    344             !( jd->flags & OPT_LOGGED_IN ) && jd->fd == -1 )
    345         {
    346                 if( sasl_oauth2_get_refresh_token( ic, message ) )
    347                 {
     342
     343        if (g_strcasecmp(who, JABBER_XMLCONSOLE_HANDLE) == 0) {
     344                return jabber_write(ic, message, strlen(message));
     345        }
     346
     347        if (g_strcasecmp(who, JABBER_OAUTH_HANDLE) == 0 &&
     348            !(jd->flags & OPT_LOGGED_IN) && jd->fd == -1) {
     349                if (sasl_oauth2_get_refresh_token(ic, message)) {
    348350                        return 1;
    349                 }
    350                 else
    351                 {
    352                         imcb_error( ic, "OAuth failure" );
    353                         imc_logout( ic, TRUE );
     351                } else {
     352                        imcb_error(ic, "OAuth failure");
     353                        imc_logout(ic, TRUE);
    354354                        return 0;
    355355                }
    356356        }
    357        
    358         if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) )
    359                 bud = jabber_buddy_by_ext_jid( ic, who, 0 );
    360         else
    361                 bud = jabber_buddy_by_jid( ic, who, GET_BUDDY_BARE_OK );
    362        
    363         node = xt_new_node( "body", message, NULL );
    364         node = jabber_make_packet( "message", "chat", bud ? bud->full_jid : who, node );
    365        
    366         if( bud && ( jd->flags & JFLAG_WANT_TYPING ) &&
    367             ( ( bud->flags & JBFLAG_DOES_XEP85 ) ||
    368              !( bud->flags & JBFLAG_PROBED_XEP85 ) ) )
    369         {
     357
     358        if ((s = strchr(who, '=')) && jabber_chat_by_jid(ic, s + 1)) {
     359                bud = jabber_buddy_by_ext_jid(ic, who, 0);
     360        } else {
     361                bud = jabber_buddy_by_jid(ic, who, GET_BUDDY_BARE_OK);
     362        }
     363
     364        node = xt_new_node("body", message, NULL);
     365        node = jabber_make_packet("message", "chat", bud ? bud->full_jid : who, node);
     366
     367        if (bud && (jd->flags & JFLAG_WANT_TYPING) &&
     368            ((bud->flags & JBFLAG_DOES_XEP85) ||
     369             !(bud->flags & JBFLAG_PROBED_XEP85))) {
    370370                struct xt_node *act;
    371                
     371
    372372                /* If the user likes typing notification and if we don't know
    373373                   (and didn't probe before) if this resource supports XEP85,
     
    376376                   tag to tell that the user stopped typing (well, that's what
    377377                   we guess when s/he pressed Enter...). */
    378                 act = xt_new_node( "active", NULL, NULL );
    379                 xt_add_attr( act, "xmlns", XMLNS_CHATSTATES );
    380                 xt_add_child( node, act );
    381                
     378                act = xt_new_node("active", NULL, NULL);
     379                xt_add_attr(act, "xmlns", XMLNS_CHATSTATES);
     380                xt_add_child(node, act);
     381
    382382                /* Just make sure we do this only once. */
    383383                bud->flags |= JBFLAG_PROBED_XEP85;
    384384        }
    385        
    386         st = jabber_write_packet( ic, node );
    387         xt_free_node( node );
    388        
     385
     386        st = jabber_write_packet(ic, node);
     387        xt_free_node(node);
     388
    389389        return st;
    390390}
    391391
    392 static GList *jabber_away_states( struct im_connection *ic )
     392static GList *jabber_away_states(struct im_connection *ic)
    393393{
    394394        static GList *l = NULL;
    395395        int i;
    396        
    397         if( l == NULL )
    398                 for( i = 0; jabber_away_state_list[i].full_name; i ++ )
    399                         l = g_list_append( l, (void*) jabber_away_state_list[i].full_name );
    400        
     396
     397        if (l == NULL) {
     398                for (i = 0; jabber_away_state_list[i].full_name; i++) {
     399                        l = g_list_append(l, (void *) jabber_away_state_list[i].full_name);
     400                }
     401        }
     402
    401403        return l;
    402404}
    403405
    404 static void jabber_get_info( struct im_connection *ic, char *who )
     406static void jabber_get_info(struct im_connection *ic, char *who)
    405407{
    406408        struct jabber_buddy *bud;
    407        
    408         bud = jabber_buddy_by_jid( ic, who, GET_BUDDY_FIRST );
    409        
    410         while( bud )
    411         {
    412                 imcb_log( ic, "Buddy %s (%d) information:", bud->full_jid, bud->priority );
    413                 if( bud->away_state )
    414                         imcb_log( ic, "Away state: %s", bud->away_state->full_name );
    415                 imcb_log( ic, "Status message: %s", bud->away_message ? bud->away_message : "(none)" );
    416                
     409
     410        bud = jabber_buddy_by_jid(ic, who, GET_BUDDY_FIRST);
     411
     412        while (bud) {
     413                imcb_log(ic, "Buddy %s (%d) information:", bud->full_jid, bud->priority);
     414                if (bud->away_state) {
     415                        imcb_log(ic, "Away state: %s", bud->away_state->full_name);
     416                }
     417                imcb_log(ic, "Status message: %s", bud->away_message ? bud->away_message : "(none)");
     418
    417419                bud = bud->next;
    418420        }
    419        
    420         jabber_get_vcard( ic, bud ? bud->full_jid : who );
    421 }
    422 
    423 static void jabber_set_away( struct im_connection *ic, char *state_txt, char *message )
    424 {
    425         struct jabber_data *jd = ic->proto_data;
    426        
     421
     422        jabber_get_vcard(ic, bud ? bud->full_jid : who);
     423}
     424
     425static void jabber_set_away(struct im_connection *ic, char *state_txt, char *message)
     426{
     427        struct jabber_data *jd = ic->proto_data;
     428
    427429        /* state_txt == NULL -> Not away.
    428430           Unknown state -> fall back to the first defined away state. */
    429         if( state_txt == NULL )
     431        if (state_txt == NULL) {
    430432                jd->away_state = NULL;
    431         else if( ( jd->away_state = jabber_away_state_by_name( state_txt ) ) == NULL )
     433        } else if ((jd->away_state = jabber_away_state_by_name(state_txt)) == NULL) {
    432434                jd->away_state = jabber_away_state_list;
    433        
    434         g_free( jd->away_message );
    435         jd->away_message = ( message && *message ) ? g_strdup( message ) : NULL;
    436        
    437         presence_send_update( ic );
    438 }
    439 
    440 static void jabber_add_buddy( struct im_connection *ic, char *who, char *group )
    441 {
    442         struct jabber_data *jd = ic->proto_data;
    443        
    444         if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
    445         {
     435        }
     436
     437        g_free(jd->away_message);
     438        jd->away_message = (message && *message) ? g_strdup(message) : NULL;
     439
     440        presence_send_update(ic);
     441}
     442
     443static void jabber_add_buddy(struct im_connection *ic, char *who, char *group)
     444{
     445        struct jabber_data *jd = ic->proto_data;
     446
     447        if (g_strcasecmp(who, JABBER_XMLCONSOLE_HANDLE) == 0) {
    446448                jd->flags |= JFLAG_XMLCONSOLE;
    447                 imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
     449                imcb_add_buddy(ic, JABBER_XMLCONSOLE_HANDLE, NULL);
    448450                return;
    449451        }
    450        
    451         if( jabber_add_to_roster( ic, who, NULL, group ) )
    452                 presence_send_request( ic, who, "subscribe" );
    453 }
    454 
    455 static void jabber_remove_buddy( struct im_connection *ic, char *who, char *group )
    456 {
    457         struct jabber_data *jd = ic->proto_data;
    458        
    459         if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 )
    460         {
     452
     453        if (jabber_add_to_roster(ic, who, NULL, group)) {
     454                presence_send_request(ic, who, "subscribe");
     455        }
     456}
     457
     458static void jabber_remove_buddy(struct im_connection *ic, char *who, char *group)
     459{
     460        struct jabber_data *jd = ic->proto_data;
     461
     462        if (g_strcasecmp(who, JABBER_XMLCONSOLE_HANDLE) == 0) {
    461463                jd->flags &= ~JFLAG_XMLCONSOLE;
    462464                /* Not necessary for now. And for now the code isn't too
     
    467469                return;
    468470        }
    469        
     471
    470472        /* We should always do this part. Clean up our administration a little bit. */
    471         jabber_buddy_remove_bare( ic, who );
    472        
    473         if( jabber_remove_from_roster( ic, who ) )
    474                 presence_send_request( ic, who, "unsubscribe" );
    475 }
    476 
    477 static struct groupchat *jabber_chat_join_( struct im_connection *ic, const char *room, const char *nick, const char *password, set_t **sets )
     473        jabber_buddy_remove_bare(ic, who);
     474
     475        if (jabber_remove_from_roster(ic, who)) {
     476                presence_send_request(ic, who, "unsubscribe");
     477        }
     478}
     479
     480static struct groupchat *jabber_chat_join_(struct im_connection *ic, const char *room, const char *nick,
     481                                           const char *password, set_t **sets)
    478482{
    479483        struct jabber_data *jd = ic->proto_data;
    480484        char *final_nick;
    481        
     485
    482486        /* Ignore the passed nick parameter if we have our own default */
    483         if ( !( final_nick = set_getstr( sets, "nick" ) ) &&
    484              !( final_nick = set_getstr( &ic->acc->set, "display_name" ) ) ) {
     487        if (!(final_nick = set_getstr(sets, "nick")) &&
     488            !(final_nick = set_getstr(&ic->acc->set, "display_name"))) {
    485489                /* Well, whatever, actually use the provided default, then */
    486490                final_nick = (char *) nick;
    487491        }
    488492
    489         if( strchr( room, '@' ) == NULL )
    490                 imcb_error( ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?",
    491                             room, room, jd->server );
    492         else if( jabber_chat_by_jid( ic, room ) )
    493                 imcb_error( ic, "Already present in chat `%s'", room );
    494         else
    495                 return jabber_chat_join( ic, room, final_nick, set_getstr( sets, "password" ) );
    496        
     493        if (strchr(room, '@') == NULL) {
     494                imcb_error(ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?",
     495                           room, room, jd->server);
     496        } else if (jabber_chat_by_jid(ic, room)) {
     497                imcb_error(ic, "Already present in chat `%s'", room);
     498        } else {
     499                return jabber_chat_join(ic, room, final_nick, set_getstr(sets, "password"));
     500        }
     501
    497502        return NULL;
    498503}
    499504
    500 static struct groupchat *jabber_chat_with_( struct im_connection *ic, char *who )
    501 {
    502         return jabber_chat_with( ic, who );
    503 }
    504 
    505 static void jabber_chat_msg_( struct groupchat *c, char *message, int flags )
    506 {
    507         if( c && message )
    508                 jabber_chat_msg( c, message, flags );
    509 }
    510 
    511 static void jabber_chat_topic_( struct groupchat *c, char *topic )
    512 {
    513         if( c && topic )
    514                 jabber_chat_topic( c, topic );
    515 }
    516 
    517 static void jabber_chat_leave_( struct groupchat *c )
    518 {
    519         if( c )
    520                 jabber_chat_leave( c, NULL );
    521 }
    522 
    523 static void jabber_chat_invite_( struct groupchat *c, char *who, char *msg )
     505static struct groupchat *jabber_chat_with_(struct im_connection *ic, char *who)
     506{
     507        return jabber_chat_with(ic, who);
     508}
     509
     510static void jabber_chat_msg_(struct groupchat *c, char *message, int flags)
     511{
     512        if (c && message) {
     513                jabber_chat_msg(c, message, flags);
     514        }
     515}
     516
     517static void jabber_chat_topic_(struct groupchat *c, char *topic)
     518{
     519        if (c && topic) {
     520                jabber_chat_topic(c, topic);
     521        }
     522}
     523
     524static void jabber_chat_leave_(struct groupchat *c)
     525{
     526        if (c) {
     527                jabber_chat_leave(c, NULL);
     528        }
     529}
     530
     531static void jabber_chat_invite_(struct groupchat *c, char *who, char *msg)
    524532{
    525533        struct jabber_data *jd = c->ic->proto_data;
     
    527535        gchar *msg_alt = NULL;
    528536
    529         if( msg == NULL )
    530                 msg_alt = g_strdup_printf( "%s invited you to %s", jd->me, jc->name );
    531        
    532         if( c && who )
    533                 jabber_chat_invite( c, who, msg ? msg : msg_alt );
    534        
    535         g_free( msg_alt );
    536 }
    537 
    538 static void jabber_keepalive( struct im_connection *ic )
     537        if (msg == NULL) {
     538                msg_alt = g_strdup_printf("%s invited you to %s", jd->me, jc->name);
     539        }
     540
     541        if (c && who) {
     542                jabber_chat_invite(c, who, msg ? msg : msg_alt);
     543        }
     544
     545        g_free(msg_alt);
     546}
     547
     548static void jabber_keepalive(struct im_connection *ic)
    539549{
    540550        /* Just any whitespace character is enough as a keepalive for XMPP sessions. */
    541         if( !jabber_write( ic, "\n", 1 ) )
     551        if (!jabber_write(ic, "\n", 1)) {
    542552                return;
    543        
     553        }
     554
    544555        /* This runs the garbage collection every minute, which means every packet
    545556           is in the cache for about a minute (which should be enough AFAIK). */
    546         jabber_cache_clean( ic );
    547 }
    548 
    549 static int jabber_send_typing( struct im_connection *ic, char *who, int typing )
     557        jabber_cache_clean(ic);
     558}
     559
     560static int jabber_send_typing(struct im_connection *ic, char *who, int typing)
    550561{
    551562        struct jabber_data *jd = ic->proto_data;
    552563        struct jabber_buddy *bud;
    553        
     564
    554565        /* Enable typing notification related code from now. */
    555566        jd->flags |= JFLAG_WANT_TYPING;
    556        
    557         if( ( bud = jabber_buddy_by_jid( ic, who, 0 ) ) == NULL )
    558         {
     567
     568        if ((bud = jabber_buddy_by_jid(ic, who, 0)) == NULL) {
    559569                /* Sending typing notifications to unknown buddies is
    560570                   unsupported for now. Shouldn't be a problem, I think. */
    561571                return 0;
    562572        }
    563        
    564         if( bud->flags & JBFLAG_DOES_XEP85 )
    565         {
     573
     574        if (bud->flags & JBFLAG_DOES_XEP85) {
    566575                /* We're only allowed to send this stuff if we know the other
    567576                   side supports it. */
    568                
     577
    569578                struct xt_node *node;
    570579                char *type;
    571580                int st;
    572                
    573                 if( typing & OPT_TYPING )
     581
     582                if (typing & OPT_TYPING) {
    574583                        type = "composing";
    575                 else if( typing & OPT_THINKING )
     584                } else if (typing & OPT_THINKING) {
    576585                        type = "paused";
    577                 else
     586                } else {
    578587                        type = "active";
    579                
    580                 node = xt_new_node( type, NULL, NULL );
    581                 xt_add_attr( node, "xmlns", XMLNS_CHATSTATES );
    582                 node = jabber_make_packet( "message", "chat", bud->full_jid, node );
    583                
    584                 st = jabber_write_packet( ic, node );
    585                 xt_free_node( node );
    586                
     588                }
     589
     590                node = xt_new_node(type, NULL, NULL);
     591                xt_add_attr(node, "xmlns", XMLNS_CHATSTATES);
     592                node = jabber_make_packet("message", "chat", bud->full_jid, node);
     593
     594                st = jabber_write_packet(ic, node);
     595                xt_free_node(node);
     596
    587597                return st;
    588598        }
    589        
     599
    590600        return 1;
    591601}
    592602
    593 void jabber_chat_add_settings( account_t *acc, set_t **head )
     603void jabber_chat_add_settings(account_t *acc, set_t **head)
    594604{
    595605        /* Meh. Stupid room passwords. Not trying to obfuscate/hide
    596606           them from the user for now. */
    597         set_add( head, "password", NULL, NULL, NULL );
    598 }
    599 
    600 void jabber_chat_free_settings( account_t *acc, set_t **head )
    601 {
    602         set_del( head, "password" );
    603 }
    604 
    605 GList *jabber_buddy_action_list( bee_user_t *bu )
     607        set_add(head, "password", NULL, NULL, NULL);
     608}
     609
     610void jabber_chat_free_settings(account_t *acc, set_t **head)
     611{
     612        set_del(head, "password");
     613}
     614
     615GList *jabber_buddy_action_list(bee_user_t *bu)
    606616{
    607617        static GList *ret = NULL;
    608        
    609         if( ret == NULL )
    610         {
     618
     619        if (ret == NULL) {
    611620                static const struct buddy_action ba[2] = {
    612621                        { "VERSION", "Get client (version) information" },
    613622                };
    614                
    615                 ret = g_list_prepend( ret, (void*) ba + 0 );
    616         }
    617        
     623
     624                ret = g_list_prepend(ret, (void *) ba + 0);
     625        }
     626
    618627        return ret;
    619628}
    620629
    621 void *jabber_buddy_action( struct bee_user *bu, const char *action, char * const args[], void *data )
    622 {
    623         if( g_strcasecmp( action, "VERSION" ) == 0 )
    624         {
     630void *jabber_buddy_action(struct bee_user *bu, const char *action, char * const args[], void *data)
     631{
     632        if (g_strcasecmp(action, "VERSION") == 0) {
    625633                struct jabber_buddy *bud;
    626                
    627                 if( ( bud = jabber_buddy_by_ext_jid( bu->ic, bu->handle, 0 ) ) == NULL )
    628                         bud = jabber_buddy_by_jid( bu->ic, bu->handle, GET_BUDDY_FIRST );
    629                 for( ; bud; bud = bud->next )
    630                         jabber_iq_version_send( bu->ic, bud, data );
    631         }
    632        
     634
     635                if ((bud = jabber_buddy_by_ext_jid(bu->ic, bu->handle, 0)) == NULL) {
     636                        bud = jabber_buddy_by_jid(bu->ic, bu->handle, GET_BUDDY_FIRST);
     637                }
     638                for (; bud; bud = bud->next) {
     639                        jabber_iq_version_send(bu->ic, bud, data);
     640                }
     641        }
     642
    633643        return NULL;
    634644}
    635645
    636 gboolean jabber_handle_is_self( struct im_connection *ic, const char *who ) {
    637         struct jabber_data *jd = ic->proto_data;
    638         return ( ( g_strcasecmp( who, ic->acc->user ) == 0 ) ||
    639                  ( jd->internal_jid &&
    640                    g_strcasecmp( who, jd->internal_jid ) == 0 ) );
     646gboolean jabber_handle_is_self(struct im_connection *ic, const char *who)
     647{
     648        struct jabber_data *jd = ic->proto_data;
     649
     650        return ((g_strcasecmp(who, ic->acc->user) == 0) ||
     651                (jd->internal_jid &&
     652                 g_strcasecmp(who, jd->internal_jid) == 0));
    641653}
    642654
    643655void jabber_initmodule()
    644656{
    645         struct prpl *ret = g_new0( struct prpl, 1 );
    646        
     657        struct prpl *ret = g_new0(struct prpl, 1);
     658
    647659        ret->name = "jabber";
    648660        ret->mms = 0;                        /* no limit */
     
    673685        ret->buddy_action = jabber_buddy_action;
    674686
    675         register_protocol( ret );
    676 }
     687        register_protocol(ret);
     688}
  • protocols/jabber/jabber.h

    raf359b4 r5ebff60  
    3333extern GSList *jabber_connections;
    3434
    35 typedef enum
    36 {
     35typedef enum {
    3736        JFLAG_STREAM_STARTED = 1,       /* Set when we detected the beginning of the stream
    3837                                           and want to do auth. */
     
    4039        JFLAG_STREAM_RESTART = 4,       /* Set when we want to restart the stream (after
    4140                                           SASL or TLS). */
    42         JFLAG_WANT_SESSION = 8,         /* Set if the server wants a <session/> tag
     41        JFLAG_WANT_SESSION = 8,         /* Set if the server wants a <session/> tag
    4342                                           before we continue. */
    4443        JFLAG_WANT_BIND = 16,           /* ... for <bind> tag. */
     
    5352} jabber_flags_t;
    5453
    55 typedef enum
    56 {
     54typedef enum {
    5755        JBFLAG_PROBED_XEP85 = 1,        /* Set this when we sent our probe packet to make
    5856                                           sure it gets sent only once. */
     
    6866
    6967/* Stores a streamhost's (a.k.a. proxy) data */
    70 typedef struct
    71 {
     68typedef struct {
    7269        char *jid;
    7370        char *host;
     
    7572} jabber_streamhost_t;
    7673
    77 typedef enum
    78 {
     74typedef enum {
    7975        JCFLAG_MESSAGE_SENT = 1,        /* Set this after sending the first message, so
    8076                                           we can detect echoes/backlogs. */
    8177} jabber_chat_flags_t;
    8278
    83 struct jabber_data
    84 {
     79struct jabber_data {
    8580        struct im_connection *ic;
    86        
     81
    8782        int fd;
    8883        void *ssl;
     
    9085        int tx_len;
    9186        int r_inpa, w_inpa;
    92        
     87
    9388        struct xt_parser *xt;
    9489        jabber_flags_t flags;
    95        
    96         char *username;         /* USERNAME@server */
    97         char *server;           /* username@SERVER -=> server/domain, not hostname */
    98         char *me;               /* bare jid */
     90
     91        char *username;         /* USERNAME@server */
     92        char *server;           /* username@SERVER -=> server/domain, not hostname */
     93        char *me;               /* bare jid */
    9994        char *internal_jid;
    100        
     95
    10196        const struct oauth2_service *oauth2_service;
    10297        char *oauth2_access_token;
    103        
     98
    10499        /* After changing one of these two (or the priority setting), call
    105100           presence_send_update() to inform the server about the changes. */
    106101        const struct jabber_away_state *away_state;
    107102        char *away_message;
    108        
     103
    109104        md5_state_t cached_id_prefix;
    110105        GHashTable *node_cache;
     
    116111};
    117112
    118 struct jabber_away_state
    119 {
     113struct jabber_away_state {
    120114        char code[5];
    121115        char *full_name;
    122116};
    123117
    124 typedef xt_status (*jabber_cache_event) ( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    125 
    126 struct jabber_cache_entry
    127 {
     118typedef xt_status (*jabber_cache_event) (struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     119
     120struct jabber_cache_entry {
    128121        time_t saved_at;
    129122        struct xt_node *node;
     
    138131   refer to a real session and should only be used for operations that
    139132   support incomplete JIDs. */
    140 struct jabber_buddy
    141 {
     133struct jabber_buddy {
    142134        char *bare_jid;
    143135        char *full_jid;
    144136        char *resource;
    145        
     137
    146138        char *ext_jid; /* The JID to use in BitlBee. The real JID if possible, */
    147139                       /* otherwise something similar to the conference JID. */
    148        
     140
    149141        int priority;
    150142        struct jabber_away_state *away_state;
    151143        char *away_message;
    152144        GSList *features;
    153        
     145
    154146        time_t last_msg;
    155147        jabber_buddy_flags_t flags;
    156        
     148
    157149        struct jabber_buddy *next;
    158150};
    159151
    160 struct jabber_chat
    161 {
     152struct jabber_chat {
    162153        int flags;
    163154        char *name;
     
    167158};
    168159
    169 struct jabber_transfer
    170 {
     160struct jabber_transfer {
    171161        /* bitlbee's handle for this transfer */
    172162        file_transfer_t *ft;
     
    246236
    247237/* jabber.c */
    248 void jabber_connect( struct im_connection *ic );
     238void jabber_connect(struct im_connection *ic);
    249239
    250240/* iq.c */
    251 xt_status jabber_pkt_iq( struct xt_node *node, gpointer data );
    252 int jabber_init_iq_auth( struct im_connection *ic );
    253 xt_status jabber_pkt_bind_sess( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    254 int jabber_get_roster( struct im_connection *ic );
    255 int jabber_get_vcard( struct im_connection *ic, char *bare_jid );
    256 int jabber_add_to_roster( struct im_connection *ic, const char *handle, const char *name, const char *group );
    257 int jabber_remove_from_roster( struct im_connection *ic, char *handle );
    258 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid );
    259 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns );
    260 void jabber_iq_version_send( struct im_connection *ic, struct jabber_buddy *bud, void *data );
     241xt_status jabber_pkt_iq(struct xt_node *node, gpointer data);
     242int jabber_init_iq_auth(struct im_connection *ic);
     243xt_status jabber_pkt_bind_sess(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     244int jabber_get_roster(struct im_connection *ic);
     245int jabber_get_vcard(struct im_connection *ic, char *bare_jid);
     246int jabber_add_to_roster(struct im_connection *ic, const char *handle, const char *name, const char *group);
     247int jabber_remove_from_roster(struct im_connection *ic, char *handle);
     248xt_status jabber_iq_query_features(struct im_connection *ic, char *bare_jid);
     249xt_status jabber_iq_query_server(struct im_connection *ic, char *jid, char *xmlns);
     250void jabber_iq_version_send(struct im_connection *ic, struct jabber_buddy *bud, void *data);
    261251
    262252/* si.c */
    263 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode );
    264 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who );
    265 void jabber_si_free_transfer( file_transfer_t *ft);
     253int jabber_si_handle_request(struct im_connection *ic, struct xt_node *node, struct xt_node *sinode);
     254void jabber_si_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *who);
     255void jabber_si_free_transfer(file_transfer_t *ft);
    266256
    267257/* s5bytestream.c */
    268 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode);
    269 gboolean jabber_bs_send_start( struct jabber_transfer *tf );
    270 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len );
     258int jabber_bs_recv_request(struct im_connection *ic, struct xt_node *node, struct xt_node *qnode);
     259gboolean jabber_bs_send_start(struct jabber_transfer *tf);
     260gboolean jabber_bs_send_write(file_transfer_t *ft, char *buffer, unsigned int len);
    271261
    272262/* message.c */
    273 xt_status jabber_pkt_message( struct xt_node *node, gpointer data );
     263xt_status jabber_pkt_message(struct xt_node *node, gpointer data);
    274264
    275265/* presence.c */
    276 xt_status jabber_pkt_presence( struct xt_node *node, gpointer data );
    277 int presence_send_update( struct im_connection *ic );
    278 int presence_send_request( struct im_connection *ic, char *handle, char *request );
     266xt_status jabber_pkt_presence(struct xt_node *node, gpointer data);
     267int presence_send_update(struct im_connection *ic);
     268int presence_send_request(struct im_connection *ic, char *handle, char *request);
    279269
    280270/* jabber_util.c */
    281 char *set_eval_priority( set_t *set, char *value );
    282 char *set_eval_tls( set_t *set, char *value );
    283 struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children );
    284 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code );
    285 void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func );
    286 struct xt_node *jabber_cache_get( struct im_connection *ic, char *id );
    287 void jabber_cache_entry_free( gpointer entry );
    288 void jabber_cache_clean( struct im_connection *ic );
    289 xt_status jabber_cache_handle_packet( struct im_connection *ic, struct xt_node *node );
    290 const struct jabber_away_state *jabber_away_state_by_code( char *code );
    291 const struct jabber_away_state *jabber_away_state_by_name( char *name );
    292 void jabber_buddy_ask( struct im_connection *ic, char *handle );
    293 int jabber_compare_jid( const char *jid1, const char *jid2 );
    294 char *jabber_normalize( const char *orig );
    295 
    296 typedef enum
    297 {
    298         GET_BUDDY_CREAT = 1,    /* Try to create it, if necessary. */
    299         GET_BUDDY_EXACT = 2,    /* Get an exact match (only makes sense with bare JIDs). */
    300         GET_BUDDY_FIRST = 4,    /* No selection, simply get the first resource for this JID. */
    301         GET_BUDDY_BARE = 8,     /* Get the bare version of the JID (possibly inexistent). */
    302         GET_BUDDY_BARE_OK = 16, /* Allow returning a bare JID if that seems better. */
     271char *set_eval_priority(set_t *set, char *value);
     272char *set_eval_tls(set_t *set, char *value);
     273struct xt_node *jabber_make_packet(char *name, char *type, char *to, struct xt_node *children);
     274struct xt_node *jabber_make_error_packet(struct xt_node *orig, char *err_cond, char *err_type, char *err_code);
     275void jabber_cache_add(struct im_connection *ic, struct xt_node *node, jabber_cache_event func);
     276struct xt_node *jabber_cache_get(struct im_connection *ic, char *id);
     277void jabber_cache_entry_free(gpointer entry);
     278void jabber_cache_clean(struct im_connection *ic);
     279xt_status jabber_cache_handle_packet(struct im_connection *ic, struct xt_node *node);
     280const struct jabber_away_state *jabber_away_state_by_code(char *code);
     281const struct jabber_away_state *jabber_away_state_by_name(char *name);
     282void jabber_buddy_ask(struct im_connection *ic, char *handle);
     283int jabber_compare_jid(const char *jid1, const char *jid2);
     284char *jabber_normalize(const char *orig);
     285
     286typedef enum {
     287        GET_BUDDY_CREAT = 1,    /* Try to create it, if necessary. */
     288        GET_BUDDY_EXACT = 2,    /* Get an exact match (only makes sense with bare JIDs). */
     289        GET_BUDDY_FIRST = 4,    /* No selection, simply get the first resource for this JID. */
     290        GET_BUDDY_BARE = 8,     /* Get the bare version of the JID (possibly inexistent). */
     291        GET_BUDDY_BARE_OK = 16, /* Allow returning a bare JID if that seems better. */
    303292} get_buddy_flags_t;
    304293
    305 struct jabber_error
    306 {
     294struct jabber_error {
    307295        char *code, *text, *type;
    308296};
    309297
    310 struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid );
    311 struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
    312 struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
    313 int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
    314 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
    315 void jabber_buddy_remove_all( struct im_connection *ic );
    316 time_t jabber_get_timestamp( struct xt_node *xt );
    317 struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns );
    318 void jabber_error_free( struct jabber_error *err );
    319 gboolean jabber_set_me( struct im_connection *ic, const char *me );
     298struct jabber_buddy *jabber_buddy_add(struct im_connection *ic, char *full_jid);
     299struct jabber_buddy *jabber_buddy_by_jid(struct im_connection *ic, char *jid, get_buddy_flags_t flags);
     300struct jabber_buddy *jabber_buddy_by_ext_jid(struct im_connection *ic, char *jid, get_buddy_flags_t flags);
     301int jabber_buddy_remove(struct im_connection *ic, char *full_jid);
     302int jabber_buddy_remove_bare(struct im_connection *ic, char *bare_jid);
     303void jabber_buddy_remove_all(struct im_connection *ic);
     304time_t jabber_get_timestamp(struct xt_node *xt);
     305struct jabber_error *jabber_error_parse(struct xt_node *node, char *xmlns);
     306void jabber_error_free(struct jabber_error *err);
     307gboolean jabber_set_me(struct im_connection *ic, const char *me);
    320308
    321309extern const struct jabber_away_state jabber_away_state_list[];
    322310
    323311/* io.c */
    324 int jabber_write_packet( struct im_connection *ic, struct xt_node *node );
    325 int jabber_write( struct im_connection *ic, char *buf, int len );
    326 gboolean jabber_connected_plain( gpointer data, gint source, b_input_condition cond );
    327 gboolean jabber_connected_ssl( gpointer data, int returncode, void *source, b_input_condition cond );
    328 gboolean jabber_start_stream( struct im_connection *ic );
    329 void jabber_end_stream( struct im_connection *ic );
     312int jabber_write_packet(struct im_connection *ic, struct xt_node *node);
     313int jabber_write(struct im_connection *ic, char *buf, int len);
     314gboolean jabber_connected_plain(gpointer data, gint source, b_input_condition cond);
     315gboolean jabber_connected_ssl(gpointer data, int returncode, void *source, b_input_condition cond);
     316gboolean jabber_start_stream(struct im_connection *ic);
     317void jabber_end_stream(struct im_connection *ic);
    330318
    331319/* sasl.c */
    332 xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data );
    333 xt_status sasl_pkt_challenge( struct xt_node *node, gpointer data );
    334 xt_status sasl_pkt_result( struct xt_node *node, gpointer data );
    335 gboolean sasl_supported( struct im_connection *ic );
    336 void sasl_oauth2_init( struct im_connection *ic );
    337 int sasl_oauth2_get_refresh_token( struct im_connection *ic, const char *msg );
    338 int sasl_oauth2_refresh( struct im_connection *ic, const char *refresh_token );
     320xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data);
     321xt_status sasl_pkt_challenge(struct xt_node *node, gpointer data);
     322xt_status sasl_pkt_result(struct xt_node *node, gpointer data);
     323gboolean sasl_supported(struct im_connection *ic);
     324void sasl_oauth2_init(struct im_connection *ic);
     325int sasl_oauth2_get_refresh_token(struct im_connection *ic, const char *msg);
     326int sasl_oauth2_refresh(struct im_connection *ic, const char *refresh_token);
    339327
    340328extern const struct oauth2_service oauth2_service_google;
     
    342330
    343331/* conference.c */
    344 struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password );
    345 struct groupchat *jabber_chat_with( struct im_connection *ic, char *who );
    346 struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name );
    347 void jabber_chat_free( struct groupchat *c );
    348 int jabber_chat_msg( struct groupchat *ic, char *message, int flags );
    349 int jabber_chat_topic( struct groupchat *c, char *topic );
    350 int jabber_chat_leave( struct groupchat *c, const char *reason );
    351 void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node );
    352 void jabber_chat_pkt_message( struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node );
    353 void jabber_chat_invite( struct groupchat *c, char *who, char *message );
     332struct groupchat *jabber_chat_join(struct im_connection *ic, const char *room, const char *nick, const char *password);
     333struct groupchat *jabber_chat_with(struct im_connection *ic, char *who);
     334struct groupchat *jabber_chat_by_jid(struct im_connection *ic, const char *name);
     335void jabber_chat_free(struct groupchat *c);
     336int jabber_chat_msg(struct groupchat *ic, char *message, int flags);
     337int jabber_chat_topic(struct groupchat *c, char *topic);
     338int jabber_chat_leave(struct groupchat *c, const char *reason);
     339void jabber_chat_pkt_presence(struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node);
     340void jabber_chat_pkt_message(struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node);
     341void jabber_chat_invite(struct groupchat *c, char *who, char *message);
    354342
    355343#endif
  • protocols/jabber/jabber_util.c

    raf359b4 r5ebff60  
    44*  Jabber module - Misc. stuff                                              *
    55*                                                                           *
    6 *  Copyright 2006-2010 Wilmer van der Gaast <wilmer@gaast.net>             
     6*  Copyright 2006-2010 Wilmer van der Gaast <wilmer@gaast.net>
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    2828static unsigned int next_id = 1;
    2929
    30 char *set_eval_priority( set_t *set, char *value )
     30char *set_eval_priority(set_t *set, char *value)
    3131{
    3232        account_t *acc = set->data;
    3333        int i;
    34        
    35         if( sscanf( value, "%d", &i ) == 1 )
    36         {
     34
     35        if (sscanf(value, "%d", &i) == 1) {
    3736                /* Priority is a signed 8-bit integer, according to RFC 3921. */
    38                 if( i < -128 || i > 127 )
     37                if (i < -128 || i > 127) {
    3938                        return SET_INVALID;
    40         }
    41         else
     39                }
     40        } else {
    4241                return SET_INVALID;
    43        
     42        }
     43
    4444        /* Only run this stuff if the account is online ATM,
    4545           and if the setting seems to be acceptable. */
    46         if( acc->ic )
    47         {
     46        if (acc->ic) {
    4847                /* Although set_eval functions usually are very nice and
    4948                   convenient, they have one disadvantage: If I would just
     
    5150                   send the old setting because the set->value gets changed
    5251                   after the (this) eval returns a non-NULL value.
    53                    
     52
    5453                   So now I can choose between implementing post-set
    5554                   functions next to evals, or just do this little hack: */
    56                
    57                 g_free( set->value );
    58                 set->value = g_strdup( value );
    59                
     55
     56                g_free(set->value);
     57                set->value = g_strdup(value);
     58
    6059                /* (Yes, sorry, I prefer the hack. :-P) */
    61                
    62                 presence_send_update( acc->ic );
    63         }
    64        
     60
     61                presence_send_update(acc->ic);
     62        }
     63
    6564        return value;
    6665}
    6766
    68 char *set_eval_tls( set_t *set, char *value )
    69 {
    70         if( g_strcasecmp( value, "try" ) == 0 )
     67char *set_eval_tls(set_t *set, char *value)
     68{
     69        if (g_strcasecmp(value, "try") == 0) {
    7170                return value;
    72         else
    73                 return set_eval_bool( set, value );
    74 }
    75 
    76 struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children )
     71        } else {
     72                return set_eval_bool(set, value);
     73        }
     74}
     75
     76struct xt_node *jabber_make_packet(char *name, char *type, char *to, struct xt_node *children)
    7777{
    7878        struct xt_node *node;
    79        
    80         node = xt_new_node( name, NULL, children );
    81        
    82         if( type )
    83                 xt_add_attr( node, "type", type );
    84         if( to )
    85                 xt_add_attr( node, "to", to );
    86        
     79
     80        node = xt_new_node(name, NULL, children);
     81
     82        if (type) {
     83                xt_add_attr(node, "type", type);
     84        }
     85        if (to) {
     86                xt_add_attr(node, "to", to);
     87        }
     88
    8789        /* IQ packets should always have an ID, so let's generate one. It
    8890           might get overwritten by jabber_cache_add() if this packet has
    8991           to be saved until we receive a response. Cached packets get
    9092           slightly different IDs so we can recognize them. */
    91         if( strcmp( name, "iq" ) == 0 )
    92         {
    93                 char *id = g_strdup_printf( "%s%05x", JABBER_PACKET_ID, ( next_id++ ) & 0xfffff );
    94                 xt_add_attr( node, "id", id );
    95                 g_free( id );
    96         }
    97        
     93        if (strcmp(name, "iq") == 0) {
     94                char *id = g_strdup_printf("%s%05x", JABBER_PACKET_ID, (next_id++) & 0xfffff);
     95                xt_add_attr(node, "id", id);
     96                g_free(id);
     97        }
     98
    9899        return node;
    99100}
    100101
    101 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code )
     102struct xt_node *jabber_make_error_packet(struct xt_node *orig, char *err_cond, char *err_type, char *err_code)
    102103{
    103104        struct xt_node *node, *c;
    104105        char *to;
    105        
     106
    106107        /* Create the "defined-condition" tag. */
    107         c = xt_new_node( err_cond, NULL, NULL );
    108         xt_add_attr( c, "xmlns", XMLNS_STANZA_ERROR );
    109        
     108        c = xt_new_node(err_cond, NULL, NULL);
     109        xt_add_attr(c, "xmlns", XMLNS_STANZA_ERROR);
     110
    110111        /* Put it in an <error> tag. */
    111         c = xt_new_node( "error", NULL, c );
    112         xt_add_attr( c, "type", err_type );
    113        
     112        c = xt_new_node("error", NULL, c);
     113        xt_add_attr(c, "type", err_type);
     114
    114115        /* Add the error code, if present */
    115         if (err_code)
    116                 xt_add_attr( c, "code", err_code );
    117        
     116        if (err_code) {
     117                xt_add_attr(c, "code", err_code);
     118        }
     119
    118120        /* To make the actual error packet, we copy the original packet and
    119121           add our <error>/type="error" tag. Including the original packet
    120122           is recommended, so let's just do it. */
    121         node = xt_dup( orig );
    122         xt_add_child( node, c );
    123         xt_add_attr( node, "type", "error" );
    124        
     123        node = xt_dup(orig);
     124        xt_add_child(node, c);
     125        xt_add_attr(node, "type", "error");
     126
    125127        /* Return to sender. */
    126         if( ( to = xt_find_attr( node, "from" ) ) )
    127         {
    128                 xt_add_attr( node, "to", to );
    129                 xt_remove_attr( node, "from" );
    130         }
    131                
     128        if ((to = xt_find_attr(node, "from"))) {
     129                xt_add_attr(node, "to", to);
     130                xt_remove_attr(node, "from");
     131        }
     132
    132133        return node;
    133134}
     
    136137   them when you receive the response. Use this BEFORE sending the packet so
    137138   it'll get a new id= tag, and do NOT free() the packet after sending it! */
    138 void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func )
     139void jabber_cache_add(struct im_connection *ic, struct xt_node *node, jabber_cache_event func)
    139140{
    140141        struct jabber_data *jd = ic->proto_data;
    141         struct jabber_cache_entry *entry = g_new0( struct jabber_cache_entry, 1 );
     142        struct jabber_cache_entry *entry = g_new0(struct jabber_cache_entry, 1);
    142143        md5_state_t id_hash;
    143144        md5_byte_t id_sum[16];
    144145        char *id, *asc_hash;
    145        
    146         next_id ++;
    147        
     146
     147        next_id++;
     148
    148149        id_hash = jd->cached_id_prefix;
    149         md5_append( &id_hash, (md5_byte_t*) &next_id, sizeof( next_id ) );
    150         md5_digest_keep( &id_hash, id_sum );
    151         asc_hash = base64_encode( id_sum, 12 );
    152        
    153         id = g_strdup_printf( "%s%s", JABBER_CACHED_ID, asc_hash );
    154         xt_add_attr( node, "id", id );
    155         g_free( id );
    156         g_free( asc_hash );
    157        
     150        md5_append(&id_hash, (md5_byte_t *) &next_id, sizeof(next_id));
     151        md5_digest_keep(&id_hash, id_sum);
     152        asc_hash = base64_encode(id_sum, 12);
     153
     154        id = g_strdup_printf("%s%s", JABBER_CACHED_ID, asc_hash);
     155        xt_add_attr(node, "id", id);
     156        g_free(id);
     157        g_free(asc_hash);
     158
    158159        entry->node = node;
    159160        entry->func = func;
    160         entry->saved_at = time( NULL );
    161         g_hash_table_insert( jd->node_cache, xt_find_attr( node, "id" ), entry );
    162 }
    163 
    164 void jabber_cache_entry_free( gpointer data )
     161        entry->saved_at = time(NULL);
     162        g_hash_table_insert(jd->node_cache, xt_find_attr(node, "id"), entry);
     163}
     164
     165void jabber_cache_entry_free(gpointer data)
    165166{
    166167        struct jabber_cache_entry *entry = data;
    167        
    168         xt_free_node( entry->node );
    169         g_free( entry );
    170 }
    171 
    172 gboolean jabber_cache_clean_entry( gpointer key, gpointer entry, gpointer nullpointer );
     168
     169        xt_free_node(entry->node);
     170        g_free(entry);
     171}
     172
     173gboolean jabber_cache_clean_entry(gpointer key, gpointer entry, gpointer nullpointer);
    173174
    174175/* This one should be called from time to time (from keepalive, in this case)
     
    177178   node should be available in the cache for at least a minute (assuming the
    178179   function is indeed called every minute). */
    179 void jabber_cache_clean( struct im_connection *ic )
     180void jabber_cache_clean(struct im_connection *ic)
    180181{
    181182        struct jabber_data *jd = ic->proto_data;
    182         time_t threshold = time( NULL ) - JABBER_CACHE_MAX_AGE;
    183        
    184         g_hash_table_foreach_remove( jd->node_cache, jabber_cache_clean_entry, &threshold );
    185 }
    186 
    187 gboolean jabber_cache_clean_entry( gpointer key, gpointer entry_, gpointer threshold_ )
     183        time_t threshold = time(NULL) - JABBER_CACHE_MAX_AGE;
     184
     185        g_hash_table_foreach_remove(jd->node_cache, jabber_cache_clean_entry, &threshold);
     186}
     187
     188gboolean jabber_cache_clean_entry(gpointer key, gpointer entry_, gpointer threshold_)
    188189{
    189190        struct jabber_cache_entry *entry = entry_;
    190191        time_t *threshold = threshold_;
    191        
     192
    192193        return entry->saved_at < *threshold;
    193194}
    194195
    195 xt_status jabber_cache_handle_packet( struct im_connection *ic, struct xt_node *node )
     196xt_status jabber_cache_handle_packet(struct im_connection *ic, struct xt_node *node)
    196197{
    197198        struct jabber_data *jd = ic->proto_data;
    198199        struct jabber_cache_entry *entry;
    199200        char *s;
    200        
    201         if( ( s = xt_find_attr( node, "id" ) ) == NULL ||
    202             strncmp( s, JABBER_CACHED_ID, strlen( JABBER_CACHED_ID ) ) != 0 )
    203         {
     201
     202        if ((s = xt_find_attr(node, "id")) == NULL ||
     203            strncmp(s, JABBER_CACHED_ID, strlen(JABBER_CACHED_ID)) != 0) {
    204204                /* Silently ignore it, without an ID (or a non-cache
    205205                   ID) we don't know how to handle the packet and we
     
    207207                return XT_HANDLED;
    208208        }
    209        
    210         entry = g_hash_table_lookup( jd->node_cache, s );
    211        
    212         if( entry == NULL )
    213         {
     209
     210        entry = g_hash_table_lookup(jd->node_cache, s);
     211
     212        if (entry == NULL) {
    214213                /*
    215214                There's no longer an easy way to see if we generated this
    216215                one or someone else, and there's a ten-minute timeout anyway,
    217216                so meh.
    218                
     217
    219218                imcb_log( ic, "Warning: Received %s-%s packet with unknown/expired ID %s!",
    220219                              node->name, xt_find_attr( node, "type" ) ? : "(no type)", s );
    221220                */
    222         }
    223         else if( entry->func )
    224         {
    225                 return entry->func( ic, node, entry->node );
    226         }
    227        
     221        } else if (entry->func) {
     222                return entry->func(ic, node, entry->node);
     223        }
     224
    228225        return XT_HANDLED;
    229226}
     
    238235};
    239236
    240 const struct jabber_away_state *jabber_away_state_by_code( char *code )
     237const struct jabber_away_state *jabber_away_state_by_code(char *code)
    241238{
    242239        int i;
    243        
    244         if( code == NULL )
     240
     241        if (code == NULL) {
    245242                return NULL;
    246        
    247         for( i = 0; jabber_away_state_list[i].full_name; i ++ )
    248                 if( g_strcasecmp( jabber_away_state_list[i].code, code ) == 0 )
     243        }
     244
     245        for (i = 0; jabber_away_state_list[i].full_name; i++) {
     246                if (g_strcasecmp(jabber_away_state_list[i].code, code) == 0) {
    249247                        return jabber_away_state_list + i;
    250        
     248                }
     249        }
     250
    251251        return NULL;
    252252}
    253253
    254 const struct jabber_away_state *jabber_away_state_by_name( char *name )
     254const struct jabber_away_state *jabber_away_state_by_name(char *name)
    255255{
    256256        int i;
    257        
    258         if( name == NULL )
     257
     258        if (name == NULL) {
    259259                return NULL;
    260        
    261         for( i = 0; jabber_away_state_list[i].full_name; i ++ )
    262                 if( g_strcasecmp( jabber_away_state_list[i].full_name, name ) == 0 )
     260        }
     261
     262        for (i = 0; jabber_away_state_list[i].full_name; i++) {
     263                if (g_strcasecmp(jabber_away_state_list[i].full_name, name) == 0) {
    263264                        return jabber_away_state_list + i;
    264        
     265                }
     266        }
     267
    265268        return NULL;
    266269}
    267270
    268 struct jabber_buddy_ask_data
    269 {
     271struct jabber_buddy_ask_data {
    270272        struct im_connection *ic;
    271273        char *handle;
     
    273275};
    274276
    275 static void jabber_buddy_ask_yes( void *data )
     277static void jabber_buddy_ask_yes(void *data)
    276278{
    277279        struct jabber_buddy_ask_data *bla = data;
    278        
    279         presence_send_request( bla->ic, bla->handle, "subscribed" );
    280        
    281         imcb_ask_add( bla->ic, bla->handle, NULL );
    282        
    283         g_free( bla->handle );
    284         g_free( bla );
    285 }
    286 
    287 static void jabber_buddy_ask_no( void *data )
     280
     281        presence_send_request(bla->ic, bla->handle, "subscribed");
     282
     283        imcb_ask_add(bla->ic, bla->handle, NULL);
     284
     285        g_free(bla->handle);
     286        g_free(bla);
     287}
     288
     289static void jabber_buddy_ask_no(void *data)
    288290{
    289291        struct jabber_buddy_ask_data *bla = data;
    290        
    291         presence_send_request( bla->ic, bla->handle, "unsubscribed" );
    292        
    293         g_free( bla->handle );
    294         g_free( bla );
    295 }
    296 
    297 void jabber_buddy_ask( struct im_connection *ic, char *handle )
    298 {
    299         struct jabber_buddy_ask_data *bla = g_new0( struct jabber_buddy_ask_data, 1 );
     292
     293        presence_send_request(bla->ic, bla->handle, "unsubscribed");
     294
     295        g_free(bla->handle);
     296        g_free(bla);
     297}
     298
     299void jabber_buddy_ask(struct im_connection *ic, char *handle)
     300{
     301        struct jabber_buddy_ask_data *bla = g_new0(struct jabber_buddy_ask_data, 1);
    300302        char *buf;
    301        
     303
    302304        bla->ic = ic;
    303         bla->handle = g_strdup( handle );
    304        
    305         buf = g_strdup_printf( "The user %s wants to add you to his/her buddy list.", handle );
    306         imcb_ask( ic, buf, bla, jabber_buddy_ask_yes, jabber_buddy_ask_no );
    307         g_free( buf );
     305        bla->handle = g_strdup(handle);
     306
     307        buf = g_strdup_printf("The user %s wants to add you to his/her buddy list.", handle);
     308        imcb_ask(ic, buf, bla, jabber_buddy_ask_yes, jabber_buddy_ask_no);
     309        g_free(buf);
    308310}
    309311
    310312/* Compares just the bare portions of two Jabber IDs. */
    311 int jabber_compare_jid( const char *jid1, const char *jid2 )
     313int jabber_compare_jid(const char *jid1, const char *jid2)
    312314{
    313315        int i;
    314        
    315         for( i = 0; ; i ++ )
    316         {
    317                 if( jid1[i] == '\0' || jid1[i] == '/' || jid2[i] == '\0' || jid2[i] == '/' )
    318                 {
    319                         if( ( jid1[i] == '\0' || jid1[i] == '/' ) && ( jid2[i] == '\0' || jid2[i] == '/' ) )
     316
     317        for (i = 0;; i++) {
     318                if (jid1[i] == '\0' || jid1[i] == '/' || jid2[i] == '\0' || jid2[i] == '/') {
     319                        if ((jid1[i] == '\0' || jid1[i] == '/') && (jid2[i] == '\0' || jid2[i] == '/')) {
    320320                                break;
     321                        }
    321322                        return FALSE;
    322323                }
    323                 if( g_ascii_tolower( jid1[i] ) != g_ascii_tolower( jid2[i] ) )
    324                 {
     324                if (g_ascii_tolower(jid1[i]) != g_ascii_tolower(jid2[i])) {
    325325                        return FALSE;
    326326                }
    327327        }
    328        
     328
    329329        return TRUE;
    330330}
     
    332332/* The /resource part is case sensitive. This stops once we see a slash.
    333333   Returns a new string. Don't leak it! */
    334 char *jabber_normalize( const char *orig )
     334char *jabber_normalize(const char *orig)
    335335{
    336336        char *lower, *new, *s;
    337337
    338         if ( ! ( s = strchr( orig, '/' ) ) )
    339                 return g_utf8_strdown( orig, -1 );
    340 
    341         lower = g_utf8_strdown( orig, (s - orig) );  /* stop in s */
    342         new = g_strconcat( lower, s, NULL );
    343         g_free( lower );
     338        if (!(s = strchr(orig, '/'))) {
     339                return g_utf8_strdown(orig, -1);
     340        }
     341
     342        lower = g_utf8_strdown(orig, (s - orig));    /* stop in s */
     343        new = g_strconcat(lower, s, NULL);
     344        g_free(lower);
    344345        return new;
    345346}
     
    347348/* Similar to jabber_normalize, but works with addresses in the form
    348349 * resource=chatroom@example.com */
    349 char *jabber_normalize_ext( const char *orig )
     350char *jabber_normalize_ext(const char *orig)
    350351{
    351352        char *lower, *new, *s;
    352353
    353         if ( ! ( s = strchr( orig, '=' ) ) )
    354                 return g_utf8_strdown( orig, -1 );
    355 
    356         lower = g_utf8_strdown( s, -1 ); /* start in s */
     354        if (!(s = strchr(orig, '='))) {
     355                return g_utf8_strdown(orig, -1);
     356        }
     357
     358        lower = g_utf8_strdown(s, -1);   /* start in s */
    357359
    358360        *s = 0;
    359         new = g_strconcat( orig, lower, NULL );
     361        new = g_strconcat(orig, lower, NULL);
    360362        *s = '=';
    361363
    362         g_free( lower );
     364        g_free(lower);
    363365        return new;
    364366}
     
    369371   to deal with that properly. Set their ->resource property to NULL. Do *NOT*
    370372   allow to mix this stuff, though... */
    371 struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid_ )
     373struct jabber_buddy *jabber_buddy_add(struct im_connection *ic, char *full_jid_)
    372374{
    373375        struct jabber_data *jd = ic->proto_data;
    374376        struct jabber_buddy *bud, *new, *bi;
    375377        char *s, *full_jid;
    376        
    377         full_jid = jabber_normalize( full_jid_ );
    378        
    379         if( ( s = strchr( full_jid, '/' ) ) )
     378
     379        full_jid = jabber_normalize(full_jid_);
     380
     381        if ((s = strchr(full_jid, '/'))) {
    380382                *s = 0;
    381        
    382         new = g_new0( struct jabber_buddy, 1 );
    383        
    384         if( ( bud = g_hash_table_lookup( jd->buddies, full_jid ) ) )
    385         {
     383        }
     384
     385        new = g_new0(struct jabber_buddy, 1);
     386
     387        if ((bud = g_hash_table_lookup(jd->buddies, full_jid))) {
    386388                /* The first entry is always a bare JID. If there are more, we
    387389                   should ignore the first one here. */
    388                 if( bud->next )
     390                if (bud->next) {
    389391                        bud = bud->next;
    390                
     392                }
     393
    391394                /* If this is a transport buddy or whatever, it can't have more
    392395                   than one instance, so this is always wrong: */
    393                 if( s == NULL || bud->resource == NULL )
    394                 {
    395                         if( s ) *s = '/';
    396                         g_free( new );
    397                         g_free( full_jid );
     396                if (s == NULL || bud->resource == NULL) {
     397                        if (s) {
     398                                *s = '/';
     399                        }
     400                        g_free(new);
     401                        g_free(full_jid);
    398402                        return NULL;
    399403                }
    400                
     404
    401405                new->bare_jid = bud->bare_jid;
    402                
     406
    403407                /* We already have another resource for this buddy, add the
    404408                   new one to the list. */
    405                 for( bi = bud; bi; bi = bi->next )
    406                 {
     409                for (bi = bud; bi; bi = bi->next) {
    407410                        /* Check for dupes. */
    408                         if( strcmp( bi->resource, s + 1 ) == 0 )
    409                         {
     411                        if (strcmp(bi->resource, s + 1) == 0) {
    410412                                *s = '/';
    411                                 g_free( new );
    412                                 g_free( full_jid );
     413                                g_free(new);
     414                                g_free(full_jid);
    413415                                return NULL;
    414416                        }
    415417                        /* Append the new item to the list. */
    416                         else if( bi->next == NULL )
    417                         {
     418                        else if (bi->next == NULL) {
    418419                                bi->next = new;
    419420                                break;
    420421                        }
    421422                }
    422         }
    423         else
    424         {
    425                 new->full_jid = new->bare_jid = g_strdup( full_jid );
    426                 g_hash_table_insert( jd->buddies, new->bare_jid, new );
    427                
    428                 if( s )
    429                 {
    430                         new->next = g_new0( struct jabber_buddy, 1 );
     423        } else {
     424                new->full_jid = new->bare_jid = g_strdup(full_jid);
     425                g_hash_table_insert(jd->buddies, new->bare_jid, new);
     426
     427                if (s) {
     428                        new->next = g_new0(struct jabber_buddy, 1);
    431429                        new->next->bare_jid = new->bare_jid;
    432430                        new = new->next;
    433431                }
    434432        }
    435        
    436         if( s )
    437         {
     433
     434        if (s) {
    438435                *s = '/';
    439436                new->full_jid = full_jid;
    440                 new->resource = strchr( new->full_jid, '/' ) + 1;
    441         }
    442         else
    443         {
     437                new->resource = strchr(new->full_jid, '/') + 1;
     438        } else {
    444439                /* Let's waste some more bytes of RAM instead of to make
    445440                   memory management a total disaster here. And it saves
     
    447442                new->full_jid = full_jid;
    448443        }
    449        
     444
    450445        return new;
    451446}
     
    454449   asked for a bare JID, it uses the "resource_select" setting to see which
    455450   resource to pick. */
    456 struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid_, get_buddy_flags_t flags )
     451struct jabber_buddy *jabber_buddy_by_jid(struct im_connection *ic, char *jid_, get_buddy_flags_t flags)
    457452{
    458453        struct jabber_data *jd = ic->proto_data;
    459454        struct jabber_buddy *bud, *head;
    460455        char *s, *jid;
    461        
    462         jid = jabber_normalize( jid_ );
    463        
    464         if( ( s = strchr( jid, '/' ) ) )
    465         {
     456
     457        jid = jabber_normalize(jid_);
     458
     459        if ((s = strchr(jid, '/'))) {
    466460                int bare_exists = 0;
    467                
     461
    468462                *s = 0;
    469                 if( ( bud = g_hash_table_lookup( jd->buddies, jid ) ) )
    470                 {
     463                if ((bud = g_hash_table_lookup(jd->buddies, jid))) {
    471464                        bare_exists = 1;
    472                        
    473                         if( bud->next )
     465
     466                        if (bud->next) {
    474467                                bud = bud->next;
    475                        
     468                        }
     469
    476470                        /* Just return the first one for this bare JID. */
    477                         if( flags & GET_BUDDY_FIRST )
    478                         {
     471                        if (flags & GET_BUDDY_FIRST) {
    479472                                *s = '/';
    480                                 g_free( jid );
     473                                g_free(jid);
    481474                                return bud;
    482475                        }
    483                        
     476
    484477                        /* Is this one of those no-resource buddies? */
    485                         if( bud->resource == NULL )
    486                         {
     478                        if (bud->resource == NULL) {
    487479                                *s = '/';
    488                                 g_free( jid );
     480                                g_free(jid);
    489481                                return NULL;
    490482                        }
    491                        
     483
    492484                        /* See if there's an exact match. */
    493                         for( ; bud; bud = bud->next )
    494                                 if( strcmp( bud->resource, s + 1 ) == 0 )
     485                        for (; bud; bud = bud->next) {
     486                                if (strcmp(bud->resource, s + 1) == 0) {
    495487                                        break;
    496                 }
    497                
    498                 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) &&
    499                     ( bare_exists || bee_user_by_handle( ic->bee, ic, jid ) ) )
    500                 {
     488                                }
     489                        }
     490                }
     491
     492                if (bud == NULL && (flags & GET_BUDDY_CREAT) &&
     493                    (bare_exists || bee_user_by_handle(ic->bee, ic, jid))) {
    501494                        *s = '/';
    502                         bud = jabber_buddy_add( ic, jid );
    503                 }
    504                
    505                 g_free( jid );
     495                        bud = jabber_buddy_add(ic, jid);
     496                }
     497
     498                g_free(jid);
    506499                return bud;
    507         }
    508         else
    509         {
     500        } else {
    510501                struct jabber_buddy *best_prio, *best_time;
    511502                char *set;
    512                
    513                 head = g_hash_table_lookup( jd->buddies, jid );
    514                 bud = ( head && head->next ) ? head->next : head;
    515                
    516                 g_free( jid );
    517                
    518                 if( bud == NULL )
     503
     504                head = g_hash_table_lookup(jd->buddies, jid);
     505                bud = (head && head->next) ? head->next : head;
     506
     507                g_free(jid);
     508
     509                if (bud == NULL) {
    519510                        /* No match. Create it now? */
    520                         return ( ( flags & GET_BUDDY_CREAT ) &&
    521                                  bee_user_by_handle( ic->bee, ic, jid_ ) ) ?
    522                                    jabber_buddy_add( ic, jid_ ) : NULL;
    523                 else if( bud->resource && ( flags & GET_BUDDY_EXACT ) )
     511                        return ((flags & GET_BUDDY_CREAT) &&
     512                                bee_user_by_handle(ic->bee, ic, jid_)) ?
     513                               jabber_buddy_add(ic, jid_) : NULL;
     514                } else if (bud->resource && (flags & GET_BUDDY_EXACT)) {
    524515                        /* We want an exact match, so in thise case there shouldn't be a /resource. */
    525516                        return NULL;
    526                 else if( bud->resource == NULL || bud->next == NULL )
     517                } else if (bud->resource == NULL || bud->next == NULL) {
    527518                        /* No need for selection if there's only one option. */
    528519                        return bud;
    529                 else if( flags & GET_BUDDY_FIRST )
     520                } else if (flags & GET_BUDDY_FIRST) {
    530521                        /* Looks like the caller doesn't care about details. */
    531522                        return bud;
    532                 else if( flags & GET_BUDDY_BARE )
     523                } else if (flags & GET_BUDDY_BARE) {
    533524                        return head;
    534                
     525                }
     526
    535527                best_prio = best_time = bud;
    536                 for( ; bud; bud = bud->next )
    537                 {
    538                         if( bud->priority > best_prio->priority )
     528                for (; bud; bud = bud->next) {
     529                        if (bud->priority > best_prio->priority) {
    539530                                best_prio = bud;
    540                         if( bud->last_msg > best_time->last_msg )
     531                        }
     532                        if (bud->last_msg > best_time->last_msg) {
    541533                                best_time = bud;
    542                 }
    543                
    544                 if( ( set = set_getstr( &ic->acc->set, "resource_select" ) ) == NULL )
     534                        }
     535                }
     536
     537                if ((set = set_getstr(&ic->acc->set, "resource_select")) == NULL) {
    545538                        return NULL;
    546                 else if( strcmp( set, "priority" ) == 0 )
     539                } else if (strcmp(set, "priority") == 0) {
    547540                        return best_prio;
    548                 else if( flags & GET_BUDDY_BARE_OK ) /* && strcmp( set, "activity" ) == 0 */
    549                 {
    550                         if( best_time->last_msg + set_getint( &ic->acc->set, "activity_timeout" ) >= time( NULL ) )
     541                } else if (flags & GET_BUDDY_BARE_OK) { /* && strcmp( set, "activity" ) == 0 */
     542                        if (best_time->last_msg + set_getint(&ic->acc->set, "activity_timeout") >= time(NULL)) {
    551543                                return best_time;
    552                         else
     544                        } else {
    553545                                return head;
    554                 }
    555                 else
     546                        }
     547                } else {
    556548                        return best_time;
     549                }
    557550        }
    558551}
     
    565558   replacing the / with a =. But there should be some stripping (@s are
    566559   allowed in Jabber nicks...). */
    567 struct jabber_buddy *jabber_buddy_by_ext_jid( struct im_connection *ic, char *jid_, get_buddy_flags_t flags )
     560struct jabber_buddy *jabber_buddy_by_ext_jid(struct im_connection *ic, char *jid_, get_buddy_flags_t flags)
    568561{
    569562        struct jabber_buddy *bud;
    570563        char *s, *jid;
    571        
    572         jid = jabber_normalize_ext( jid_ );
    573        
    574         if( ( s = strchr( jid, '=' ) ) == NULL )
     564
     565        jid = jabber_normalize_ext(jid_);
     566
     567        if ((s = strchr(jid, '=')) == NULL) {
    575568                return NULL;
    576        
    577         for( bud = jabber_buddy_by_jid( ic, s + 1, GET_BUDDY_FIRST ); bud; bud = bud->next )
    578         {
     569        }
     570
     571        for (bud = jabber_buddy_by_jid(ic, s + 1, GET_BUDDY_FIRST); bud; bud = bud->next) {
    579572                /* Hmmm, could happen if not all people in the chat are anonymized? */
    580                 if( bud->ext_jid == NULL )
     573                if (bud->ext_jid == NULL) {
    581574                        continue;
    582                
    583                 if( strcmp( bud->ext_jid, jid ) == 0 )
     575                }
     576
     577                if (strcmp(bud->ext_jid, jid) == 0) {
    584578                        break;
    585         }
    586        
    587         g_free( jid );
    588        
     579                }
     580        }
     581
     582        g_free(jid);
     583
    589584        return bud;
    590585}
     
    593588   off-line (because (s)he can still be online from a different location.
    594589   XXX: See above, we should accept bare JIDs too... */
    595 int jabber_buddy_remove( struct im_connection *ic, char *full_jid_ )
     590int jabber_buddy_remove(struct im_connection *ic, char *full_jid_)
    596591{
    597592        struct jabber_data *jd = ic->proto_data;
    598593        struct jabber_buddy *bud, *prev = NULL, *bi;
    599594        char *s, *full_jid;
    600        
    601         full_jid = jabber_normalize( full_jid_ );
    602        
    603         if( ( s = strchr( full_jid, '/' ) ) )
     595
     596        full_jid = jabber_normalize(full_jid_);
     597
     598        if ((s = strchr(full_jid, '/'))) {
    604599                *s = 0;
    605        
    606         if( ( bud = g_hash_table_lookup( jd->buddies, full_jid ) ) )
    607         {
    608                 if( bud->next )
    609                         bud = (prev=bud)->next;
    610                
     600        }
     601
     602        if ((bud = g_hash_table_lookup(jd->buddies, full_jid))) {
     603                if (bud->next) {
     604                        bud = (prev = bud)->next;
     605                }
     606
    611607                /* If there's only one item in the list (and if the resource
    612608                   matches), removing it is simple. (And the hash reference
    613609                   should be removed too!) */
    614                 if( bud->next == NULL &&
    615                     ( ( s == NULL && bud->resource == NULL ) ||
    616                       ( bud->resource && s && strcmp( bud->resource, s + 1 ) == 0 ) ) )
    617                 {
    618                         int st = jabber_buddy_remove_bare( ic, full_jid );
    619                         g_free( full_jid );
     610                if (bud->next == NULL &&
     611                    ((s == NULL && bud->resource == NULL) ||
     612                     (bud->resource && s && strcmp(bud->resource, s + 1) == 0))) {
     613                        int st = jabber_buddy_remove_bare(ic, full_jid);
     614                        g_free(full_jid);
    620615                        return st;
    621                 }
    622                 else if( s == NULL || bud->resource == NULL )
    623                 {
     616                } else if (s == NULL || bud->resource == NULL) {
    624617                        /* Tried to remove a bare JID while this JID does seem
    625618                           to have resources... (Or the opposite.) *sigh* */
    626                         g_free( full_jid );
     619                        g_free(full_jid);
    627620                        return 0;
    628                 }
    629                 else
    630                 {
    631                         for( bi = bud; bi; bi = (prev=bi)->next )
    632                                 if( strcmp( bi->resource, s + 1 ) == 0 )
     621                } else {
     622                        for (bi = bud; bi; bi = (prev = bi)->next) {
     623                                if (strcmp(bi->resource, s + 1) == 0) {
    633624                                        break;
    634                        
    635                         g_free( full_jid );
    636                        
    637                         if( bi )
    638                         {
    639                                 if( prev )
     625                                }
     626                        }
     627
     628                        g_free(full_jid);
     629
     630                        if (bi) {
     631                                if (prev) {
    640632                                        prev->next = bi->next;
    641                                 else
     633                                } else {
    642634                                        /* Don't think this should ever happen anymore. */
    643                                         g_hash_table_replace( jd->buddies, bi->bare_jid, bi->next );
    644                                
    645                                 g_free( bi->ext_jid );
    646                                 g_free( bi->full_jid );
    647                                 g_free( bi->away_message );
    648                                 g_free( bi );
    649                                
     635                                        g_hash_table_replace(jd->buddies, bi->bare_jid, bi->next);
     636                                }
     637
     638                                g_free(bi->ext_jid);
     639                                g_free(bi->full_jid);
     640                                g_free(bi->away_message);
     641                                g_free(bi);
     642
    650643                                return 1;
    651                         }
    652                         else
    653                         {
     644                        } else {
    654645                                return 0;
    655646                        }
    656647                }
    657         }
    658         else
    659         {
    660                 g_free( full_jid );
     648        } else {
     649                g_free(full_jid);
    661650                return 0;
    662651        }
     
    666655   specified bare JID. Use this when removing someone from the contact
    667656   list, for example. */
    668 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid )
     657int jabber_buddy_remove_bare(struct im_connection *ic, char *bare_jid)
    669658{
    670659        struct jabber_data *jd = ic->proto_data;
    671660        struct jabber_buddy *bud, *next;
    672        
    673         if( strchr( bare_jid, '/' ) )
     661
     662        if (strchr(bare_jid, '/')) {
    674663                return 0;
    675        
    676         if( ( bud = jabber_buddy_by_jid( ic, bare_jid, GET_BUDDY_FIRST ) ) )
    677         {
     664        }
     665
     666        if ((bud = jabber_buddy_by_jid(ic, bare_jid, GET_BUDDY_FIRST))) {
    678667                /* Most important: Remove the hash reference. We don't know
    679668                   this buddy anymore. */
    680                 g_hash_table_remove( jd->buddies, bud->bare_jid );
    681                 g_free( bud->bare_jid );
    682                
     669                g_hash_table_remove(jd->buddies, bud->bare_jid);
     670                g_free(bud->bare_jid);
     671
    683672                /* Deallocate the linked list of resources. */
    684                 while( bud )
    685                 {
     673                while (bud) {
    686674                        /* ext_jid && anonymous means that this buddy is
    687675                           specific to one groupchat (the one we're
    688676                           currently cleaning up) so it can be deleted
    689677                           completely. */
    690                         if( bud->ext_jid && bud->flags & JBFLAG_IS_ANONYMOUS )
    691                                 imcb_remove_buddy( ic, bud->ext_jid, NULL );
    692                        
     678                        if (bud->ext_jid && bud->flags & JBFLAG_IS_ANONYMOUS) {
     679                                imcb_remove_buddy(ic, bud->ext_jid, NULL);
     680                        }
     681
    693682                        next = bud->next;
    694                         g_free( bud->ext_jid );
    695                         g_free( bud->full_jid );
    696                         g_free( bud->away_message );
    697                         g_free( bud );
     683                        g_free(bud->ext_jid);
     684                        g_free(bud->full_jid);
     685                        g_free(bud->away_message);
     686                        g_free(bud);
    698687                        bud = next;
    699688                }
    700                
     689
    701690                return 1;
    702         }
    703         else
    704         {
     691        } else {
    705692                return 0;
    706693        }
    707694}
    708695
    709 static gboolean jabber_buddy_remove_all_cb( gpointer key, gpointer value, gpointer data )
     696static gboolean jabber_buddy_remove_all_cb(gpointer key, gpointer value, gpointer data)
    710697{
    711698        struct jabber_buddy *bud, *next;
    712        
     699
    713700        bud = value;
    714         if( bud->bare_jid != bud->full_jid )
    715                 g_free( bud->bare_jid );
    716         while( bud )
    717         {
     701        if (bud->bare_jid != bud->full_jid) {
     702                g_free(bud->bare_jid);
     703        }
     704        while (bud) {
    718705                next = bud->next;
    719                 g_free( bud->ext_jid );
    720                 g_free( bud->full_jid );
    721                 g_free( bud->away_message );
    722                 g_free( bud );
     706                g_free(bud->ext_jid);
     707                g_free(bud->full_jid);
     708                g_free(bud->away_message);
     709                g_free(bud);
    723710                bud = next;
    724711        }
    725        
     712
    726713        return TRUE;
    727714}
    728715
    729 void jabber_buddy_remove_all( struct im_connection *ic )
     716void jabber_buddy_remove_all(struct im_connection *ic)
    730717{
    731718        struct jabber_data *jd = ic->proto_data;
    732        
    733         g_hash_table_foreach_remove( jd->buddies, jabber_buddy_remove_all_cb, NULL );
    734         g_hash_table_destroy( jd->buddies );
    735 }
    736 
    737 time_t jabber_get_timestamp( struct xt_node *xt )
     719
     720        g_hash_table_foreach_remove(jd->buddies, jabber_buddy_remove_all_cb, NULL);
     721        g_hash_table_destroy(jd->buddies);
     722}
     723
     724time_t jabber_get_timestamp(struct xt_node *xt)
    738725{
    739726        struct xt_node *c;
     
    744731
    745732        /* XEP-0091 has <x> */
    746         c = xt_find_node_by_attr( xt->children, "x", "xmlns", XMLNS_DELAY_OLD );
    747 
    748         if( !c || !( s = xt_find_attr( c, "stamp" ) ) ) {
     733        c = xt_find_node_by_attr(xt->children, "x", "xmlns", XMLNS_DELAY_OLD);
     734
     735        if (!c || !(s = xt_find_attr(c, "stamp"))) {
    749736                is_old = FALSE;
    750737
    751738                /* XEP-0203 has <delay> */
    752                 c = xt_find_node_by_attr( xt->children, "delay", "xmlns", XMLNS_DELAY );
    753                 if( !c || !( s = xt_find_attr( c, "stamp" ) ) ) {
     739                c = xt_find_node_by_attr(xt->children, "delay", "xmlns", XMLNS_DELAY);
     740                if (!c || !(s = xt_find_attr(c, "stamp"))) {
    754741                        return 0;
    755742                }
    756743        }
    757        
    758         memset( &tp, 0, sizeof( tp ) );
     744
     745        memset(&tp, 0, sizeof(tp));
    759746
    760747        /* The other main difference between XEPs is the timestamp format */
    761748        format = (is_old) ? "%4d%2d%2dT%2d:%2d:%2d" : "%4d-%2d-%2dT%2d:%2d:%2dZ";
    762749
    763         if( sscanf( s, format, &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
    764                                &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) != 6 )
     750        if (sscanf(s, format, &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
     751                   &tp.tm_hour, &tp.tm_min, &tp.tm_sec) != 6) {
    765752                return 0;
    766        
     753        }
     754
    767755        tp.tm_year -= 1900;
    768         tp.tm_mon --;
    769        
    770         return mktime_utc( &tp );
    771 }
    772 
    773 struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns )
     756        tp.tm_mon--;
     757
     758        return mktime_utc(&tp);
     759}
     760
     761struct jabber_error *jabber_error_parse(struct xt_node *node, char *xmlns)
    774762{
    775763        struct jabber_error *err;
    776764        struct xt_node *c;
    777765        char *s;
    778        
    779         if( node == NULL )
     766
     767        if (node == NULL) {
    780768                return NULL;
    781        
    782         err = g_new0( struct jabber_error, 1 );
    783         err->type = xt_find_attr( node, "type" );
    784        
    785         for( c = node->children; c; c = c->next )
    786         {
    787                 if( !( s = xt_find_attr( c, "xmlns" ) ) ||
    788                     strcmp( s, xmlns ) != 0 )
     769        }
     770
     771        err = g_new0(struct jabber_error, 1);
     772        err->type = xt_find_attr(node, "type");
     773
     774        for (c = node->children; c; c = c->next) {
     775                if (!(s = xt_find_attr(c, "xmlns")) ||
     776                    strcmp(s, xmlns) != 0) {
    789777                        continue;
    790                
    791                 if( strcmp( c->name, "text" ) != 0 )
    792                 {
     778                }
     779
     780                if (strcmp(c->name, "text") != 0) {
    793781                        err->code = c->name;
    794782                }
    795783                /* Only use the text if it doesn't have an xml:lang attribute,
    796784                   if it's empty or if it's set to something English. */
    797                 else if( !( s = xt_find_attr( c, "xml:lang" ) ) ||
    798                          !*s || strncmp( s, "en", 2 ) == 0 )
    799                 {
     785                else if (!(s = xt_find_attr(c, "xml:lang")) ||
     786                         !*s || strncmp(s, "en", 2) == 0) {
    800787                        err->text = c->text;
    801788                }
    802789        }
    803        
     790
    804791        return err;
    805792}
    806793
    807 void jabber_error_free( struct jabber_error *err )
    808 {
    809         g_free( err );
    810 }
    811 
    812 gboolean jabber_set_me( struct im_connection *ic, const char *me )
     794void jabber_error_free(struct jabber_error *err)
     795{
     796        g_free(err);
     797}
     798
     799gboolean jabber_set_me(struct im_connection *ic, const char *me)
    813800{
    814801        struct jabber_data *jd = ic->proto_data;
    815        
    816         if( strchr( me, '@' ) == NULL )
     802
     803        if (strchr(me, '@') == NULL) {
    817804                return FALSE;
    818        
    819         g_free( jd->username );
    820         g_free( jd->me );
    821        
    822         jd->me = jabber_normalize( me );
    823         jd->server = strchr( jd->me, '@' );
    824         jd->username = g_strndup( jd->me, jd->server - jd->me );
    825         jd->server ++;
     805        }
     806
     807        g_free(jd->username);
     808        g_free(jd->me);
     809
     810        jd->me = jabber_normalize(me);
     811        jd->server = strchr(jd->me, '@');
     812        jd->username = g_strndup(jd->me, jd->server - jd->me);
     813        jd->server++;
    826814
    827815        /* Set the "internal" account username, for groupchats */
    828         g_free( jd->internal_jid );
    829         jd->internal_jid = g_strdup( jd->me );
    830        
     816        g_free(jd->internal_jid);
     817        jd->internal_jid = g_strdup(jd->me);
     818
    831819        return TRUE;
    832820}
  • protocols/jabber/message.c

    raf359b4 r5ebff60  
    2424#include "jabber.h"
    2525
    26 xt_status jabber_pkt_message( struct xt_node *node, gpointer data )
     26xt_status jabber_pkt_message(struct xt_node *node, gpointer data)
    2727{
    2828        struct im_connection *ic = data;
    29         char *from = xt_find_attr( node, "from" );
    30         char *type = xt_find_attr( node, "type" );
    31         char *id = xt_find_attr( node, "id" );
    32         struct xt_node *body = xt_find_node( node->children, "body" ), *c;
    33         struct xt_node *request = xt_find_node( node->children, "request" );
     29        char *from = xt_find_attr(node, "from");
     30        char *type = xt_find_attr(node, "type");
     31        char *id = xt_find_attr(node, "id");
     32        struct xt_node *body = xt_find_node(node->children, "body"), *c;
     33        struct xt_node *request = xt_find_node(node->children, "request");
    3434        struct jabber_buddy *bud = NULL;
    3535        char *s, *room = NULL, *reason = NULL;
    36        
    37         if( !from )
     36
     37        if (!from) {
    3838                return XT_HANDLED; /* Consider this packet corrupted. */
    3939
    40         if( request && id )
    41         {
     40        }
     41        if (request && id) {
    4242                /* Send a message receipt (XEP-0184), looking like this:
    4343                 * <message
     
    4848                 * </message> */
    4949                struct xt_node *received, *receipt;
    50                
    51                 received = xt_new_node( "received", NULL, NULL );
    52                 xt_add_attr( received, "xmlns", XMLNS_RECEIPTS );
    53                 xt_add_attr( received, "id", id );
    54                 receipt = jabber_make_packet( "message", NULL, from, received );
    5550
    56                 jabber_write_packet( ic, receipt );
    57                 xt_free_node( receipt );
     51                received = xt_new_node("received", NULL, NULL);
     52                xt_add_attr(received, "xmlns", XMLNS_RECEIPTS);
     53                xt_add_attr(received, "id", id);
     54                receipt = jabber_make_packet("message", NULL, from, received);
     55
     56                jabber_write_packet(ic, receipt);
     57                xt_free_node(receipt);
    5858        }
    59        
    60         bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT );
    61        
    62         if( type && strcmp( type, "error" ) == 0 )
    63         {
     59
     60        bud = jabber_buddy_by_jid(ic, from, GET_BUDDY_EXACT);
     61
     62        if (type && strcmp(type, "error") == 0) {
    6463                /* Handle type=error packet. */
    65         }
    66         else if( type && from && strcmp( type, "groupchat" ) == 0 )
    67         {
    68                 jabber_chat_pkt_message( ic, bud, node );
    69         }
    70         else /* "chat", "normal", "headline", no-type or whatever. Should all be pretty similar. */
    71         {
    72                 GString *fullmsg = g_string_new( "" );
     64        } else if (type && from && strcmp(type, "groupchat") == 0) {
     65                jabber_chat_pkt_message(ic, bud, node);
     66        } else { /* "chat", "normal", "headline", no-type or whatever. Should all be pretty similar. */
     67                GString *fullmsg = g_string_new("");
    7368
    74                 for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
    75                 {
    76                         char *ns = xt_find_attr( c, "xmlns" );
     69                for (c = node->children; (c = xt_find_node(c, "x")); c = c->next) {
     70                        char *ns = xt_find_attr(c, "xmlns");
    7771                        struct xt_node *inv;
    78                        
    79                         if( ns && strcmp( ns, XMLNS_MUC_USER ) == 0 &&
    80                             ( inv = xt_find_node( c->children, "invite" ) ) )
    81                         {
     72
     73                        if (ns && strcmp(ns, XMLNS_MUC_USER) == 0 &&
     74                            (inv = xt_find_node(c->children, "invite"))) {
    8275                                /* This is an invitation. Set some vars which
    8376                                   will be passed to imcb_chat_invite() below. */
    8477                                room = from;
    85                                 if( ( from = xt_find_attr( inv, "from" ) ) == NULL )
     78                                if ((from = xt_find_attr(inv, "from")) == NULL) {
    8679                                        from = room;
    87                                 if( ( inv = xt_find_node( inv->children, "reason" ) ) && inv->text_len > 0 )
     80                                }
     81                                if ((inv = xt_find_node(inv->children, "reason")) && inv->text_len > 0) {
    8882                                        reason = inv->text;
     83                                }
    8984                        }
    9085                }
    91                
    92                 if( ( s = strchr( from, '/' ) ) )
    93                 {
    94                         if( bud )
    95                         {
    96                                 bud->last_msg = time( NULL );
     86
     87                if ((s = strchr(from, '/'))) {
     88                        if (bud) {
     89                                bud->last_msg = time(NULL);
    9790                                from = bud->ext_jid ? bud->ext_jid : bud->bare_jid;
    98                         }
    99                         else
     91                        } else {
    10092                                *s = 0; /* We need to generate a bare JID now. */
    101                 }
    102                
    103                 if( type && strcmp( type, "headline" ) == 0 )
    104                 {
    105                         if( ( c = xt_find_node( node->children, "subject" ) ) && c->text_len > 0 )
    106                                 g_string_append_printf( fullmsg, "Headline: %s\n", c->text );
    107                        
    108                         /* <x xmlns="jabber:x:oob"><url>http://....</url></x> can contain a URL, it seems. */
    109                         for( c = node->children; c; c = c->next )
    110                         {
    111                                 struct xt_node *url;
    112                                
    113                                 if( ( url = xt_find_node( c->children, "url" ) ) && url->text_len > 0 )
    114                                         g_string_append_printf( fullmsg, "URL: %s\n", url->text );
    11593                        }
    11694                }
    117                 else if( ( c = xt_find_node( node->children, "subject" ) ) && c->text_len > 0 &&
    118                          ( !bud || !( bud->flags & JBFLAG_HIDE_SUBJECT ) ) )
    119                 {
    120                         g_string_append_printf( fullmsg, "<< \002BitlBee\002 - Message with subject: %s >>\n", c->text );
    121                         if( bud )
     95
     96                if (type && strcmp(type, "headline") == 0) {
     97                        if ((c = xt_find_node(node->children, "subject")) && c->text_len > 0) {
     98                                g_string_append_printf(fullmsg, "Headline: %s\n", c->text);
     99                        }
     100
     101                        /* <x xmlns="jabber:x:oob"><url>http://....</url></x> can contain a URL, it seems. */
     102                        for (c = node->children; c; c = c->next) {
     103                                struct xt_node *url;
     104
     105                                if ((url = xt_find_node(c->children, "url")) && url->text_len > 0) {
     106                                        g_string_append_printf(fullmsg, "URL: %s\n", url->text);
     107                                }
     108                        }
     109                } else if ((c = xt_find_node(node->children, "subject")) && c->text_len > 0 &&
     110                           (!bud || !(bud->flags & JBFLAG_HIDE_SUBJECT))) {
     111                        g_string_append_printf(fullmsg, "<< \002BitlBee\002 - Message with subject: %s >>\n", c->text);
     112                        if (bud) {
    122113                                bud->flags |= JBFLAG_HIDE_SUBJECT;
    123                 }
    124                 else if( bud && !c )
    125                 {
     114                        }
     115                } else if (bud && !c) {
    126116                        /* Yeah, possibly we're hiding changes to this field now. But nobody uses
    127117                           this for anything useful anyway, except GMail when people reply to an
     
    130120                        bud->flags &= ~JBFLAG_HIDE_SUBJECT;
    131121                }
    132                
    133                 if( body && body->text_len > 0 ) /* Could be just a typing notification. */
    134                         fullmsg = g_string_append( fullmsg, body->text );
    135                
    136                 if( fullmsg->len > 0 )
    137                         imcb_buddy_msg( ic, from, fullmsg->str,
    138                                         0, jabber_get_timestamp( node ) );
    139                 if( room )
    140                         imcb_chat_invite( ic, room, from, reason );
    141                
    142                 g_string_free( fullmsg, TRUE );
    143                
     122
     123                if (body && body->text_len > 0) { /* Could be just a typing notification. */
     124                        fullmsg = g_string_append(fullmsg, body->text);
     125                }
     126
     127                if (fullmsg->len > 0) {
     128                        imcb_buddy_msg(ic, from, fullmsg->str,
     129                                       0, jabber_get_timestamp(node));
     130                }
     131                if (room) {
     132                        imcb_chat_invite(ic, room, from, reason);
     133                }
     134
     135                g_string_free(fullmsg, TRUE);
     136
    144137                /* Handling of incoming typing notifications. */
    145                 if( bud == NULL )
    146                 {
     138                if (bud == NULL) {
    147139                        /* Can't handle these for unknown buddies. */
    148                 }
    149                 else if( xt_find_node( node->children, "composing" ) )
    150                 {
     140                } else if (xt_find_node(node->children, "composing")) {
    151141                        bud->flags |= JBFLAG_DOES_XEP85;
    152                         imcb_buddy_typing( ic, from, OPT_TYPING );
     142                        imcb_buddy_typing(ic, from, OPT_TYPING);
    153143                }
    154144                /* No need to send a "stopped typing" signal when there's a message. */
    155                 else if( xt_find_node( node->children, "active" ) && ( body == NULL ) )
    156                 {
     145                else if (xt_find_node(node->children, "active") && (body == NULL)) {
    157146                        bud->flags |= JBFLAG_DOES_XEP85;
    158                         imcb_buddy_typing( ic, from, 0 );
     147                        imcb_buddy_typing(ic, from, 0);
     148                } else if (xt_find_node(node->children, "paused")) {
     149                        bud->flags |= JBFLAG_DOES_XEP85;
     150                        imcb_buddy_typing(ic, from, OPT_THINKING);
    159151                }
    160                 else if( xt_find_node( node->children, "paused" ) )
    161                 {
    162                         bud->flags |= JBFLAG_DOES_XEP85;
    163                         imcb_buddy_typing( ic, from, OPT_THINKING );
     152
     153                if (s) {
     154                        *s = '/'; /* And convert it back to a full JID. */
    164155                }
    165                
    166                 if( s )
    167                         *s = '/'; /* And convert it back to a full JID. */
    168156        }
    169        
     157
    170158        return XT_HANDLED;
    171159}
  • protocols/jabber/presence.c

    raf359b4 r5ebff60  
    2424#include "jabber.h"
    2525
    26 xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )
     26xt_status jabber_pkt_presence(struct xt_node *node, gpointer data)
    2727{
    2828        struct im_connection *ic = data;
    29         char *from = xt_find_attr( node, "from" );
    30         char *type = xt_find_attr( node, "type" );      /* NULL should mean the person is online. */
     29        char *from = xt_find_attr(node, "from");
     30        char *type = xt_find_attr(node, "type");        /* NULL should mean the person is online. */
    3131        struct xt_node *c, *cap;
    3232        struct jabber_buddy *bud, *send_presence = NULL;
    3333        int is_chat = 0;
    3434        char *s;
    35        
    36         if( !from )
     35
     36        if (!from) {
    3737                return XT_HANDLED;
    38        
    39         if( ( s = strchr( from, '/' ) ) )
    40         {
     38        }
     39
     40        if ((s = strchr(from, '/'))) {
    4141                *s = 0;
    42                 if( jabber_chat_by_jid( ic, from ) )
     42                if (jabber_chat_by_jid(ic, from)) {
    4343                        is_chat = 1;
     44                }
    4445                *s = '/';
    4546        }
    46        
    47         if( type == NULL )
    48         {
    49                 if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
    50                 {
     47
     48        if (type == NULL) {
     49                if (!(bud = jabber_buddy_by_jid(ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT))) {
    5150                        /*
    5251                        imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from );
     
    5453                        return XT_HANDLED;
    5554                }
    56                
    57                 g_free( bud->away_message );
    58                 if( ( c = xt_find_node( node->children, "status" ) ) && c->text_len > 0 )
    59                         bud->away_message = g_strdup( c->text );
    60                 else
     55
     56                g_free(bud->away_message);
     57                if ((c = xt_find_node(node->children, "status")) && c->text_len > 0) {
     58                        bud->away_message = g_strdup(c->text);
     59                } else {
    6160                        bud->away_message = NULL;
    62                
    63                 if( ( c = xt_find_node( node->children, "show" ) ) && c->text_len > 0 )
    64                 {
    65                         bud->away_state = (void*) jabber_away_state_by_code( c->text );
    66                 }
    67                 else
    68                 {
     61                }
     62
     63                if ((c = xt_find_node(node->children, "show")) && c->text_len > 0) {
     64                        bud->away_state = (void *) jabber_away_state_by_code(c->text);
     65                } else {
    6966                        bud->away_state = NULL;
    7067                }
    71                
    72                 if( ( c = xt_find_node( node->children, "priority" ) ) && c->text_len > 0 )
    73                         bud->priority = atoi( c->text );
    74                 else
     68
     69                if ((c = xt_find_node(node->children, "priority")) && c->text_len > 0) {
     70                        bud->priority = atoi(c->text);
     71                } else {
    7572                        bud->priority = 0;
    76                
    77                 if( bud && ( cap = xt_find_node( node->children, "c" ) ) &&
    78                     ( s = xt_find_attr( cap, "xmlns" ) ) && strcmp( s, XMLNS_CAPS ) == 0 )
    79                 {
     73                }
     74
     75                if (bud && (cap = xt_find_node(node->children, "c")) &&
     76                    (s = xt_find_attr(cap, "xmlns")) && strcmp(s, XMLNS_CAPS) == 0) {
    8077                        /* This <presence> stanza includes an XEP-0115
    8178                           capabilities part. Not too interesting, but we can
    8279                           see if it has an ext= attribute. */
    83                         s = xt_find_attr( cap, "ext" );
    84                         if( s && ( strstr( s, "cstates" ) || strstr( s, "chatstate" ) ) )
     80                        s = xt_find_attr(cap, "ext");
     81                        if (s && (strstr(s, "cstates") || strstr(s, "chatstate"))) {
    8582                                bud->flags |= JBFLAG_DOES_XEP85;
    86                        
     83                        }
     84
    8785                        /* This field can contain more information like xhtml
    8886                           support, but we don't support that ourselves.
    8987                           Officially the ext= tag was deprecated, but enough
    9088                           clients do send it.
    91                            
     89
    9290                           (I'm aware that this is not the right way to use
    9391                           this field.) See for an explanation of ext=:
    9492                           http://www.xmpp.org/extensions/attic/xep-0115-1.3.html*/
    9593                }
    96                
    97                 if( is_chat )
    98                         jabber_chat_pkt_presence( ic, bud, node );
    99                 else
    100                         send_presence = jabber_buddy_by_jid( ic, bud->bare_jid, 0 );
    101         }
    102         else if( strcmp( type, "unavailable" ) == 0 )
    103         {
    104                 if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL )
    105                 {
     94
     95                if (is_chat) {
     96                        jabber_chat_pkt_presence(ic, bud, node);
     97                } else {
     98                        send_presence = jabber_buddy_by_jid(ic, bud->bare_jid, 0);
     99                }
     100        } else if (strcmp(type, "unavailable") == 0) {
     101                if ((bud = jabber_buddy_by_jid(ic, from, 0)) == NULL) {
    106102                        /*
    107103                        imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from );
     
    109105                        return XT_HANDLED;
    110106                }
    111                
     107
    112108                /* Handle this before we delete the JID. */
    113                 if( is_chat )
    114                 {
    115                         jabber_chat_pkt_presence( ic, bud, node );
    116                 }
    117                
    118                 if( strchr( from, '/' ) == NULL )
     109                if (is_chat) {
     110                        jabber_chat_pkt_presence(ic, bud, node);
     111                }
     112
     113                if (strchr(from, '/') == NULL) {
    119114                        /* Sometimes servers send a type="unavailable" from a
    120115                           bare JID, which should mean that suddenly all
    121116                           resources for this JID disappeared. */
    122                         jabber_buddy_remove_bare( ic, from );
    123                 else
    124                         jabber_buddy_remove( ic, from );
    125                
    126                 if( is_chat )
    127                 {
     117                        jabber_buddy_remove_bare(ic, from);
     118                } else {
     119                        jabber_buddy_remove(ic, from);
     120                }
     121
     122                if (is_chat) {
    128123                        /* Nothing else to do for now? */
    129                 }
    130                 else if( ( s = strchr( from, '/' ) ) )
    131                 {
     124                } else if ((s = strchr(from, '/'))) {
    132125                        *s = 0;
    133                
     126
    134127                        /* If another resource is still available, send its presence
    135128                           information. */
    136                         if( ( send_presence = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL )
    137                         {
     129                        if ((send_presence = jabber_buddy_by_jid(ic, from, 0)) == NULL) {
    138130                                /* Otherwise, count him/her as offline now. */
    139                                 imcb_buddy_status( ic, from, 0, NULL, NULL );
     131                                imcb_buddy_status(ic, from, 0, NULL, NULL);
    140132                        }
    141                        
     133
    142134                        *s = '/';
    143                 }
    144                 else
    145                 {
    146                         imcb_buddy_status( ic, from, 0, NULL, NULL );
    147                 }
    148         }
    149         else if( strcmp( type, "subscribe" ) == 0 )
    150         {
    151                 jabber_buddy_ask( ic, from );
    152         }
    153         else if( strcmp( type, "subscribed" ) == 0 )
    154         {
     135                } else {
     136                        imcb_buddy_status(ic, from, 0, NULL, NULL);
     137                }
     138        } else if (strcmp(type, "subscribe") == 0) {
     139                jabber_buddy_ask(ic, from);
     140        } else if (strcmp(type, "subscribed") == 0) {
    155141                /* Not sure about this one, actually... */
    156                 imcb_log( ic, "%s just accepted your authorization request", from );
    157         }
    158         else if( strcmp( type, "unsubscribe" ) == 0 || strcmp( type, "unsubscribed" ) == 0 )
    159         {
     142                imcb_log(ic, "%s just accepted your authorization request", from);
     143        } else if (strcmp(type, "unsubscribe") == 0 || strcmp(type, "unsubscribed") == 0) {
    160144                /* Do nothing here. Plenty of control freaks or over-curious
    161145                   souls get excited when they can see who still has them in
     
    163147                   got the impression that those are the people who get
    164148                   removed from many buddy lists for "some" reason...
    165                    
     149
    166150                   If you're one of those people, this is your chance to write
    167151                   your first line of code in C... */
    168         }
    169         else if( strcmp( type, "error" ) == 0 )
    170         {
    171                 return jabber_cache_handle_packet( ic, node );
    172                
     152        } else if (strcmp(type, "error") == 0) {
     153                return jabber_cache_handle_packet(ic, node);
     154
    173155                /*
    174156                struct jabber_error *err;
    175157                if( ( c = xt_find_node( node->children, "error" ) ) )
    176158                {
    177                         err = jabber_error_parse( c, XMLNS_STANZA_ERROR );
    178                         imcb_error( ic, "Stanza (%s) error: %s%s%s", node->name,
    179                                     err->code, err->text ? ": " : "",
    180                                     err->text ? err->text : "" );
    181                         jabber_error_free( err );
     159                        err = jabber_error_parse( c, XMLNS_STANZA_ERROR );
     160                        imcb_error( ic, "Stanza (%s) error: %s%s%s", node->name,
     161                                    err->code, err->text ? ": " : "",
     162                                    err->text ? err->text : "" );
     163                        jabber_error_free( err );
    182164                } */
    183165        }
    184166
    185         if( send_presence )
    186         {
     167        if (send_presence) {
    187168                int is_away = 0;
    188169
    189                 if( send_presence->away_state &&
    190                     strcmp( send_presence->away_state->code, "chat" ) != 0 )
     170                if (send_presence->away_state &&
     171                    strcmp(send_presence->away_state->code, "chat") != 0) {
    191172                        is_away = OPT_AWAY;
    192 
    193                 imcb_buddy_status( ic, send_presence->bare_jid, OPT_LOGGED_IN | is_away,
    194                                    is_away ? send_presence->away_state->full_name : NULL,
    195                                    send_presence->away_message );
    196         }
    197        
     173                }
     174
     175                imcb_buddy_status(ic, send_presence->bare_jid, OPT_LOGGED_IN | is_away,
     176                                  is_away ? send_presence->away_state->full_name : NULL,
     177                                  send_presence->away_message);
     178        }
     179
    198180        return XT_HANDLED;
    199181}
     
    201183/* Whenever presence information is updated, call this function to inform the
    202184   server. */
    203 int presence_send_update( struct im_connection *ic )
     185int presence_send_update(struct im_connection *ic)
    204186{
    205187        struct jabber_data *jd = ic->proto_data;
     
    207189        GSList *l;
    208190        int st;
    209        
    210         node = jabber_make_packet( "presence", NULL, NULL, NULL );
    211         xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) );
    212         if( jd->away_state )
    213                 xt_add_child( node, xt_new_node( "show", jd->away_state->code, NULL ) );
    214         if( jd->away_message )
    215                 xt_add_child( node, xt_new_node( "status", jd->away_message, NULL ) );
    216        
     191
     192        node = jabber_make_packet("presence", NULL, NULL, NULL);
     193        xt_add_child(node, xt_new_node("priority", set_getstr(&ic->acc->set, "priority"), NULL));
     194        if (jd->away_state) {
     195                xt_add_child(node, xt_new_node("show", jd->away_state->code, NULL));
     196        }
     197        if (jd->away_message) {
     198                xt_add_child(node, xt_new_node("status", jd->away_message, NULL));
     199        }
     200
    217201        /* This makes the packet slightly bigger, but clients interested in
    218202           capabilities can now cache the discovery info. This reduces the
    219203           usual post-login iq-flood. See XEP-0115. At least libpurple and
    220204           Trillian seem to do this right. */
    221         cap = xt_new_node( "c", NULL, NULL );
    222         xt_add_attr( cap, "xmlns", XMLNS_CAPS );
    223         xt_add_attr( cap, "node", "http://bitlbee.org/xmpp/caps" );
    224         xt_add_attr( cap, "ver", BITLBEE_VERSION ); /* The XEP wants this hashed, but nobody's doing that. */
    225         xt_add_child( node, cap );
    226        
    227         st = jabber_write_packet( ic, node );
    228        
     205        cap = xt_new_node("c", NULL, NULL);
     206        xt_add_attr(cap, "xmlns", XMLNS_CAPS);
     207        xt_add_attr(cap, "node", "http://bitlbee.org/xmpp/caps");
     208        xt_add_attr(cap, "ver", BITLBEE_VERSION);  /* The XEP wants this hashed, but nobody's doing that. */
     209        xt_add_child(node, cap);
     210
     211        st = jabber_write_packet(ic, node);
     212
    229213        /* Have to send this update to all groupchats too, the server won't
    230214           do this automatically. */
    231         for( l = ic->groupchats; l && st; l = l->next )
    232         {
     215        for (l = ic->groupchats; l && st; l = l->next) {
    233216                struct groupchat *c = l->data;
    234217                struct jabber_chat *jc = c->data;
    235                
    236                 xt_add_attr( node, "to", jc->my_full_jid );
    237                 st = jabber_write_packet( ic, node );
    238         }
    239        
    240         xt_free_node( node );
     218
     219                xt_add_attr(node, "to", jc->my_full_jid);
     220                st = jabber_write_packet(ic, node);
     221        }
     222
     223        xt_free_node(node);
    241224        return st;
    242225}
    243226
    244227/* Send a subscribe/unsubscribe request to a buddy. */
    245 int presence_send_request( struct im_connection *ic, char *handle, char *request )
     228int presence_send_request(struct im_connection *ic, char *handle, char *request)
    246229{
    247230        struct xt_node *node;
    248231        int st;
    249        
    250         node = jabber_make_packet( "presence", NULL, NULL, NULL );
    251         xt_add_attr( node, "to", handle );
    252         xt_add_attr( node, "type", request );
    253        
    254         st = jabber_write_packet( ic, node );
    255        
    256         xt_free_node( node );
     232
     233        node = jabber_make_packet("presence", NULL, NULL, NULL);
     234        xt_add_attr(node, "to", handle);
     235        xt_add_attr(node, "type", request);
     236
     237        st = jabber_write_packet(ic, node);
     238
     239        xt_free_node(node);
    257240        return st;
    258241}
  • protocols/jabber/s5bytestream.c

    raf359b4 r5ebff60  
    3434        GSList *streamhosts;
    3535
    36         enum
    37         {
    38                 BS_PHASE_CONNECT,
    39                 BS_PHASE_CONNECTED,
    40                 BS_PHASE_REQUEST,
     36        enum {
     37                BS_PHASE_CONNECT,
     38                BS_PHASE_CONNECTED,
     39                BS_PHASE_REQUEST,
    4140                BS_PHASE_REPLY
    4241        } phase;
     
    4645
    4746        gint connect_timeout;
    48        
     47
    4948        char peek_buf[64];
    5049        int peek_buf_len;
    5150};
    5251
    53 struct socks5_message
    54 {
     52struct socks5_message {
    5553        unsigned char ver;
    56         union
    57         {
     54        union {
    5855                unsigned char cmd;
    5956                unsigned char rep;
     
    6461        unsigned char address[40];
    6562        in_port_t port;
    66 } __attribute__ ((packed)); 
     63} __attribute__ ((packed));
    6764
    6865char *socks5_reply_code[] = {
     
    7673        "Command not supported",
    7774        "Address type not supported",
    78         "unassigned"};
     75        "unassigned"
     76};
    7977
    8078/* connect() timeout in seconds. */
     
    8583/* very useful */
    8684#define ASSERTSOCKOP(op, msg) \
    87         if( (op) == -1 ) \
    88                 return jabber_bs_abort( bt , msg ": %s", strerror( errno ) );
    89 
    90 gboolean jabber_bs_abort( struct bs_transfer *bt, char *format, ... );
    91 void jabber_bs_canceled( file_transfer_t *ft , char *reason );
    92 void jabber_bs_free_transfer( file_transfer_t *ft );
    93 gboolean jabber_bs_connect_timeout( gpointer data, gint fd, b_input_condition cond );
    94 gboolean jabber_bs_poll( struct bs_transfer *bt, int fd, short *revents );
    95 gboolean jabber_bs_peek( struct bs_transfer *bt, void *buffer, int buflen );
    96 
    97 void jabber_bs_recv_answer_request( struct bs_transfer *bt );
    98 gboolean jabber_bs_recv_read( gpointer data, gint fd, b_input_condition cond );
    99 gboolean jabber_bs_recv_write_request( file_transfer_t *ft );
    100 gboolean jabber_bs_recv_handshake( gpointer data, gint fd, b_input_condition cond );
    101 gboolean jabber_bs_recv_handshake_abort( struct bs_transfer *bt, char *error );
    102 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode );
    103 
    104 gboolean jabber_bs_send_handshake_abort( struct bs_transfer *bt, char *error );
    105 gboolean jabber_bs_send_request( struct jabber_transfer *tf, GSList *streamhosts );
    106 gboolean jabber_bs_send_handshake( gpointer data, gint fd, b_input_condition cond );
    107 static xt_status jabber_bs_send_handle_activate( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
    108 void jabber_bs_send_activate( struct bs_transfer *bt );
     85        if ((op) == -1) { \
     86                return jabber_bs_abort(bt, msg ": %s", strerror(errno)); }
     87
     88gboolean jabber_bs_abort(struct bs_transfer *bt, char *format, ...);
     89void jabber_bs_canceled(file_transfer_t *ft, char *reason);
     90void jabber_bs_free_transfer(file_transfer_t *ft);
     91gboolean jabber_bs_connect_timeout(gpointer data, gint fd, b_input_condition cond);
     92gboolean jabber_bs_poll(struct bs_transfer *bt, int fd, short *revents);
     93gboolean jabber_bs_peek(struct bs_transfer *bt, void *buffer, int buflen);
     94
     95void jabber_bs_recv_answer_request(struct bs_transfer *bt);
     96gboolean jabber_bs_recv_read(gpointer data, gint fd, b_input_condition cond);
     97gboolean jabber_bs_recv_write_request(file_transfer_t *ft);
     98gboolean jabber_bs_recv_handshake(gpointer data, gint fd, b_input_condition cond);
     99gboolean jabber_bs_recv_handshake_abort(struct bs_transfer *bt, char *error);
     100int jabber_bs_recv_request(struct im_connection *ic, struct xt_node *node, struct xt_node *qnode);
     101
     102gboolean jabber_bs_send_handshake_abort(struct bs_transfer *bt, char *error);
     103gboolean jabber_bs_send_request(struct jabber_transfer *tf, GSList *streamhosts);
     104gboolean jabber_bs_send_handshake(gpointer data, gint fd, b_input_condition cond);
     105static xt_status jabber_bs_send_handle_activate(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     106void jabber_bs_send_activate(struct bs_transfer *bt);
    109107
    110108/*
    111109 * Frees a bs_transfer struct and calls the SI free function
    112110 */
    113 void jabber_bs_free_transfer( file_transfer_t *ft) {
     111void jabber_bs_free_transfer(file_transfer_t *ft)
     112{
    114113        struct jabber_transfer *tf = ft->data;
    115114        struct bs_transfer *bt = tf->streamhandle;
    116115        jabber_streamhost_t *sh;
    117116
    118         if ( bt->connect_timeout )
    119         {
    120                 b_event_remove( bt->connect_timeout );
     117        if (bt->connect_timeout) {
     118                b_event_remove(bt->connect_timeout);
    121119                bt->connect_timeout = 0;
    122120        }
    123121
    124         if ( tf->watch_in )
    125         {
    126                 b_event_remove( tf->watch_in );
     122        if (tf->watch_in) {
     123                b_event_remove(tf->watch_in);
    127124                tf->watch_in = 0;
    128125        }
    129        
    130         if( tf->watch_out )
    131         {
    132                 b_event_remove( tf->watch_out );
     126
     127        if (tf->watch_out) {
     128                b_event_remove(tf->watch_out);
    133129                tf->watch_out = 0;
    134130        }
    135        
    136         g_free( bt->pseudoadr );
    137 
    138         while( bt->streamhosts )
    139         {
     131
     132        g_free(bt->pseudoadr);
     133
     134        while (bt->streamhosts) {
    140135                sh = bt->streamhosts->data;
    141                 bt->streamhosts = g_slist_remove( bt->streamhosts, sh );
    142                 g_free( sh->jid );
    143                 g_free( sh->host );
    144                 g_free( sh );
    145         }
    146        
    147         g_free( bt );
    148 
    149         jabber_si_free_transfer( ft );
     136                bt->streamhosts = g_slist_remove(bt->streamhosts, sh);
     137                g_free(sh->jid);
     138                g_free(sh->host);
     139                g_free(sh);
     140        }
     141
     142        g_free(bt);
     143
     144        jabber_si_free_transfer(ft);
    150145}
    151146
     
    154149 * writes it to buffer if that's the case.
    155150 */
    156 gboolean jabber_bs_peek( struct bs_transfer *bt, void *buffer, int buflen )
     151gboolean jabber_bs_peek(struct bs_transfer *bt, void *buffer, int buflen)
    157152{
    158153        int ret;
    159154        int fd = bt->tf->fd;
    160155
    161         if( buflen > sizeof( bt->peek_buf ) )
    162                 return jabber_bs_abort( bt, "BUG: %d > sizeof(peek_buf)", buflen );
    163 
    164         ASSERTSOCKOP( ret = recv( fd, bt->peek_buf + bt->peek_buf_len,
    165                 buflen - bt->peek_buf_len, 0 ), "recv() on SOCKS5 connection" );
    166 
    167         if( ret == 0 )
    168                 return jabber_bs_abort( bt, "Remote end closed connection" );
    169        
     156        if (buflen > sizeof(bt->peek_buf)) {
     157                return jabber_bs_abort(bt, "BUG: %d > sizeof(peek_buf)", buflen);
     158        }
     159
     160        ASSERTSOCKOP(ret = recv(fd, bt->peek_buf + bt->peek_buf_len,
     161                                buflen - bt->peek_buf_len, 0), "recv() on SOCKS5 connection");
     162
     163        if (ret == 0) {
     164                return jabber_bs_abort(bt, "Remote end closed connection");
     165        }
     166
    170167        bt->peek_buf_len += ret;
    171         memcpy( buffer, bt->peek_buf, bt->peek_buf_len );
    172        
    173         if( bt->peek_buf_len == buflen )
    174         {
     168        memcpy(buffer, bt->peek_buf, bt->peek_buf_len);
     169
     170        if (bt->peek_buf_len == buflen) {
    175171                /* If we have everything the caller wanted, reset the peek buffer. */
    176172                bt->peek_buf_len = 0;
    177173                return buflen;
    178         }
    179         else
     174        } else {
    180175                return bt->peek_buf_len;
    181 }
    182 
    183 
    184 /*
     176        }
     177}
     178
     179
     180/*
    185181 * This function is scheduled in bs_handshake via b_timeout_add after a (non-blocking) connect().
    186182 */
    187 gboolean jabber_bs_connect_timeout( gpointer data, gint fd, b_input_condition cond )
     183gboolean jabber_bs_connect_timeout(gpointer data, gint fd, b_input_condition cond)
    188184{
    189185        struct bs_transfer *bt = data;
     
    191187        bt->connect_timeout = 0;
    192188
    193         jabber_bs_abort( bt, "no connection after %d seconds", bt->tf->ft->sending ? JABBER_BS_LISTEN_TIMEOUT : JABBER_BS_CONTIMEOUT );
     189        jabber_bs_abort(bt, "no connection after %d seconds",
     190                        bt->tf->ft->sending ? JABBER_BS_LISTEN_TIMEOUT : JABBER_BS_CONTIMEOUT);
    194191
    195192        return FALSE;
    196193}
    197194
    198 /* 
     195/*
    199196 * Polls the socket, checks for errors and removes a connect timer
    200197 * if there is one.
    201198 */
    202 gboolean jabber_bs_poll( struct bs_transfer *bt, int fd, short *revents )
    203 {
    204         struct pollfd pfd = { .fd = fd, .events = POLLHUP|POLLERR };
    205        
    206         if ( bt->connect_timeout )
    207         {
    208                 b_event_remove( bt->connect_timeout );
     199gboolean jabber_bs_poll(struct bs_transfer *bt, int fd, short *revents)
     200{
     201        struct pollfd pfd = { .fd = fd, .events = POLLHUP | POLLERR };
     202
     203        if (bt->connect_timeout) {
     204                b_event_remove(bt->connect_timeout);
    209205                bt->connect_timeout = 0;
    210206        }
    211207
    212         ASSERTSOCKOP( poll( &pfd, 1, 0 ), "poll()" )
    213 
    214         if( pfd.revents & POLLERR )
    215         {
     208        ASSERTSOCKOP(poll(&pfd, 1, 0), "poll()")
     209
     210        if (pfd.revents & POLLERR) {
    216211                int sockerror;
    217                 socklen_t errlen = sizeof( sockerror );
    218 
    219                 if ( getsockopt( fd, SOL_SOCKET, SO_ERROR, &sockerror, &errlen ) )
    220                         return jabber_bs_abort( bt, "getsockopt() failed, unknown socket error during SOCKS5 handshake (weird!)" );
    221 
    222                 if ( bt->phase == BS_PHASE_CONNECTED )
    223                         return jabber_bs_abort( bt, "connect failed: %s", strerror( sockerror ) );
    224 
    225                 return jabber_bs_abort( bt, "Socket error during SOCKS5 handshake(weird!): %s", strerror( sockerror ) );
    226         }
    227 
    228         if( pfd.revents & POLLHUP )
    229                 return jabber_bs_abort( bt, "Remote end closed connection" );
    230        
     212                socklen_t errlen = sizeof(sockerror);
     213
     214                if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerror, &errlen)) {
     215                        return jabber_bs_abort(bt,
     216                                               "getsockopt() failed, unknown socket error during SOCKS5 handshake (weird!)");
     217                }
     218
     219                if (bt->phase == BS_PHASE_CONNECTED) {
     220                        return jabber_bs_abort(bt, "connect failed: %s", strerror(sockerror));
     221                }
     222
     223                return jabber_bs_abort(bt, "Socket error during SOCKS5 handshake(weird!): %s", strerror(sockerror));
     224        }
     225
     226        if (pfd.revents & POLLHUP) {
     227                return jabber_bs_abort(bt, "Remote end closed connection");
     228        }
     229
    231230        *revents = pfd.revents;
    232        
     231
    233232        return TRUE;
    234233}
     
    237236 * Used for receive and send path.
    238237 */
    239 gboolean jabber_bs_abort( struct bs_transfer *bt, char *format, ... )
     238gboolean jabber_bs_abort(struct bs_transfer *bt, char *format, ...)
    240239{
    241240        va_list params;
    242         va_start( params, format );
     241
     242        va_start(params, format);
    243243        char error[128];
    244244
    245         if( vsnprintf( error, 128, format, params ) < 0 )
    246                 sprintf( error, "internal error parsing error string (BUG)" );
    247         va_end( params );
    248         if( bt->tf->ft->sending )
    249                 return jabber_bs_send_handshake_abort( bt, error );
    250         else
    251                 return jabber_bs_recv_handshake_abort( bt, error );
     245        if (vsnprintf(error, 128, format, params) < 0) {
     246                sprintf(error, "internal error parsing error string (BUG)");
     247        }
     248        va_end(params);
     249        if (bt->tf->ft->sending) {
     250                return jabber_bs_send_handshake_abort(bt, error);
     251        } else {
     252                return jabber_bs_recv_handshake_abort(bt, error);
     253        }
    252254}
    253255
    254256/* Bad luck */
    255 void jabber_bs_canceled( file_transfer_t *ft , char *reason )
     257void jabber_bs_canceled(file_transfer_t *ft, char *reason)
    256258{
    257259        struct jabber_transfer *tf = ft->data;
    258260
    259         imcb_log( tf->ic, "File transfer aborted: %s", reason );
     261        imcb_log(tf->ic, "File transfer aborted: %s", reason);
    260262}
    261263
     
    263265 * Parses an incoming bytestream request and calls jabber_bs_handshake on success.
    264266 */
    265 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode)
     267int jabber_bs_recv_request(struct im_connection *ic, struct xt_node *node, struct xt_node *qnode)
    266268{
    267269        char *sid, *ini_jid, *tgt_jid, *mode, *iq_id;
     
    270272        GSList *tflist;
    271273        struct bs_transfer *bt;
    272         GSList *shlist=NULL;
     274        GSList *shlist = NULL;
    273275        struct xt_node *shnode;
    274276
     
    277279        unsigned char hash[20];
    278280        int i;
    279        
    280         if( !(iq_id   = xt_find_attr( node, "id" ) ) ||
    281             !(ini_jid = xt_find_attr( node, "from" ) ) ||
    282             !(tgt_jid = xt_find_attr( node, "to" ) ) ||
    283             !(sid     = xt_find_attr( qnode, "sid" ) ) )
    284         {
    285                 imcb_log( ic, "WARNING: Received incomplete SI bytestream request");
     281
     282        if (!(iq_id   = xt_find_attr(node, "id")) ||
     283            !(ini_jid = xt_find_attr(node, "from")) ||
     284            !(tgt_jid = xt_find_attr(node, "to")) ||
     285            !(sid     = xt_find_attr(qnode, "sid"))) {
     286                imcb_log(ic, "WARNING: Received incomplete SI bytestream request");
    286287                return XT_HANDLED;
    287288        }
    288289
    289         if( ( mode = xt_find_attr( qnode, "mode" ) ) &&
    290               ( strcmp( mode, "tcp" ) != 0 ) )
    291         {
    292                 imcb_log( ic, "WARNING: Received SI Request for unsupported bytestream mode %s", xt_find_attr( qnode, "mode" ) );
     290        if ((mode = xt_find_attr(qnode, "mode")) &&
     291            (strcmp(mode, "tcp") != 0)) {
     292                imcb_log(ic, "WARNING: Received SI Request for unsupported bytestream mode %s",
     293                         xt_find_attr(qnode, "mode"));
    293294                return XT_HANDLED;
    294295        }
    295296
    296297        shnode = qnode->children;
    297         while( ( shnode = xt_find_node( shnode, "streamhost" ) ) )
    298         {
     298        while ((shnode = xt_find_node(shnode, "streamhost"))) {
    299299                char *jid, *host, *port_s;
    300300                int port;
    301                 if( ( jid = xt_find_attr( shnode, "jid" ) ) &&
    302                     ( host = xt_find_attr( shnode, "host" ) ) &&
    303                     ( port_s = xt_find_attr( shnode, "port" ) ) &&
    304                     ( sscanf( port_s, "%d", &port ) == 1 ) )
    305                 {
    306                         jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 );
     301                if ((jid = xt_find_attr(shnode, "jid")) &&
     302                    (host = xt_find_attr(shnode, "host")) &&
     303                    (port_s = xt_find_attr(shnode, "port")) &&
     304                    (sscanf(port_s, "%d", &port) == 1)) {
     305                        jabber_streamhost_t *sh = g_new0(jabber_streamhost_t, 1);
    307306                        sh->jid = g_strdup(jid);
    308307                        sh->host = g_strdup(host);
    309                         sprintf( sh->port, "%u", port );
    310                         shlist = g_slist_append( shlist, sh );
     308                        sprintf(sh->port, "%u", port);
     309                        shlist = g_slist_append(shlist, sh);
    311310                }
    312311                shnode = shnode->next;
    313312        }
    314        
    315         if( !shlist )
    316         {
    317                 imcb_log( ic, "WARNING: Received incomplete SI bytestream request, no parseable streamhost entries");
     313
     314        if (!shlist) {
     315                imcb_log(ic, "WARNING: Received incomplete SI bytestream request, no parseable streamhost entries");
    318316                return XT_HANDLED;
    319317        }
     
    321319        /* Let's see if we can find out what this bytestream should be for... */
    322320
    323         for( tflist = jd->filetransfers ; tflist; tflist = g_slist_next(tflist) )
    324         {
     321        for (tflist = jd->filetransfers; tflist; tflist = g_slist_next(tflist)) {
    325322                struct jabber_transfer *tft = tflist->data;
    326                 if( ( strcmp( tft->sid, sid ) == 0 ) &&
    327                     ( strcmp( tft->ini_jid, ini_jid ) == 0 ) &&
    328                     ( strcmp( tft->tgt_jid, tgt_jid ) == 0 ) )
    329                 {
    330                         tf = tft;
     323                if ((strcmp(tft->sid, sid) == 0) &&
     324                    (strcmp(tft->ini_jid, ini_jid) == 0) &&
     325                    (strcmp(tft->tgt_jid, tgt_jid) == 0)) {
     326                        tf = tft;
    331327                        break;
    332328                }
    333329        }
    334330
    335         if (!tf)
    336         {
    337                 imcb_log( ic, "WARNING: Received bytestream request from %s that doesn't match an SI request", ini_jid );
     331        if (!tf) {
     332                imcb_log(ic, "WARNING: Received bytestream request from %s that doesn't match an SI request", ini_jid);
    338333                return XT_HANDLED;
    339334        }
    340335
    341336        /* iq_id and canceled can be reused since SI is done */
    342         g_free( tf->iq_id );
    343         tf->iq_id = g_strdup( iq_id );
     337        g_free(tf->iq_id);
     338        tf->iq_id = g_strdup(iq_id);
    344339
    345340        tf->ft->canceled = jabber_bs_canceled;
    346341
    347342        /* SHA1( SID + Initiator JID + Target JID ) is given to the streamhost which it will match against the initiator's value */
    348         sha1_init( &sha );
    349         sha1_append( &sha, (unsigned char*) sid, strlen( sid ) );
    350         sha1_append( &sha, (unsigned char*) ini_jid, strlen( ini_jid ) );
    351         sha1_append( &sha, (unsigned char*) tgt_jid, strlen( tgt_jid ) );
    352         sha1_finish( &sha, hash );
    353        
    354         for( i = 0; i < 20; i ++ )
    355                 sprintf( hash_hex + i * 2, "%02x", hash[i] );
    356                
    357         bt = g_new0( struct bs_transfer, 1 );
     343        sha1_init(&sha);
     344        sha1_append(&sha, (unsigned char *) sid, strlen(sid));
     345        sha1_append(&sha, (unsigned char *) ini_jid, strlen(ini_jid));
     346        sha1_append(&sha, (unsigned char *) tgt_jid, strlen(tgt_jid));
     347        sha1_finish(&sha, hash);
     348
     349        for (i = 0; i < 20; i++) {
     350                sprintf(hash_hex + i * 2, "%02x", hash[i]);
     351        }
     352
     353        bt = g_new0(struct bs_transfer, 1);
    358354        bt->tf = tf;
    359355        bt->streamhosts = shlist;
    360356        bt->sh = shlist->data;
    361357        bt->phase = BS_PHASE_CONNECT;
    362         bt->pseudoadr = g_strdup( hash_hex );
     358        bt->pseudoadr = g_strdup(hash_hex);
    363359        tf->streamhandle = bt;
    364360        tf->ft->free = jabber_bs_free_transfer;
    365361
    366         jabber_bs_recv_handshake( bt, -1, 0 );
     362        jabber_bs_recv_handshake(bt, -1, 0);
    367363
    368364        return XT_HANDLED;
     
    376372 * All in all, it turned out quite nice :)
    377373 */
    378 gboolean jabber_bs_recv_handshake( gpointer data, gint fd, b_input_condition cond )
     374gboolean jabber_bs_recv_handshake(gpointer data, gint fd, b_input_condition cond)
    379375{
    380376
     
    383379        int gret;
    384380
    385         if ( ( fd != -1 ) && !jabber_bs_poll( bt, fd, &revents ) )
     381        if ((fd != -1) && !jabber_bs_poll(bt, fd, &revents)) {
    386382                return FALSE;
    387        
    388         switch( bt->phase )
     383        }
     384
     385        switch (bt->phase) {
     386        case BS_PHASE_CONNECT:
    389387        {
    390         case BS_PHASE_CONNECT:
     388                struct addrinfo hints, *rp;
     389
     390                memset(&hints, 0, sizeof(struct addrinfo));
     391                hints.ai_socktype = SOCK_STREAM;
     392
     393                if ((gret = getaddrinfo(bt->sh->host, bt->sh->port, &hints, &rp)) != 0) {
     394                        return jabber_bs_abort(bt, "getaddrinfo() failed: %s", gai_strerror(gret));
     395                }
     396
     397                ASSERTSOCKOP(bt->tf->fd = fd = socket(rp->ai_family, rp->ai_socktype, 0), "Opening socket");
     398
     399                sock_make_nonblocking(fd);
     400
     401                imcb_log(bt->tf->ic, "File %s: Connecting to streamhost %s:%s", bt->tf->ft->file_name, bt->sh->host,
     402                         bt->sh->port);
     403
     404                if ((connect(fd, rp->ai_addr, rp->ai_addrlen) == -1) &&
     405                    (errno != EINPROGRESS)) {
     406                        return jabber_bs_abort(bt, "connect() failed: %s", strerror(errno));
     407                }
     408
     409                freeaddrinfo(rp);
     410
     411                bt->phase = BS_PHASE_CONNECTED;
     412
     413                bt->tf->watch_out = b_input_add(fd, B_EV_IO_WRITE, jabber_bs_recv_handshake, bt);
     414
     415                /* since it takes forever(3mins?) till connect() fails on itself we schedule a timeout */
     416                bt->connect_timeout = b_timeout_add(JABBER_BS_CONTIMEOUT * 1000, jabber_bs_connect_timeout, bt);
     417
     418                bt->tf->watch_in = 0;
     419                return FALSE;
     420        }
     421        case BS_PHASE_CONNECTED:
     422        {
     423                struct {
     424                        unsigned char ver;
     425                        unsigned char nmethods;
     426                        unsigned char method;
     427                } socks5_hello = {
     428                        .ver = 5,
     429                        .nmethods = 1,
     430                        .method = 0x00         /* no auth */
     431                                  /* one could also implement username/password. If you know
     432                                   * a jabber client or proxy that actually does it, tell me.
     433                                   */
     434                };
     435
     436                ASSERTSOCKOP(send(fd, &socks5_hello, sizeof(socks5_hello), 0), "Sending auth request");
     437
     438                bt->phase = BS_PHASE_REQUEST;
     439
     440                bt->tf->watch_in = b_input_add(fd, B_EV_IO_READ, jabber_bs_recv_handshake, bt);
     441
     442                bt->tf->watch_out = 0;
     443                return FALSE;
     444        }
     445        case BS_PHASE_REQUEST:
     446        {
     447                struct socks5_message socks5_connect =
    391448                {
    392                         struct addrinfo hints, *rp;
    393 
    394                         memset( &hints, 0, sizeof( struct addrinfo ) );
    395                         hints.ai_socktype = SOCK_STREAM;
    396 
    397                         if ( ( gret = getaddrinfo( bt->sh->host, bt->sh->port, &hints, &rp ) ) != 0 )
    398                                 return jabber_bs_abort( bt, "getaddrinfo() failed: %s", gai_strerror( gret ) );
    399 
    400                         ASSERTSOCKOP( bt->tf->fd = fd = socket( rp->ai_family, rp->ai_socktype, 0 ), "Opening socket" );
    401 
    402                         sock_make_nonblocking( fd );
    403 
    404                         imcb_log( bt->tf->ic, "File %s: Connecting to streamhost %s:%s", bt->tf->ft->file_name, bt->sh->host, bt->sh->port );
    405 
    406                         if( ( connect( fd, rp->ai_addr, rp->ai_addrlen ) == -1 ) &&
    407                             ( errno != EINPROGRESS ) )
    408                                 return jabber_bs_abort( bt , "connect() failed: %s", strerror( errno ) );
    409 
    410                         freeaddrinfo( rp );
    411 
    412                         bt->phase = BS_PHASE_CONNECTED;
    413                        
    414                         bt->tf->watch_out = b_input_add( fd, B_EV_IO_WRITE, jabber_bs_recv_handshake, bt );
    415 
    416                         /* since it takes forever(3mins?) till connect() fails on itself we schedule a timeout */
    417                         bt->connect_timeout = b_timeout_add( JABBER_BS_CONTIMEOUT * 1000, jabber_bs_connect_timeout, bt );
    418 
    419                         bt->tf->watch_in = 0;
     449                        .ver = 5,
     450                        .cmdrep.cmd = 0x01,
     451                        .rsv = 0,
     452                        .atyp = 0x03,
     453                        .addrlen = strlen(bt->pseudoadr),
     454                        .port = 0
     455                };
     456                int ret;
     457                char buf[2];
     458
     459                /* If someone's trying to be funny and sends only one byte at a time we'll fail :) */
     460                ASSERTSOCKOP(ret = recv(fd, buf, 2, 0), "Receiving auth reply");
     461
     462                if (!(ret == 2) ||
     463                    !(buf[0] == 5) ||
     464                    !(buf[1] == 0)) {
     465                        return jabber_bs_abort(bt, "Auth not accepted by streamhost (reply: len=%d, ver=%d, status=%d)",
     466                                               ret, buf[0], buf[1]);
     467                }
     468
     469                /* copy hash into connect message */
     470                memcpy(socks5_connect.address, bt->pseudoadr, socks5_connect.addrlen);
     471
     472                ASSERTSOCKOP(send(fd, &socks5_connect, sizeof(struct socks5_message), 0), "Sending SOCKS5 Connect");
     473
     474                bt->phase = BS_PHASE_REPLY;
     475
     476                return TRUE;
     477        }
     478        case BS_PHASE_REPLY:
     479        {
     480                struct socks5_message socks5_reply;
     481                int ret;
     482
     483                if (!(ret = jabber_bs_peek(bt, &socks5_reply, sizeof(struct socks5_message)))) {
    420484                        return FALSE;
    421485                }
    422         case BS_PHASE_CONNECTED:
    423                 {
    424                         struct {
    425                                 unsigned char ver;
    426                                 unsigned char nmethods;
    427                                 unsigned char method;
    428                         } socks5_hello = {
    429                                 .ver = 5,
    430                                 .nmethods = 1,
    431                                 .method = 0x00 /* no auth */
    432                                 /* one could also implement username/password. If you know
    433                                  * a jabber client or proxy that actually does it, tell me.
    434                                  */
    435                         };
    436                        
    437                         ASSERTSOCKOP( send( fd, &socks5_hello, sizeof( socks5_hello ) , 0 ), "Sending auth request" );
    438 
    439                         bt->phase = BS_PHASE_REQUEST;
    440 
    441                         bt->tf->watch_in = b_input_add( fd, B_EV_IO_READ, jabber_bs_recv_handshake, bt );
    442 
    443                         bt->tf->watch_out = 0;
    444                         return FALSE;
    445                 }
    446         case BS_PHASE_REQUEST:
    447                 {
    448                         struct socks5_message socks5_connect =
    449                         {
    450                                 .ver = 5,
    451                                 .cmdrep.cmd = 0x01,
    452                                 .rsv = 0,
    453                                 .atyp = 0x03,
    454                                 .addrlen = strlen( bt->pseudoadr ),
    455                                 .port = 0
    456                         };
    457                         int ret;
    458                         char buf[2];
    459 
    460                         /* If someone's trying to be funny and sends only one byte at a time we'll fail :) */
    461                         ASSERTSOCKOP( ret = recv( fd, buf, 2, 0 ) , "Receiving auth reply" );
    462 
    463                         if( !( ret == 2 ) ||
    464                             !( buf[0] == 5 ) ||
    465                             !( buf[1] == 0 ) )
    466                                 return jabber_bs_abort( bt, "Auth not accepted by streamhost (reply: len=%d, ver=%d, status=%d)",
    467                                                                         ret, buf[0], buf[1] );
    468 
    469                         /* copy hash into connect message */
    470                         memcpy( socks5_connect.address, bt->pseudoadr, socks5_connect.addrlen );
    471 
    472                         ASSERTSOCKOP( send( fd, &socks5_connect, sizeof( struct socks5_message ), 0 ) , "Sending SOCKS5 Connect" );
    473 
    474                         bt->phase = BS_PHASE_REPLY;
    475 
     486
     487                if (ret < 5) {         /* header up to address length */
    476488                        return TRUE;
    477                 }
    478         case BS_PHASE_REPLY:
    479                 {
    480                         struct socks5_message socks5_reply;
    481                         int ret;
    482 
    483                         if ( !( ret = jabber_bs_peek( bt, &socks5_reply, sizeof( struct socks5_message ) ) ) )
    484                                 return FALSE;
    485 
    486                         if ( ret < 5 ) /* header up to address length */
    487                                 return TRUE;
    488                         else if( ret < sizeof( struct socks5_message ) )
    489                         {
    490                                 /* Either a buggy proxy or just one that doesnt regard
    491                                  * the SHOULD in XEP-0065 saying the reply SHOULD
    492                                  * contain the address. We'll take it, so make sure the
    493                                  * next jabber_bs_peek starts with an empty buffer. */
    494                                 bt->peek_buf_len = 0;
     489                } else if (ret < sizeof(struct socks5_message)) {
     490                        /* Either a buggy proxy or just one that doesnt regard
     491                         * the SHOULD in XEP-0065 saying the reply SHOULD
     492                         * contain the address. We'll take it, so make sure the
     493                         * next jabber_bs_peek starts with an empty buffer. */
     494                        bt->peek_buf_len = 0;
     495                }
     496
     497                if (!(socks5_reply.ver == 5) ||
     498                    !(socks5_reply.cmdrep.rep == 0)) {
     499                        char errstr[128] = "";
     500                        if ((socks5_reply.ver == 5) && (socks5_reply.cmdrep.rep <
     501                                                        (sizeof(socks5_reply_code) / sizeof(socks5_reply_code[0])))) {
     502                                sprintf(errstr, "with \"%s\" ", socks5_reply_code[ socks5_reply.cmdrep.rep ]);
    495503                        }
    496 
    497                         if( !( socks5_reply.ver == 5 ) ||
    498                             !( socks5_reply.cmdrep.rep == 0 ) ) {
    499                                 char errstr[128] = "";
    500                                 if( ( socks5_reply.ver == 5 ) && ( socks5_reply.cmdrep.rep <
    501                                     ( sizeof( socks5_reply_code ) / sizeof( socks5_reply_code[0] ) ) ) ) {
    502                                         sprintf( errstr, "with \"%s\" ", socks5_reply_code[ socks5_reply.cmdrep.rep ] );
    503                                 }
    504                                 return jabber_bs_abort( bt, "SOCKS5 CONNECT failed %s(reply: ver=%d, rep=%d, atyp=%d, addrlen=%d)",
    505                                         errstr,
    506                                         socks5_reply.ver,
    507                                         socks5_reply.cmdrep.rep,
    508                                         socks5_reply.atyp,
    509                                         socks5_reply.addrlen);
    510                         }
    511                        
    512                         /* usually a proxy sends back the 40 bytes address but I encountered at least one (of jabber.cz)
    513                          * that sends atyp=0 addrlen=0 and only 6 bytes (one less than one would expect).
    514                          * Therefore I removed the wait for more bytes. Since we don't care about what else the proxy
    515                          * is sending, it shouldnt matter */
    516 
    517                         if( bt->tf->ft->sending )
    518                                 jabber_bs_send_activate( bt );
    519                         else
    520                                 jabber_bs_recv_answer_request( bt );
    521 
    522                         return FALSE;
    523                 }
     504                        return jabber_bs_abort(bt,
     505                                               "SOCKS5 CONNECT failed %s(reply: ver=%d, rep=%d, atyp=%d, addrlen=%d)",
     506                                               errstr,
     507                                               socks5_reply.ver,
     508                                               socks5_reply.cmdrep.rep,
     509                                               socks5_reply.atyp,
     510                                               socks5_reply.addrlen);
     511                }
     512
     513                /* usually a proxy sends back the 40 bytes address but I encountered at least one (of jabber.cz)
     514                 * that sends atyp=0 addrlen=0 and only 6 bytes (one less than one would expect).
     515                 * Therefore I removed the wait for more bytes. Since we don't care about what else the proxy
     516                 * is sending, it shouldnt matter */
     517
     518                if (bt->tf->ft->sending) {
     519                        jabber_bs_send_activate(bt);
     520                } else {
     521                        jabber_bs_recv_answer_request(bt);
     522                }
     523
     524                return FALSE;
     525        }
    524526        default:
    525527                /* BUG */
    526                 imcb_log( bt->tf->ic, "BUG in file transfer code: undefined handshake phase" );
     528                imcb_log(bt->tf->ic, "BUG in file transfer code: undefined handshake phase");
    527529
    528530                bt->tf->watch_in = 0;
     
    534536 * If the handshake failed we can try the next streamhost, if there is one.
    535537 * An intelligent sender would probably specify himself as the first streamhost and
    536  * a proxy as the second (Kopete and PSI are examples here). That way, a (potentially) 
     538 * a proxy as the second (Kopete and PSI are examples here). That way, a (potentially)
    537539 * slow proxy is only used if neccessary. This of course also means, that the timeout
    538540 * per streamhost should be kept short. If one or two firewalled adresses are specified,
    539541 * they have to timeout first before a proxy is tried.
    540542 */
    541 gboolean jabber_bs_recv_handshake_abort( struct bs_transfer *bt, char *error )
     543gboolean jabber_bs_recv_handshake_abort(struct bs_transfer *bt, char *error)
    542544{
    543545        struct jabber_transfer *tf = bt->tf;
     
    545547        GSList *shlist;
    546548
    547         imcb_log( tf->ic, "Transferring file %s: connection to streamhost %s:%s failed (%s)",
    548                   tf->ft->file_name,
    549                   bt->sh->host,
    550                   bt->sh->port,
    551                   error );
     549        imcb_log(tf->ic, "Transferring file %s: connection to streamhost %s:%s failed (%s)",
     550                 tf->ft->file_name,
     551                 bt->sh->host,
     552                 bt->sh->port,
     553                 error);
    552554
    553555        /* Alright, this streamhost failed, let's try the next... */
    554556        bt->phase = BS_PHASE_CONNECT;
    555         shlist = g_slist_find( bt->streamhosts, bt->sh );
    556         if( shlist && shlist->next )
    557         {
     557        shlist = g_slist_find(bt->streamhosts, bt->sh);
     558        if (shlist && shlist->next) {
    558559                bt->sh = shlist->next->data;
    559                 return jabber_bs_recv_handshake( bt, -1, 0 );
     560                return jabber_bs_recv_handshake(bt, -1, 0);
    560561        }
    561562
     
    563564        /* out of stream hosts */
    564565
    565         iqnode = jabber_make_packet( "iq", "result", tf->ini_jid, NULL );
    566         reply = jabber_make_error_packet( iqnode, "item-not-found", "cancel" , "404" );
    567         xt_free_node( iqnode );
    568 
    569         xt_add_attr( reply, "id", tf->iq_id );
    570                
    571         if( !jabber_write_packet( tf->ic, reply ) )
    572                 imcb_log( tf->ic, "WARNING: Error transmitting bytestream response" );
    573         xt_free_node( reply );
    574 
    575         imcb_file_canceled( tf->ic, tf->ft, "couldn't connect to any streamhosts" );
     566        iqnode = jabber_make_packet("iq", "result", tf->ini_jid, NULL);
     567        reply = jabber_make_error_packet(iqnode, "item-not-found", "cancel", "404");
     568        xt_free_node(iqnode);
     569
     570        xt_add_attr(reply, "id", tf->iq_id);
     571
     572        if (!jabber_write_packet(tf->ic, reply)) {
     573                imcb_log(tf->ic, "WARNING: Error transmitting bytestream response");
     574        }
     575        xt_free_node(reply);
     576
     577        imcb_file_canceled(tf->ic, tf->ft, "couldn't connect to any streamhosts");
    576578
    577579        /* MUST always return FALSE! */
     
    579581}
    580582
    581 /* 
     583/*
    582584 * After the SOCKS5 handshake succeeds we need to inform the initiator which streamhost we chose.
    583585 * If he is the streamhost himself, he might already know that. However, if it's a proxy,
    584586 * the initiator will have to make a connection himself.
    585587 */
    586 void jabber_bs_recv_answer_request( struct bs_transfer *bt )
     588void jabber_bs_recv_answer_request(struct bs_transfer *bt)
    587589{
    588590        struct jabber_transfer *tf = bt->tf;
    589591        struct xt_node *reply;
    590592
    591         imcb_log( tf->ic, "File %s: established SOCKS5 connection to %s:%s",
    592                   tf->ft->file_name,
    593                   bt->sh->host,
    594                   bt->sh->port );
     593        imcb_log(tf->ic, "File %s: established SOCKS5 connection to %s:%s",
     594                 tf->ft->file_name,
     595                 bt->sh->host,
     596                 bt->sh->port);
    595597
    596598        tf->ft->data = tf;
    597         tf->watch_in = b_input_add( tf->fd, B_EV_IO_READ, jabber_bs_recv_read, bt );
     599        tf->watch_in = b_input_add(tf->fd, B_EV_IO_READ, jabber_bs_recv_read, bt);
    598600        tf->ft->write_request = jabber_bs_recv_write_request;
    599601
    600         reply = xt_new_node( "streamhost-used", NULL, NULL );
    601         xt_add_attr( reply, "jid", bt->sh->jid );
    602 
    603         reply = xt_new_node( "query", NULL, reply );
    604         xt_add_attr( reply, "xmlns", XMLNS_BYTESTREAMS );
    605 
    606         reply = jabber_make_packet( "iq", "result", tf->ini_jid, reply );
    607 
    608         xt_add_attr( reply, "id", tf->iq_id );
    609                
    610         if( !jabber_write_packet( tf->ic, reply ) )
    611                 imcb_file_canceled( tf->ic, tf->ft, "Error transmitting bytestream response" );
    612         xt_free_node( reply );
    613 }
    614 
    615 /*
     602        reply = xt_new_node("streamhost-used", NULL, NULL);
     603        xt_add_attr(reply, "jid", bt->sh->jid);
     604
     605        reply = xt_new_node("query", NULL, reply);
     606        xt_add_attr(reply, "xmlns", XMLNS_BYTESTREAMS);
     607
     608        reply = jabber_make_packet("iq", "result", tf->ini_jid, reply);
     609
     610        xt_add_attr(reply, "id", tf->iq_id);
     611
     612        if (!jabber_write_packet(tf->ic, reply)) {
     613                imcb_file_canceled(tf->ic, tf->ft, "Error transmitting bytestream response");
     614        }
     615        xt_free_node(reply);
     616}
     617
     618/*
    616619 * This function is called from write_request directly. If no data is available, it will install itself
    617620 * as a watcher for input on fd and once that happens, deliver the data and unschedule itself again.
    618621 */
    619 gboolean jabber_bs_recv_read( gpointer data, gint fd, b_input_condition cond )
     622gboolean jabber_bs_recv_read(gpointer data, gint fd, b_input_condition cond)
    620623{
    621624        int ret;
     
    623626        struct jabber_transfer *tf = bt->tf;
    624627
    625         if( fd != -1 ) /* called via event thread */
    626         {
     628        if (fd != -1) { /* called via event thread */
    627629                tf->watch_in = 0;
    628                 ASSERTSOCKOP( ret = recv( fd, tf->ft->buffer, sizeof( tf->ft->buffer ), 0 ) , "Receiving" );
    629         }
    630         else
    631         {
     630                ASSERTSOCKOP(ret = recv(fd, tf->ft->buffer, sizeof(tf->ft->buffer), 0), "Receiving");
     631        } else {
    632632                /* called directly. There might not be any data available. */
    633                 if( ( ( ret = recv( tf->fd, tf->ft->buffer, sizeof( tf->ft->buffer ), 0 ) ) == -1 ) &&
    634                     ( errno != EAGAIN ) )
    635                     return jabber_bs_abort( bt, "Receiving: %s", strerror( errno ) );
    636 
    637                 if( ( ret == -1 ) && ( errno == EAGAIN ) )
    638                 {
    639                         tf->watch_in = b_input_add( tf->fd, B_EV_IO_READ, jabber_bs_recv_read, bt );
     633                if (((ret = recv(tf->fd, tf->ft->buffer, sizeof(tf->ft->buffer), 0)) == -1) &&
     634                    (errno != EAGAIN)) {
     635                        return jabber_bs_abort(bt, "Receiving: %s", strerror(errno));
     636                }
     637
     638                if ((ret == -1) && (errno == EAGAIN)) {
     639                        tf->watch_in = b_input_add(tf->fd, B_EV_IO_READ, jabber_bs_recv_read, bt);
    640640                        return FALSE;
    641641                }
     
    643643
    644644        /* shouldn't happen since we know the file size */
    645         if( ret == 0 )
    646                 return jabber_bs_abort( bt, "Remote end closed connection" );
    647        
     645        if (ret == 0) {
     646                return jabber_bs_abort(bt, "Remote end closed connection");
     647        }
     648
    648649        tf->bytesread += ret;
    649650
    650         if( tf->bytesread >= tf->ft->file_size )
    651                 imcb_file_finished( tf->ic, tf->ft );
    652 
    653         tf->ft->write( tf->ft, tf->ft->buffer, ret );   
     651        if (tf->bytesread >= tf->ft->file_size) {
     652                imcb_file_finished(tf->ic, tf->ft);
     653        }
     654
     655        tf->ft->write(tf->ft, tf->ft->buffer, ret);
    654656
    655657        return FALSE;
    656658}
    657659
    658 /* 
     660/*
    659661 * imc callback that is invoked when it is ready to receive some data.
    660662 */
    661 gboolean jabber_bs_recv_write_request( file_transfer_t *ft )
     663gboolean jabber_bs_recv_write_request(file_transfer_t *ft)
    662664{
    663665        struct jabber_transfer *tf = ft->data;
    664666
    665         if( tf->watch_in )
    666         {
    667                 imcb_file_canceled( tf->ic, ft, "BUG in jabber file transfer: write_request called when already watching for input" );
     667        if (tf->watch_in) {
     668                imcb_file_canceled(tf->ic, ft,
     669                                   "BUG in jabber file transfer: write_request called when already watching for input");
    668670                return FALSE;
    669671        }
    670        
    671         jabber_bs_recv_read( tf->streamhandle, -1 , 0 );
     672
     673        jabber_bs_recv_read(tf->streamhandle, -1, 0);
    672674
    673675        return TRUE;
    674676}
    675677
    676 /* 
     678/*
    677679 * Issues a write_request to imc.
    678680 * */
    679 gboolean jabber_bs_send_can_write( gpointer data, gint fd, b_input_condition cond )
     681gboolean jabber_bs_send_can_write(gpointer data, gint fd, b_input_condition cond)
    680682{
    681683        struct bs_transfer *bt = data;
     
    683685        bt->tf->watch_out = 0;
    684686
    685         bt->tf->ft->write_request( bt->tf->ft );
     687        bt->tf->ft->write_request(bt->tf->ft);
    686688
    687689        return FALSE;
     
    692694 * Add a write watch so we can write more during the next cycle (if possible).
    693695 */
    694 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len )
     696gboolean jabber_bs_send_write(file_transfer_t *ft, char *buffer, unsigned int len)
    695697{
    696698        struct jabber_transfer *tf = ft->data;
     
    698700        int ret;
    699701
    700         if( tf->watch_out )
    701                 return jabber_bs_abort( bt, "BUG: write() called while watching " );
    702        
     702        if (tf->watch_out) {
     703                return jabber_bs_abort(bt, "BUG: write() called while watching ");
     704        }
     705
    703706        /* TODO: catch broken pipe */
    704         ASSERTSOCKOP( ret = send( tf->fd, buffer, len, 0 ), "Sending" );
     707        ASSERTSOCKOP(ret = send(tf->fd, buffer, len, 0), "Sending");
    705708
    706709        tf->byteswritten += ret;
    707        
     710
    708711        /* TODO: this should really not be fatal */
    709         if( ret < len )
    710                 return jabber_bs_abort( bt, "send() sent %d instead of %d (send buffer too big!)", ret, len );
    711 
    712         if( tf->byteswritten >= ft->file_size )
    713                 imcb_file_finished( tf->ic, ft );
    714         else
    715                 bt->tf->watch_out = b_input_add( tf->fd, B_EV_IO_WRITE, jabber_bs_send_can_write, bt );
    716                
     712        if (ret < len) {
     713                return jabber_bs_abort(bt, "send() sent %d instead of %d (send buffer too big!)", ret, len);
     714        }
     715
     716        if (tf->byteswritten >= ft->file_size) {
     717                imcb_file_finished(tf->ic, ft);
     718        } else {
     719                bt->tf->watch_out = b_input_add(tf->fd, B_EV_IO_WRITE, jabber_bs_send_can_write, bt);
     720        }
     721
    717722        return TRUE;
    718723}
     
    721726 * Handles the reply by the receiver containing the used streamhost.
    722727 */
    723 static xt_status jabber_bs_send_handle_reply(struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) {
     728static xt_status jabber_bs_send_handle_reply(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
     729{
    724730        struct jabber_transfer *tf = NULL;
    725731        struct jabber_data *jd = ic->proto_data;
     
    729735        char *sid, *jid;
    730736
    731         if( !( c = xt_find_node( node->children, "query" ) ) ||
    732             !( c = xt_find_node( c->children, "streamhost-used" ) ) ||
    733             !( jid = xt_find_attr( c, "jid" ) ) )
    734 
    735         {
    736                 imcb_log( ic, "WARNING: Received incomplete bytestream reply" );
     737        if (!(c = xt_find_node(node->children, "query")) ||
     738            !(c = xt_find_node(c->children, "streamhost-used")) ||
     739            !(jid = xt_find_attr(c, "jid"))) {
     740                imcb_log(ic, "WARNING: Received incomplete bytestream reply");
    737741                return XT_HANDLED;
    738742        }
    739        
    740         if( !( c = xt_find_node( orig->children, "query" ) ) ||
    741             !( sid = xt_find_attr( c, "sid" ) ) )
    742         {
    743                 imcb_log( ic, "WARNING: Error parsing request corresponding to the incoming bytestream reply" );
     743
     744        if (!(c = xt_find_node(orig->children, "query")) ||
     745            !(sid = xt_find_attr(c, "sid"))) {
     746                imcb_log(ic, "WARNING: Error parsing request corresponding to the incoming bytestream reply");
    744747                return XT_HANDLED;
    745748        }
     
    747750        /* Let's see if we can find out what this bytestream should be for... */
    748751
    749         for( tflist = jd->filetransfers ; tflist; tflist = g_slist_next(tflist) )
    750         {
     752        for (tflist = jd->filetransfers; tflist; tflist = g_slist_next(tflist)) {
    751753                struct jabber_transfer *tft = tflist->data;
    752                 if( ( strcmp( tft->sid, sid ) == 0 ) )
    753                 {
    754                         tf = tft;
     754                if ((strcmp(tft->sid, sid) == 0)) {
     755                        tf = tft;
    755756                        break;
    756757                }
    757758        }
    758759
    759         if( !tf )
    760         {
    761                 imcb_log( ic, "WARNING: Received SOCKS5 bytestream reply to unknown request" );
     760        if (!tf) {
     761                imcb_log(ic, "WARNING: Received SOCKS5 bytestream reply to unknown request");
    762762                return XT_HANDLED;
    763763        }
     
    767767        tf->accepted = TRUE;
    768768
    769         if( strcmp( jid, tf->ini_jid ) == 0 )
    770         {
     769        if (strcmp(jid, tf->ini_jid) == 0) {
    771770                /* we're streamhost and target */
    772                 if( bt->phase == BS_PHASE_REPLY )
    773                 {
     771                if (bt->phase == BS_PHASE_REPLY) {
    774772                        /* handshake went through, let's start transferring */
    775                         tf->ft->write_request( tf->ft );
    776                 }
    777         } else
    778         {
     773                        tf->ft->write_request(tf->ft);
     774                }
     775        } else {
    779776                /* using a proxy, abort listen */
    780777
    781                 if( tf->watch_in )
    782                 {
    783                         b_event_remove( tf->watch_in );
     778                if (tf->watch_in) {
     779                        b_event_remove(tf->watch_in);
    784780                        tf->watch_in = 0;
    785781                }
    786                
    787                 if( tf->fd != -1 ) {
    788                         closesocket( tf->fd );
     782
     783                if (tf->fd != -1) {
     784                        closesocket(tf->fd);
    789785                        tf->fd = -1;
    790786                }
    791787
    792                 if ( bt->connect_timeout )
    793                 {
    794                         b_event_remove( bt->connect_timeout );
     788                if (bt->connect_timeout) {
     789                        b_event_remove(bt->connect_timeout);
    795790                        bt->connect_timeout = 0;
    796791                }
    797792
    798793                GSList *shlist;
    799                 for( shlist = jd->streamhosts ; shlist ; shlist = g_slist_next( shlist ) )
    800                 {
     794                for (shlist = jd->streamhosts; shlist; shlist = g_slist_next(shlist)) {
    801795                        jabber_streamhost_t *sh = shlist->data;
    802                         if( strcmp( sh->jid, jid ) == 0 )
    803                         {
     796                        if (strcmp(sh->jid, jid) == 0) {
    804797                                bt->sh = sh;
    805                                 jabber_bs_recv_handshake( bt, -1, 0 );
     798                                jabber_bs_recv_handshake(bt, -1, 0);
    806799                                return XT_HANDLED;
    807800                        }
    808801                }
    809802
    810                 imcb_log( ic, "WARNING: Received SOCKS5 bytestream reply with unknown streamhost %s", jid );
     803                imcb_log(ic, "WARNING: Received SOCKS5 bytestream reply with unknown streamhost %s", jid);
    811804        }
    812805
     
    814807}
    815808
    816 /* 
     809/*
    817810 * Tell the proxy to activate the stream. Looks like this:
    818811 *
    819812 * <iq type=set>
    820  *      <query xmlns=bs sid=sid>
    821  *              <activate>tgt_jid</activate>
    822  *      </query>
     813 *      <query xmlns=bs sid=sid>
     814 *              <activate>tgt_jid</activate>
     815 *      </query>
    823816 * </iq>
    824817 */
    825 void jabber_bs_send_activate( struct bs_transfer *bt )
     818void jabber_bs_send_activate(struct bs_transfer *bt)
    826819{
    827820        struct xt_node *node;
    828821
    829         node = xt_new_node( "activate", bt->tf->tgt_jid, NULL );
    830         node = xt_new_node( "query", NULL, node );
    831         xt_add_attr( node, "xmlns", XMLNS_BYTESTREAMS );
    832         xt_add_attr( node, "sid", bt->tf->sid );
    833         node = jabber_make_packet( "iq", "set", bt->sh->jid, node );
    834 
    835         jabber_cache_add( bt->tf->ic, node, jabber_bs_send_handle_activate );
    836 
    837         jabber_write_packet( bt->tf->ic, node );
     822        node = xt_new_node("activate", bt->tf->tgt_jid, NULL);
     823        node = xt_new_node("query", NULL, node);
     824        xt_add_attr(node, "xmlns", XMLNS_BYTESTREAMS);
     825        xt_add_attr(node, "sid", bt->tf->sid);
     826        node = jabber_make_packet("iq", "set", bt->sh->jid, node);
     827
     828        jabber_cache_add(bt->tf->ic, node, jabber_bs_send_handle_activate);
     829
     830        jabber_write_packet(bt->tf->ic, node);
    838831}
    839832
     
    842835 * We can finally start pushing some data out.
    843836 */
    844 static xt_status jabber_bs_send_handle_activate( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     837static xt_status jabber_bs_send_handle_activate(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    845838{
    846839        char *sid;
     
    850843        struct jabber_data *jd = ic->proto_data;
    851844
    852         query = xt_find_node( orig->children, "query" );
    853         sid = xt_find_attr( query, "sid" );
    854 
    855         for( tflist = jd->filetransfers ; tflist; tflist = g_slist_next(tflist) )
    856         {
     845        query = xt_find_node(orig->children, "query");
     846        sid = xt_find_attr(query, "sid");
     847
     848        for (tflist = jd->filetransfers; tflist; tflist = g_slist_next(tflist)) {
    857849                struct jabber_transfer *tft = tflist->data;
    858                 if( ( strcmp( tft->sid, sid ) == 0 ) )
    859                 {
    860                         tf = tft;
     850                if ((strcmp(tft->sid, sid) == 0)) {
     851                        tf = tft;
    861852                        break;
    862853                }
    863854        }
    864855
    865         if( !tf )
    866         {
    867                 imcb_log( ic, "WARNING: Received SOCKS5 bytestream activation for unknown stream" );
     856        if (!tf) {
     857                imcb_log(ic, "WARNING: Received SOCKS5 bytestream activation for unknown stream");
    868858                return XT_HANDLED;
    869859        }
    870860
    871         imcb_log( tf->ic, "File %s: SOCKS5 handshake and activation successful! Transfer about to start...", tf->ft->file_name );
     861        imcb_log(tf->ic, "File %s: SOCKS5 handshake and activation successful! Transfer about to start...",
     862                 tf->ft->file_name);
    872863
    873864        /* handshake went through, let's start transferring */
    874         tf->ft->write_request( tf->ft );
     865        tf->ft->write_request(tf->ft);
    875866
    876867        return XT_HANDLED;
    877868}
    878869
    879 jabber_streamhost_t *jabber_si_parse_proxy( struct im_connection *ic, char *proxy )
     870jabber_streamhost_t *jabber_si_parse_proxy(struct im_connection *ic, char *proxy)
    880871{
    881872        char *host, *port, *jid;
    882873        jabber_streamhost_t *sh;
    883874
    884         if( ( ( host = strchr( proxy, ',' ) ) == 0 ) ||
    885             ( ( port = strchr( host+1, ',' ) ) == 0 ) )
    886         {
    887                 imcb_log( ic, "Error parsing proxy setting: \"%s\" (ignored)", proxy );
     875        if (((host = strchr(proxy, ',')) == 0) ||
     876            ((port = strchr(host + 1, ',')) == 0)) {
     877                imcb_log(ic, "Error parsing proxy setting: \"%s\" (ignored)", proxy);
    888878                return NULL;
    889879        }
    890        
     880
    891881        jid = proxy;
    892882        *host++ = '\0';
    893883        *port++ = '\0';
    894884
    895         sh = g_new0( jabber_streamhost_t, 1 );
    896         sh->jid = g_strdup( jid );
    897         sh->host = g_strdup( host );
    898         g_snprintf( sh->port, sizeof( sh->port ), "%s", port );
     885        sh = g_new0(jabber_streamhost_t, 1);
     886        sh->jid = g_strdup(jid);
     887        sh->host = g_strdup(host);
     888        g_snprintf(sh->port, sizeof(sh->port), "%s", port);
    899889
    900890        return sh;
    901891}
    902892
    903 void jabber_si_set_proxies( struct bs_transfer *bt )
     893void jabber_si_set_proxies(struct bs_transfer *bt)
    904894{
    905895        struct jabber_transfer *tf = bt->tf;
    906896        struct jabber_data *jd = tf->ic->proto_data;
    907         char *proxysetting = g_strdup ( set_getstr( &tf->ic->acc->set, "proxy" ) );
     897        char *proxysetting = g_strdup(set_getstr(&tf->ic->acc->set, "proxy"));
    908898        char *proxy, *next, *errmsg = NULL;
    909899        char port[6];
    910         char host[HOST_NAME_MAX+1];
     900        char host[HOST_NAME_MAX + 1];
    911901        jabber_streamhost_t *sh, *sh2;
    912902        GSList *streamhosts = jd->streamhosts;
    913903
    914904        proxy = proxysetting;
    915         while ( proxy && ( *proxy!='\0' ) ) {
    916                 if( ( next = strchr( proxy, ';' ) ) )
    917                         *next++ = '\0';
    918                
    919                 if( strcmp( proxy, "<local>" ) == 0 ) {
    920                         if( ( tf->fd = ft_listen( &tf->saddr, host, port, jd->fd, FALSE, &errmsg ) ) != -1 ) {
    921                                 sh = g_new0( jabber_streamhost_t, 1 );
    922                                 sh->jid = g_strdup( tf->ini_jid );
    923                                 sh->host = g_strdup( host );
    924                                 g_snprintf( sh->port, sizeof( sh->port ), "%s", port );
    925                                 bt->streamhosts = g_slist_append( bt->streamhosts, sh );
    926 
    927                                 bt->tf->watch_in = b_input_add( tf->fd, B_EV_IO_READ, jabber_bs_send_handshake, bt );
    928                                 bt->connect_timeout = b_timeout_add( JABBER_BS_LISTEN_TIMEOUT * 1000, jabber_bs_connect_timeout, bt );
     905        while (proxy && (*proxy != '\0')) {
     906                if ((next = strchr(proxy, ';'))) {
     907                        *next++ = '\0';
     908                }
     909
     910                if (strcmp(proxy, "<local>") == 0) {
     911                        if ((tf->fd = ft_listen(&tf->saddr, host, port, jd->fd, FALSE, &errmsg)) != -1) {
     912                                sh = g_new0(jabber_streamhost_t, 1);
     913                                sh->jid = g_strdup(tf->ini_jid);
     914                                sh->host = g_strdup(host);
     915                                g_snprintf(sh->port, sizeof(sh->port), "%s", port);
     916                                bt->streamhosts = g_slist_append(bt->streamhosts, sh);
     917
     918                                bt->tf->watch_in = b_input_add(tf->fd, B_EV_IO_READ, jabber_bs_send_handshake, bt);
     919                                bt->connect_timeout = b_timeout_add(JABBER_BS_LISTEN_TIMEOUT * 1000,
     920                                                                    jabber_bs_connect_timeout, bt);
    929921                        } else {
    930                                 imcb_log( tf->ic, "Transferring file %s: couldn't listen locally(non fatal, check your ft_listen setting in bitlbee.conf): %s",
    931                                           tf->ft->file_name,
    932                                           errmsg );
     922                                imcb_log(tf->ic,
     923                                         "Transferring file %s: couldn't listen locally(non fatal, check your ft_listen setting in bitlbee.conf): %s",
     924                                         tf->ft->file_name,
     925                                         errmsg);
    933926                        }
    934                 } else if( strcmp( proxy, "<auto>" ) == 0 ) {
    935                         while ( streamhosts ) {
    936                                 sh = g_new0( jabber_streamhost_t, 1 );
     927                } else if (strcmp(proxy, "<auto>") == 0) {
     928                        while (streamhosts) {
     929                                sh = g_new0(jabber_streamhost_t, 1);
    937930                                sh2 = streamhosts->data;
    938                                 sh->jid = g_strdup( sh2->jid );
    939                                 sh->host = g_strdup( sh2->host );
    940                                 strcpy( sh->port, sh2->port );
    941                                 bt->streamhosts = g_slist_append( bt->streamhosts, sh );
    942                                 streamhosts = g_slist_next( streamhosts );
     931                                sh->jid = g_strdup(sh2->jid);
     932                                sh->host = g_strdup(sh2->host);
     933                                strcpy(sh->port, sh2->port);
     934                                bt->streamhosts = g_slist_append(bt->streamhosts, sh);
     935                                streamhosts = g_slist_next(streamhosts);
    943936                        }
    944                 } else if( ( sh = jabber_si_parse_proxy( tf->ic, proxy ) ) )
    945                         bt->streamhosts = g_slist_append( bt->streamhosts, sh );
     937                } else if ((sh = jabber_si_parse_proxy(tf->ic, proxy))) {
     938                        bt->streamhosts = g_slist_append(bt->streamhosts, sh);
     939                }
    946940                proxy = next;
    947941        }
     
    951945 * Starts a bytestream.
    952946 */
    953 gboolean jabber_bs_send_start( struct jabber_transfer *tf )
     947gboolean jabber_bs_send_start(struct jabber_transfer *tf)
    954948{
    955949        struct bs_transfer *bt;
     
    957951        char hash_hex[41];
    958952        unsigned char hash[20];
    959         int i,ret;
     953        int i, ret;
    960954
    961955        /* SHA1( SID + Initiator JID + Target JID ) is given to the streamhost which it will match against the initiator's value */
    962         sha1_init( &sha );
    963         sha1_append( &sha, (unsigned char*) tf->sid, strlen( tf->sid ) );
    964         sha1_append( &sha, (unsigned char*) tf->ini_jid, strlen( tf->ini_jid ) );
    965         sha1_append( &sha, (unsigned char*) tf->tgt_jid, strlen( tf->tgt_jid ) );
    966         sha1_finish( &sha, hash );
    967        
    968         for( i = 0; i < 20; i ++ )
    969                 sprintf( hash_hex + i * 2, "%02x", hash[i] );
    970                
    971         bt = g_new0( struct bs_transfer, 1 );
     956        sha1_init(&sha);
     957        sha1_append(&sha, (unsigned char *) tf->sid, strlen(tf->sid));
     958        sha1_append(&sha, (unsigned char *) tf->ini_jid, strlen(tf->ini_jid));
     959        sha1_append(&sha, (unsigned char *) tf->tgt_jid, strlen(tf->tgt_jid));
     960        sha1_finish(&sha, hash);
     961
     962        for (i = 0; i < 20; i++) {
     963                sprintf(hash_hex + i * 2, "%02x", hash[i]);
     964        }
     965
     966        bt = g_new0(struct bs_transfer, 1);
    972967        bt->tf = tf;
    973968        bt->phase = BS_PHASE_CONNECT;
    974         bt->pseudoadr = g_strdup( hash_hex );
     969        bt->pseudoadr = g_strdup(hash_hex);
    975970        tf->streamhandle = bt;
    976971        tf->ft->free = jabber_bs_free_transfer;
    977972        tf->ft->canceled = jabber_bs_canceled;
    978973
    979         jabber_si_set_proxies( bt );
    980 
    981         ret = jabber_bs_send_request( tf, bt->streamhosts);
     974        jabber_si_set_proxies(bt);
     975
     976        ret = jabber_bs_send_request(tf, bt->streamhosts);
    982977
    983978        return ret;
    984979}
    985980
    986 gboolean jabber_bs_send_request( struct jabber_transfer *tf, GSList *streamhosts )
     981gboolean jabber_bs_send_request(struct jabber_transfer *tf, GSList *streamhosts)
    987982{
    988983        struct xt_node *shnode, *query, *iq;
    989984
    990         query = xt_new_node( "query", NULL, NULL );
    991         xt_add_attr( query, "xmlns", XMLNS_BYTESTREAMS );
    992         xt_add_attr( query, "sid", tf->sid );
    993         xt_add_attr( query, "mode", "tcp" );
    994 
    995         while( streamhosts ) {
     985        query = xt_new_node("query", NULL, NULL);
     986        xt_add_attr(query, "xmlns", XMLNS_BYTESTREAMS);
     987        xt_add_attr(query, "sid", tf->sid);
     988        xt_add_attr(query, "mode", "tcp");
     989
     990        while (streamhosts) {
    996991                jabber_streamhost_t *sh = streamhosts->data;
    997                 shnode = xt_new_node( "streamhost", NULL, NULL );
    998                 xt_add_attr( shnode, "jid", sh->jid );
    999                 xt_add_attr( shnode, "host", sh->host );
    1000                 xt_add_attr( shnode, "port", sh->port );
    1001 
    1002                 xt_add_child( query, shnode );
    1003 
    1004                 streamhosts = g_slist_next( streamhosts );
    1005         }
    1006 
    1007 
    1008         iq = jabber_make_packet( "iq", "set", tf->tgt_jid, query );
    1009         xt_add_attr( iq, "from", tf->ini_jid );
    1010 
    1011         jabber_cache_add( tf->ic, iq, jabber_bs_send_handle_reply );
    1012 
    1013         if( !jabber_write_packet( tf->ic, iq ) )
    1014                 imcb_file_canceled( tf->ic, tf->ft, "Error transmitting bytestream request" );
     992                shnode = xt_new_node("streamhost", NULL, NULL);
     993                xt_add_attr(shnode, "jid", sh->jid);
     994                xt_add_attr(shnode, "host", sh->host);
     995                xt_add_attr(shnode, "port", sh->port);
     996
     997                xt_add_child(query, shnode);
     998
     999                streamhosts = g_slist_next(streamhosts);
     1000        }
     1001
     1002
     1003        iq = jabber_make_packet("iq", "set", tf->tgt_jid, query);
     1004        xt_add_attr(iq, "from", tf->ini_jid);
     1005
     1006        jabber_cache_add(tf->ic, iq, jabber_bs_send_handle_reply);
     1007
     1008        if (!jabber_write_packet(tf->ic, iq)) {
     1009                imcb_file_canceled(tf->ic, tf->ft, "Error transmitting bytestream request");
     1010        }
    10151011        return TRUE;
    10161012}
    10171013
    1018 gboolean jabber_bs_send_handshake_abort(struct bs_transfer *bt, char *error )
     1014gboolean jabber_bs_send_handshake_abort(struct bs_transfer *bt, char *error)
    10191015{
    10201016        struct jabber_transfer *tf = bt->tf;
     
    10221018
    10231019        /* TODO: did the receiver get here somehow??? */
    1024         imcb_log( tf->ic, "Transferring file %s: SOCKS5 handshake failed: %s",
    1025                   tf->ft->file_name,
    1026                   error );
    1027 
    1028         if( jd->streamhosts==NULL ) /* we're done here unless we have a proxy to try */
    1029                 imcb_file_canceled( tf->ic, tf->ft, error );
     1020        imcb_log(tf->ic, "Transferring file %s: SOCKS5 handshake failed: %s",
     1021                 tf->ft->file_name,
     1022                 error);
     1023
     1024        if (jd->streamhosts == NULL) { /* we're done here unless we have a proxy to try */
     1025                imcb_file_canceled(tf->ic, tf->ft, error);
     1026        }
    10301027
    10311028        /* MUST always return FALSE! */
     
    10361033 * SOCKS5BYTESTREAM protocol for the sender
    10371034 */
    1038 gboolean jabber_bs_send_handshake( gpointer data, gint fd, b_input_condition cond )
     1035gboolean jabber_bs_send_handshake(gpointer data, gint fd, b_input_condition cond)
    10391036{
    10401037        struct bs_transfer *bt = data;
     
    10421039        short revents;
    10431040
    1044         if ( !jabber_bs_poll( bt, fd, &revents ) )
     1041        if (!jabber_bs_poll(bt, fd, &revents)) {
    10451042                return FALSE;
    1046        
    1047         switch( bt->phase )
     1043        }
     1044
     1045        switch (bt->phase) {
     1046        case BS_PHASE_CONNECT:
    10481047        {
    1049         case BS_PHASE_CONNECT:
    1050                 {
    1051                         struct sockaddr_storage clt_addr;
    1052                         socklen_t ssize = sizeof( clt_addr );
    1053                        
    1054                         /* Connect */
    1055 
    1056                         ASSERTSOCKOP( tf->fd = accept( fd, (struct sockaddr *) &clt_addr, &ssize ), "Accepting connection" );
    1057 
    1058                         closesocket( fd );
    1059                         fd = tf->fd;
    1060                         sock_make_nonblocking( fd );
    1061                        
    1062                         bt->phase = BS_PHASE_CONNECTED;
    1063 
    1064                         bt->tf->watch_in = b_input_add( fd, B_EV_IO_READ, jabber_bs_send_handshake, bt );
     1048                struct sockaddr_storage clt_addr;
     1049                socklen_t ssize = sizeof(clt_addr);
     1050
     1051                /* Connect */
     1052
     1053                ASSERTSOCKOP(tf->fd = accept(fd, (struct sockaddr *) &clt_addr, &ssize), "Accepting connection");
     1054
     1055                closesocket(fd);
     1056                fd = tf->fd;
     1057                sock_make_nonblocking(fd);
     1058
     1059                bt->phase = BS_PHASE_CONNECTED;
     1060
     1061                bt->tf->watch_in = b_input_add(fd, B_EV_IO_READ, jabber_bs_send_handshake, bt);
     1062                return FALSE;
     1063        }
     1064        case BS_PHASE_CONNECTED:
     1065        {
     1066                int ret, have_noauth = FALSE;
     1067                struct {
     1068                        unsigned char ver;
     1069                        unsigned char method;
     1070                } socks5_auth_reply = { .ver = 5, .method = 0 };
     1071                struct {
     1072                        unsigned char ver;
     1073                        unsigned char nmethods;
     1074                        unsigned char method;
     1075                } socks5_hello;
     1076
     1077                if (!(ret = jabber_bs_peek(bt, &socks5_hello, sizeof(socks5_hello)))) {
    10651078                        return FALSE;
    10661079                }
    1067         case BS_PHASE_CONNECTED:
    1068                 {
    1069                         int ret, have_noauth=FALSE;
    1070                         struct {
    1071                                 unsigned char ver;
    1072                                 unsigned char method;
    1073                         } socks5_auth_reply = { .ver = 5, .method = 0 };
    1074                         struct {
    1075                                 unsigned char ver;
    1076                                 unsigned char nmethods;
    1077                                 unsigned char method;
    1078                         } socks5_hello;
    1079 
    1080                         if( !( ret = jabber_bs_peek( bt, &socks5_hello, sizeof( socks5_hello ) ) ) )
    1081                                 return FALSE;
    1082 
    1083                         if( ret < sizeof( socks5_hello ) )
    1084                                 return TRUE;
    1085 
    1086                         if( !( socks5_hello.ver == 5 ) ||
    1087                             !( socks5_hello.nmethods >= 1 ) ||
    1088                             !( socks5_hello.nmethods < 32 ) )
    1089                                 return jabber_bs_abort( bt, "Invalid auth request ver=%d nmethods=%d method=%d", socks5_hello.ver, socks5_hello.nmethods, socks5_hello.method );
    1090 
    1091                         have_noauth = socks5_hello.method == 0;
    1092 
    1093                         if( socks5_hello.nmethods > 1 )
    1094                         {
    1095                                 char mbuf[32];
    1096                                 int i;
    1097                                 ASSERTSOCKOP( ret = recv( fd, mbuf, socks5_hello.nmethods - 1, 0 ) , "Receiving auth methods" );
    1098                                 if( ret < ( socks5_hello.nmethods - 1 ) )
    1099                                         return jabber_bs_abort( bt, "Partial auth request");
    1100                                 for( i = 0 ; !have_noauth && ( i < socks5_hello.nmethods - 1 ) ; i ++ )
    1101                                         if( mbuf[i] == 0 )
    1102                                                 have_noauth = TRUE;
     1080
     1081                if (ret < sizeof(socks5_hello)) {
     1082                        return TRUE;
     1083                }
     1084
     1085                if (!(socks5_hello.ver == 5) ||
     1086                    !(socks5_hello.nmethods >= 1) ||
     1087                    !(socks5_hello.nmethods < 32)) {
     1088                        return jabber_bs_abort(bt, "Invalid auth request ver=%d nmethods=%d method=%d",
     1089                                               socks5_hello.ver, socks5_hello.nmethods, socks5_hello.method);
     1090                }
     1091
     1092                have_noauth = socks5_hello.method == 0;
     1093
     1094                if (socks5_hello.nmethods > 1) {
     1095                        char mbuf[32];
     1096                        int i;
     1097                        ASSERTSOCKOP(ret = recv(fd, mbuf, socks5_hello.nmethods - 1, 0), "Receiving auth methods");
     1098                        if (ret < (socks5_hello.nmethods - 1)) {
     1099                                return jabber_bs_abort(bt, "Partial auth request");
    11031100                        }
    1104                        
    1105                         if( !have_noauth )
    1106                                 return jabber_bs_abort( bt, "Auth request didn't include no authentication" );
    1107 
    1108                         ASSERTSOCKOP( send( fd, &socks5_auth_reply, sizeof( socks5_auth_reply ) , 0 ), "Sending auth reply" );
    1109 
    1110                         bt->phase = BS_PHASE_REQUEST;
    1111 
     1101                        for (i = 0; !have_noauth && (i < socks5_hello.nmethods - 1); i++) {
     1102                                if (mbuf[i] == 0) {
     1103                                        have_noauth = TRUE;
     1104                                }
     1105                        }
     1106                }
     1107
     1108                if (!have_noauth) {
     1109                        return jabber_bs_abort(bt, "Auth request didn't include no authentication");
     1110                }
     1111
     1112                ASSERTSOCKOP(send(fd, &socks5_auth_reply, sizeof(socks5_auth_reply), 0), "Sending auth reply");
     1113
     1114                bt->phase = BS_PHASE_REQUEST;
     1115
     1116                return TRUE;
     1117        }
     1118        case BS_PHASE_REQUEST:
     1119        {
     1120                struct socks5_message socks5_connect;
     1121                int msgsize = sizeof(struct socks5_message);
     1122                int ret;
     1123
     1124                if (!(ret = jabber_bs_peek(bt, &socks5_connect, msgsize))) {
     1125                        return FALSE;
     1126                }
     1127
     1128                if (ret < msgsize) {
    11121129                        return TRUE;
    11131130                }
    1114         case BS_PHASE_REQUEST:
    1115                 {
    1116                         struct socks5_message socks5_connect;
    1117                         int msgsize = sizeof( struct socks5_message );
    1118                         int ret;
    1119 
    1120                         if( !( ret = jabber_bs_peek( bt, &socks5_connect, msgsize ) ) )
    1121                                 return FALSE;
    1122 
    1123                         if( ret < msgsize )
    1124                                 return TRUE;
    1125 
    1126                         if( !( socks5_connect.ver == 5) ||
    1127                             !( socks5_connect.cmdrep.cmd == 1 ) ||
    1128                             !( socks5_connect.atyp == 3 ) ||
    1129                             !(socks5_connect.addrlen == 40 ) )
    1130                                 return jabber_bs_abort( bt, "Invalid SOCKS5 Connect message (addrlen=%d, ver=%d, cmd=%d, atyp=%d)", socks5_connect.addrlen, socks5_connect.ver, socks5_connect.cmdrep.cmd, socks5_connect.atyp );
    1131                         if( !( memcmp( socks5_connect.address, bt->pseudoadr, 40 ) == 0 ) )
    1132                                 return jabber_bs_abort( bt, "SOCKS5 Connect message contained wrong digest");
    1133 
    1134                         socks5_connect.cmdrep.rep = 0;
    1135 
    1136                         ASSERTSOCKOP( send( fd, &socks5_connect, msgsize, 0 ), "Sending connect reply" );
    1137 
    1138                         bt->phase = BS_PHASE_REPLY;
    1139 
    1140                         imcb_log( tf->ic, "File %s: SOCKS5 handshake successful! Transfer about to start...", tf->ft->file_name );
    1141 
    1142                         if( tf->accepted )
    1143                         {
    1144                                 /* streamhost-used message came already in(possible?), let's start sending */
    1145                                 tf->ft->write_request( tf->ft );
    1146                         }
    1147 
    1148                         tf->watch_in = 0;
    1149                         return FALSE;
    1150 
    1151                 }
     1131
     1132                if (!(socks5_connect.ver == 5) ||
     1133                    !(socks5_connect.cmdrep.cmd == 1) ||
     1134                    !(socks5_connect.atyp == 3) ||
     1135                    !(socks5_connect.addrlen == 40)) {
     1136                        return jabber_bs_abort(bt,
     1137                                               "Invalid SOCKS5 Connect message (addrlen=%d, ver=%d, cmd=%d, atyp=%d)",
     1138                                               socks5_connect.addrlen, socks5_connect.ver, socks5_connect.cmdrep.cmd,
     1139                                               socks5_connect.atyp);
     1140                }
     1141                if (!(memcmp(socks5_connect.address, bt->pseudoadr, 40) == 0)) {
     1142                        return jabber_bs_abort(bt, "SOCKS5 Connect message contained wrong digest");
     1143                }
     1144
     1145                socks5_connect.cmdrep.rep = 0;
     1146
     1147                ASSERTSOCKOP(send(fd, &socks5_connect, msgsize, 0), "Sending connect reply");
     1148
     1149                bt->phase = BS_PHASE_REPLY;
     1150
     1151                imcb_log(tf->ic, "File %s: SOCKS5 handshake successful! Transfer about to start...", tf->ft->file_name);
     1152
     1153                if (tf->accepted) {
     1154                        /* streamhost-used message came already in(possible?), let's start sending */
     1155                        tf->ft->write_request(tf->ft);
     1156                }
     1157
     1158                tf->watch_in = 0;
     1159                return FALSE;
     1160
     1161        }
    11521162        default:
    11531163                /* BUG */
    1154                 imcb_log( bt->tf->ic, "BUG in file transfer code: undefined handshake phase" );
     1164                imcb_log(bt->tf->ic, "BUG in file transfer code: undefined handshake phase");
    11551165
    11561166                bt->tf->watch_in = 0;
  • protocols/jabber/sasl.c

    raf359b4 r5ebff60  
    4848};
    4949
    50 xt_status sasl_pkt_mechanisms( struct xt_node *node, gpointer data )
     50xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data)
    5151{
    5252        struct im_connection *ic = data;
     
    5757        int want_oauth = FALSE;
    5858        GString *mechs;
    59        
    60         if( !sasl_supported( ic ) )
    61         {
     59
     60        if (!sasl_supported(ic)) {
    6261                /* Should abort this now, since we should already be doing
    6362                   IQ authentication. Strange things happen when you try
    6463                   to do both... */
    65                 imcb_log( ic, "XMPP 1.0 non-compliant server seems to support SASL, please report this as a BitlBee bug!" );
     64                imcb_log(ic,
     65                         "XMPP 1.0 non-compliant server seems to support SASL, please report this as a BitlBee bug!");
    6666                return XT_HANDLED;
    6767        }
    68        
    69         s = xt_find_attr( node, "xmlns" );
    70         if( !s || strcmp( s, XMLNS_SASL ) != 0 )
    71         {
    72                 imcb_log( ic, "Stream error while authenticating" );
    73                 imc_logout( ic, FALSE );
     68
     69        s = xt_find_attr(node, "xmlns");
     70        if (!s || strcmp(s, XMLNS_SASL) != 0) {
     71                imcb_log(ic, "Stream error while authenticating");
     72                imc_logout(ic, FALSE);
    7473                return XT_ABORT;
    7574        }
    76        
    77         want_oauth = set_getbool( &ic->acc->set, "oauth" );
    78        
    79         mechs = g_string_new( "" );
     75
     76        want_oauth = set_getbool(&ic->acc->set, "oauth");
     77
     78        mechs = g_string_new("");
    8079        c = node->children;
    81         while( ( c = xt_find_node( c, "mechanism" ) ) )
    82         {
    83                 if( c->text && g_strcasecmp( c->text, "PLAIN" ) == 0 )
     80        while ((c = xt_find_node(c, "mechanism"))) {
     81                if (c->text && g_strcasecmp(c->text, "PLAIN") == 0) {
    8482                        sup_plain = 1;
    85                 else if( c->text && g_strcasecmp( c->text, "DIGEST-MD5" ) == 0 )
     83                } else if (c->text && g_strcasecmp(c->text, "DIGEST-MD5") == 0) {
    8684                        sup_digest = 1;
    87                 else if( c->text && g_strcasecmp( c->text, "X-OAUTH2" ) == 0 )
     85                } else if (c->text && g_strcasecmp(c->text, "X-OAUTH2") == 0) {
    8886                        sup_gtalk = 1;
    89                 else if( c->text && g_strcasecmp( c->text, "X-FACEBOOK-PLATFORM" ) == 0 )
     87                } else if (c->text && g_strcasecmp(c->text, "X-FACEBOOK-PLATFORM") == 0) {
    9088                        sup_fb = 1;
    91                
    92                 if( c->text )
    93                         g_string_append_printf( mechs, " %s", c->text );
    94                
     89                }
     90
     91                if (c->text) {
     92                        g_string_append_printf(mechs, " %s", c->text);
     93                }
     94
    9595                c = c->next;
    9696        }
    97        
    98         if( !want_oauth && !sup_plain && !sup_digest )
    99         {
    100                 if( !sup_gtalk && !sup_fb )
    101                         imcb_error( ic, "This server requires OAuth "
    102                                         "(supported schemes:%s)", mechs->str );
    103                 else
    104                         imcb_error( ic, "BitlBee does not support any of the offered SASL "
    105                                         "authentication schemes:%s", mechs->str );
    106                 imc_logout( ic, FALSE );
    107                 g_string_free( mechs, TRUE );
     97
     98        if (!want_oauth && !sup_plain && !sup_digest) {
     99                if (!sup_gtalk && !sup_fb) {
     100                        imcb_error(ic, "This server requires OAuth "
     101                                   "(supported schemes:%s)", mechs->str);
     102                } else {
     103                        imcb_error(ic, "BitlBee does not support any of the offered SASL "
     104                                   "authentication schemes:%s", mechs->str);
     105                }
     106                imc_logout(ic, FALSE);
     107                g_string_free(mechs, TRUE);
    108108                return XT_ABORT;
    109109        }
    110         g_string_free( mechs, TRUE );
    111        
    112         reply = xt_new_node( "auth", NULL, NULL );
    113         xt_add_attr( reply, "xmlns", XMLNS_SASL );
    114        
    115         if( sup_gtalk && want_oauth )
    116         {
     110        g_string_free(mechs, TRUE);
     111
     112        reply = xt_new_node("auth", NULL, NULL);
     113        xt_add_attr(reply, "xmlns", XMLNS_SASL);
     114
     115        if (sup_gtalk && want_oauth) {
    117116                int len;
    118                
     117
    119118                /* X-OAUTH2 is, not *the* standard OAuth2 SASL/XMPP implementation.
    120119                   It's currently used by GTalk and vaguely documented on
    121120                   http://code.google.com/apis/cloudprint/docs/rawxmpp.html . */
    122                 xt_add_attr( reply, "mechanism", "X-OAUTH2" );
    123                
    124                 len = strlen( jd->username ) + strlen( jd->oauth2_access_token ) + 2;
    125                 s = g_malloc( len + 1 );
     121                xt_add_attr(reply, "mechanism", "X-OAUTH2");
     122
     123                len = strlen(jd->username) + strlen(jd->oauth2_access_token) + 2;
     124                s = g_malloc(len + 1);
    126125                s[0] = 0;
    127                 strcpy( s + 1, jd->username );
    128                 strcpy( s + 2 + strlen( jd->username ), jd->oauth2_access_token );
    129                 reply->text = base64_encode( (unsigned char *)s, len );
    130                 reply->text_len = strlen( reply->text );
    131                 g_free( s );
    132         }
    133         else if( sup_fb && want_oauth )
    134         {
    135                 xt_add_attr( reply, "mechanism", "X-FACEBOOK-PLATFORM" );
     126                strcpy(s + 1, jd->username);
     127                strcpy(s + 2 + strlen(jd->username), jd->oauth2_access_token);
     128                reply->text = base64_encode((unsigned char *) s, len);
     129                reply->text_len = strlen(reply->text);
     130                g_free(s);
     131        } else if (sup_fb && want_oauth) {
     132                xt_add_attr(reply, "mechanism", "X-FACEBOOK-PLATFORM");
    136133                jd->flags |= JFLAG_SASL_FB;
    137         }
    138         else if( want_oauth )
    139         {
    140                 imcb_error( ic, "OAuth requested, but not supported by server" );
    141                 imc_logout( ic, FALSE );
    142                 xt_free_node( reply );
     134        } else if (want_oauth) {
     135                imcb_error(ic, "OAuth requested, but not supported by server");
     136                imc_logout(ic, FALSE);
     137                xt_free_node(reply);
    143138                return XT_ABORT;
    144         }
    145         else if( sup_digest )
    146         {
    147                 xt_add_attr( reply, "mechanism", "DIGEST-MD5" );
    148                
     139        } else if (sup_digest) {
     140                xt_add_attr(reply, "mechanism", "DIGEST-MD5");
     141
    149142                /* The rest will be done later, when we receive a <challenge/>. */
    150         }
    151         else if( sup_plain )
    152         {
     143        } else if (sup_plain) {
    153144                int len;
    154                
    155                 xt_add_attr( reply, "mechanism", "PLAIN" );
    156                
     145
     146                xt_add_attr(reply, "mechanism", "PLAIN");
     147
    157148                /* With SASL PLAIN in XMPP, the text should be b64(\0user\0pass) */
    158                 len = strlen( jd->username ) + strlen( ic->acc->pass ) + 2;
    159                 s = g_malloc( len + 1 );
     149                len = strlen(jd->username) + strlen(ic->acc->pass) + 2;
     150                s = g_malloc(len + 1);
    160151                s[0] = 0;
    161                 strcpy( s + 1, jd->username );
    162                 strcpy( s + 2 + strlen( jd->username ), ic->acc->pass );
    163                 reply->text = base64_encode( (unsigned char *)s, len );
    164                 reply->text_len = strlen( reply->text );
    165                 g_free( s );
    166         }
    167        
    168         if( reply && !jabber_write_packet( ic, reply ) )
    169         {
    170                 xt_free_node( reply );
     152                strcpy(s + 1, jd->username);
     153                strcpy(s + 2 + strlen(jd->username), ic->acc->pass);
     154                reply->text = base64_encode((unsigned char *) s, len);
     155                reply->text_len = strlen(reply->text);
     156                g_free(s);
     157        }
     158
     159        if (reply && !jabber_write_packet(ic, reply)) {
     160                xt_free_node(reply);
    171161                return XT_ABORT;
    172162        }
    173         xt_free_node( reply );
    174        
     163        xt_free_node(reply);
     164
    175165        /* To prevent classic authentication from happening. */
    176166        jd->flags |= JFLAG_STREAM_STARTED;
    177        
     167
    178168        return XT_HANDLED;
    179169}
     
    181171/* Non-static function, but not mentioned in jabber.h because it's for internal
    182172   use, just that the unittest should be able to reach it... */
    183 char *sasl_get_part( char *data, char *field )
     173char *sasl_get_part(char *data, char *field)
    184174{
    185175        int i, len;
    186        
    187         len = strlen( field );
    188        
    189         while( g_ascii_isspace( *data ) || *data == ',' )
    190                 data ++;
    191        
    192         if( g_strncasecmp( data, field, len ) == 0 && data[len] == '=' )
    193         {
    194                 i = strlen( field ) + 1;
    195         }
    196         else
    197         {
    198                 for( i = 0; data[i]; i ++ )
    199                 {
     176
     177        len = strlen(field);
     178
     179        while (g_ascii_isspace(*data) || *data == ',') {
     180                data++;
     181        }
     182
     183        if (g_strncasecmp(data, field, len) == 0 && data[len] == '=') {
     184                i = strlen(field) + 1;
     185        } else {
     186                for (i = 0; data[i]; i++) {
    200187                        /* If we have a ", skip until it's closed again. */
    201                         if( data[i] == '"' )
    202                         {
    203                                 i ++;
    204                                 while( data[i] != '"' || data[i-1] == '\\' )
    205                                         i ++;
     188                        if (data[i] == '"') {
     189                                i++;
     190                                while (data[i] != '"' || data[i - 1] == '\\') {
     191                                        i++;
     192                                }
    206193                        }
    207                        
     194
    208195                        /* If we got a comma, we got a new field. Check it,
    209196                           find the next key after it. */
    210                         if( data[i] == ',' )
    211                         {
    212                                 while( g_ascii_isspace( data[i] ) || data[i] == ',' )
    213                                         i ++;
    214                                
    215                                 if( g_strncasecmp( data + i, field, len ) == 0 &&
    216                                     data[i+len] == '=' )
    217                                 {
     197                        if (data[i] == ',') {
     198                                while (g_ascii_isspace(data[i]) || data[i] == ',') {
     199                                        i++;
     200                                }
     201
     202                                if (g_strncasecmp(data + i, field, len) == 0 &&
     203                                    data[i + len] == '=') {
    218204                                        i += len + 1;
    219205                                        break;
     
    222208                }
    223209        }
    224        
    225         if( data[i] == '"' )
    226         {
     210
     211        if (data[i] == '"') {
    227212                int j;
    228213                char *ret;
    229                
    230                 i ++;
     214
     215                i++;
    231216                len = 0;
    232                 while( data[i+len] != '"' || data[i+len-1] == '\\' )
    233                         len ++;
    234                
    235                 ret = g_strndup( data + i, len );
    236                 for( i = j = 0; ret[i]; i ++ )
    237                 {
    238                         if( ret[i] == '\\' )
    239                         {
     217                while (data[i + len] != '"' || data[i + len - 1] == '\\') {
     218                        len++;
     219                }
     220
     221                ret = g_strndup(data + i, len);
     222                for (i = j = 0; ret[i]; i++) {
     223                        if (ret[i] == '\\') {
    240224                                ret[j++] = ret[++i];
    241                         }
    242                         else
    243                         {
     225                        } else {
    244226                                ret[j++] = ret[i];
    245227                        }
    246228                }
    247229                ret[j] = 0;
    248                
     230
    249231                return ret;
    250         }
    251         else if( data[i] )
    252         {
     232        } else if (data[i]) {
    253233                len = 0;
    254                 while( data[i+len] && data[i+len] != ',' )
    255                         len ++;
    256                
    257                 return g_strndup( data + i, len );
    258         }
    259         else
    260         {
     234                while (data[i + len] && data[i + len] != ',') {
     235                        len++;
     236                }
     237
     238                return g_strndup(data + i, len);
     239        } else {
    261240                return NULL;
    262241        }
    263242}
    264243
    265 xt_status sasl_pkt_challenge( struct xt_node *node, gpointer data )
     244xt_status sasl_pkt_challenge(struct xt_node *node, gpointer data)
    266245{
    267246        struct im_connection *ic = data;
     
    274253        char *s = NULL, *reply = NULL;
    275254        xt_status ret = XT_ABORT;
    276        
    277         if( node->text_len == 0 )
     255
     256        if (node->text_len == 0) {
    278257                goto error;
    279        
    280         dec = frombase64( node->text );
    281        
    282         if( jd->flags & JFLAG_SASL_FB )
    283         {
     258        }
     259
     260        dec = frombase64(node->text);
     261
     262        if (jd->flags & JFLAG_SASL_FB) {
    284263                /* New-style Facebook OAauth2 support. Instead of sending a refresh
    285264                   token, they just send an access token that should never expire. */
    286265                GSList *p_in = NULL, *p_out = NULL;
    287266                char time[33];
    288                
    289                 oauth_params_parse( &p_in, dec );
    290                 oauth_params_add( &p_out, "nonce", oauth_params_get( &p_in, "nonce" ) );
    291                 oauth_params_add( &p_out, "method", oauth_params_get( &p_in, "method" ) );
    292                 oauth_params_free( &p_in );
    293                
    294                 g_snprintf( time, sizeof( time ), "%lld", (long long) ( gettime() * 1000 ) );
    295                 oauth_params_add( &p_out, "call_id", time );
    296                 oauth_params_add( &p_out, "api_key", oauth2_service_facebook.consumer_key );
    297                 oauth_params_add( &p_out, "v", "1.0" );
    298                 oauth_params_add( &p_out, "format", "XML" );
    299                 oauth_params_add( &p_out, "access_token", jd->oauth2_access_token );
    300                
    301                 reply = oauth_params_string( p_out );
    302                 oauth_params_free( &p_out );
    303         }
    304         else if( !( s = sasl_get_part( dec, "rspauth" ) ) )
    305         {
     267
     268                oauth_params_parse(&p_in, dec);
     269                oauth_params_add(&p_out, "nonce", oauth_params_get(&p_in, "nonce"));
     270                oauth_params_add(&p_out, "method", oauth_params_get(&p_in, "method"));
     271                oauth_params_free(&p_in);
     272
     273                g_snprintf(time, sizeof(time), "%lld", (long long) (gettime() * 1000));
     274                oauth_params_add(&p_out, "call_id", time);
     275                oauth_params_add(&p_out, "api_key", oauth2_service_facebook.consumer_key);
     276                oauth_params_add(&p_out, "v", "1.0");
     277                oauth_params_add(&p_out, "format", "XML");
     278                oauth_params_add(&p_out, "access_token", jd->oauth2_access_token);
     279
     280                reply = oauth_params_string(p_out);
     281                oauth_params_free(&p_out);
     282        } else if (!(s = sasl_get_part(dec, "rspauth"))) {
    306283                /* See RFC 2831 for for information. */
    307284                md5_state_t A1, A2, H;
     
    309286                char A1h[33], A2h[33], Hh[33];
    310287                int i;
    311                
    312                 nonce = sasl_get_part( dec, "nonce" );
    313                 realm = sasl_get_part( dec, "realm" );
    314                
    315                 if( !nonce )
     288
     289                nonce = sasl_get_part(dec, "nonce");
     290                realm = sasl_get_part(dec, "realm");
     291
     292                if (!nonce) {
    316293                        goto error;
    317                
     294                }
     295
    318296                /* Jabber.Org considers the realm part optional and doesn't
    319297                   specify one. Oh well, actually they're right, but still,
    320298                   don't know if this is right... */
    321                 if( !realm )
    322                         realm = g_strdup( jd->server );
    323                
    324                 random_bytes( cnonce_bin, sizeof( cnonce_bin ) );
    325                 cnonce = base64_encode( cnonce_bin, sizeof( cnonce_bin ) );
    326                 digest_uri = g_strdup_printf( "%s/%s", "xmpp", jd->server );
    327                
     299                if (!realm) {
     300                        realm = g_strdup(jd->server);
     301                }
     302
     303                random_bytes(cnonce_bin, sizeof(cnonce_bin));
     304                cnonce = base64_encode(cnonce_bin, sizeof(cnonce_bin));
     305                digest_uri = g_strdup_printf("%s/%s", "xmpp", jd->server);
     306
    328307                /* Generate the MD5 hash of username:realm:password,
    329308                   I decided to call it H. */
    330                 md5_init( &H );
    331                 s = g_strdup_printf( "%s:%s:%s", jd->username, realm, ic->acc->pass );
    332                 md5_append( &H, (unsigned char *) s, strlen( s ) );
    333                 g_free( s );
    334                 md5_finish( &H, Hr );
    335                
     309                md5_init(&H);
     310                s = g_strdup_printf("%s:%s:%s", jd->username, realm, ic->acc->pass);
     311                md5_append(&H, (unsigned char *) s, strlen(s));
     312                g_free(s);
     313                md5_finish(&H, Hr);
     314
    336315                /* Now generate the hex. MD5 hash of H:nonce:cnonce, called A1. */
    337                 md5_init( &A1 );
    338                 s = g_strdup_printf( ":%s:%s", nonce, cnonce );
    339                 md5_append( &A1, Hr, 16 );
    340                 md5_append( &A1, (unsigned char *) s, strlen( s ) );
    341                 g_free( s );
    342                 md5_finish( &A1, A1r );
    343                 for( i = 0; i < 16; i ++ )
    344                         sprintf( A1h + i * 2, "%02x", A1r[i] );
    345                
     316                md5_init(&A1);
     317                s = g_strdup_printf(":%s:%s", nonce, cnonce);
     318                md5_append(&A1, Hr, 16);
     319                md5_append(&A1, (unsigned char *) s, strlen(s));
     320                g_free(s);
     321                md5_finish(&A1, A1r);
     322                for (i = 0; i < 16; i++) {
     323                        sprintf(A1h + i * 2, "%02x", A1r[i]);
     324                }
     325
    346326                /* A2... */
    347                 md5_init( &A2 );
    348                 s = g_strdup_printf( "%s:%s", "AUTHENTICATE", digest_uri );
    349                 md5_append( &A2, (unsigned char *) s, strlen( s ) );
    350                 g_free( s );
    351                 md5_finish( &A2, A2r );
    352                 for( i = 0; i < 16; i ++ )
    353                         sprintf( A2h + i * 2, "%02x", A2r[i] );
    354                
     327                md5_init(&A2);
     328                s = g_strdup_printf("%s:%s", "AUTHENTICATE", digest_uri);
     329                md5_append(&A2, (unsigned char *) s, strlen(s));
     330                g_free(s);
     331                md5_finish(&A2, A2r);
     332                for (i = 0; i < 16; i++) {
     333                        sprintf(A2h + i * 2, "%02x", A2r[i]);
     334                }
     335
    355336                /* Final result: A1:nonce:00000001:cnonce:auth:A2. Let's reuse H for it. */
    356                 md5_init( &H );
    357                 s = g_strdup_printf( "%s:%s:%s:%s:%s:%s", A1h, nonce, "00000001", cnonce, "auth", A2h );
    358                 md5_append( &H, (unsigned char *) s, strlen( s ) );
    359                 g_free( s );
    360                 md5_finish( &H, Hr );
    361                 for( i = 0; i < 16; i ++ )
    362                         sprintf( Hh + i * 2, "%02x", Hr[i] );
    363                
     337                md5_init(&H);
     338                s = g_strdup_printf("%s:%s:%s:%s:%s:%s", A1h, nonce, "00000001", cnonce, "auth", A2h);
     339                md5_append(&H, (unsigned char *) s, strlen(s));
     340                g_free(s);
     341                md5_finish(&H, Hr);
     342                for (i = 0; i < 16; i++) {
     343                        sprintf(Hh + i * 2, "%02x", Hr[i]);
     344                }
     345
    364346                /* Now build the SASL response string: */
    365                 reply = g_strdup_printf( "username=\"%s\",realm=\"%s\",nonce=\"%s\",cnonce=\"%s\","
    366                                          "nc=%08x,qop=auth,digest-uri=\"%s\",response=%s,charset=%s",
    367                                          jd->username, realm, nonce, cnonce, 1, digest_uri, Hh, "utf-8" );
    368         }
    369         else
    370         {
     347                reply = g_strdup_printf("username=\"%s\",realm=\"%s\",nonce=\"%s\",cnonce=\"%s\","
     348                                        "nc=%08x,qop=auth,digest-uri=\"%s\",response=%s,charset=%s",
     349                                        jd->username, realm, nonce, cnonce, 1, digest_uri, Hh, "utf-8");
     350        } else {
    371351                /* We found rspauth, but don't really care... */
    372                 g_free( s );
    373         }
    374        
    375         s = reply ? tobase64( reply ) : NULL;
    376         reply_pkt = xt_new_node( "response", s, NULL );
    377         xt_add_attr( reply_pkt, "xmlns", XMLNS_SASL );
    378        
    379         if( !jabber_write_packet( ic, reply_pkt ) )
     352                g_free(s);
     353        }
     354
     355        s = reply ? tobase64(reply) : NULL;
     356        reply_pkt = xt_new_node("response", s, NULL);
     357        xt_add_attr(reply_pkt, "xmlns", XMLNS_SASL);
     358
     359        if (!jabber_write_packet(ic, reply_pkt)) {
    380360                goto silent_error;
    381        
     361        }
     362
    382363        ret = XT_HANDLED;
    383364        goto silent_error;
    384365
    385366error:
    386         imcb_error( ic, "Incorrect SASL challenge received" );
    387         imc_logout( ic, FALSE );
     367        imcb_error(ic, "Incorrect SASL challenge received");
     368        imc_logout(ic, FALSE);
    388369
    389370silent_error:
    390         g_free( digest_uri );
    391         g_free( cnonce );
    392         g_free( nonce );
    393         g_free( reply );
    394         g_free( realm );
    395         g_free( dec );
    396         g_free( s );
    397         xt_free_node( reply_pkt );
    398        
     371        g_free(digest_uri);
     372        g_free(cnonce);
     373        g_free(nonce);
     374        g_free(reply);
     375        g_free(realm);
     376        g_free(dec);
     377        g_free(s);
     378        xt_free_node(reply_pkt);
     379
    399380        return ret;
    400381}
    401382
    402 xt_status sasl_pkt_result( struct xt_node *node, gpointer data )
     383xt_status sasl_pkt_result(struct xt_node *node, gpointer data)
    403384{
    404385        struct im_connection *ic = data;
    405386        struct jabber_data *jd = ic->proto_data;
    406387        char *s;
    407        
    408         s = xt_find_attr( node, "xmlns" );
    409         if( !s || strcmp( s, XMLNS_SASL ) != 0 )
    410         {
    411                 imcb_log( ic, "Stream error while authenticating" );
    412                 imc_logout( ic, FALSE );
     388
     389        s = xt_find_attr(node, "xmlns");
     390        if (!s || strcmp(s, XMLNS_SASL) != 0) {
     391                imcb_log(ic, "Stream error while authenticating");
     392                imc_logout(ic, FALSE);
    413393                return XT_ABORT;
    414394        }
    415        
    416         if( strcmp( node->name, "success" ) == 0 )
    417         {
    418                 imcb_log( ic, "Authentication finished" );
     395
     396        if (strcmp(node->name, "success") == 0) {
     397                imcb_log(ic, "Authentication finished");
    419398                jd->flags |= JFLAG_AUTHENTICATED | JFLAG_STREAM_RESTART;
    420         }
    421         else if( strcmp( node->name, "failure" ) == 0 )
    422         {
    423                 imcb_error( ic, "Authentication failure" );
    424                 imc_logout( ic, FALSE );
     399        } else if (strcmp(node->name, "failure") == 0) {
     400                imcb_error(ic, "Authentication failure");
     401                imc_logout(ic, FALSE);
    425402                return XT_ABORT;
    426403        }
    427        
     404
    428405        return XT_HANDLED;
    429406}
     
    432409   It's done by checking if the <stream:stream> from the server has a
    433410   version attribute. I don't know if this is the right way though... */
    434 gboolean sasl_supported( struct im_connection *ic )
    435 {
    436         struct jabber_data *jd = ic->proto_data;
    437        
    438         return ( jd->xt && jd->xt->root && xt_find_attr( jd->xt->root, "version" ) ) != 0;
    439 }
    440 
    441 void sasl_oauth2_init( struct im_connection *ic )
     411gboolean sasl_supported(struct im_connection *ic)
     412{
     413        struct jabber_data *jd = ic->proto_data;
     414
     415        return (jd->xt && jd->xt->root && xt_find_attr(jd->xt->root, "version")) != 0;
     416}
     417
     418void sasl_oauth2_init(struct im_connection *ic)
    442419{
    443420        struct jabber_data *jd = ic->proto_data;
    444421        char *msg, *url;
    445        
    446         imcb_log( ic, "Starting OAuth authentication" );
    447        
     422
     423        imcb_log(ic, "Starting OAuth authentication");
     424
    448425        /* Temporary contact, just used to receive the OAuth response. */
    449         imcb_add_buddy( ic, JABBER_OAUTH_HANDLE, NULL );
    450         url = oauth2_url( jd->oauth2_service );
    451         msg = g_strdup_printf( "Open this URL in your browser to authenticate: %s", url );
    452         imcb_buddy_msg( ic, JABBER_OAUTH_HANDLE, msg, 0, 0 );
    453         imcb_buddy_msg( ic, JABBER_OAUTH_HANDLE, "Respond to this message with the returned "
    454                                                  "authorization token.", 0, 0 );
    455        
    456         g_free( msg );
    457         g_free( url );
    458 }
    459 
    460 static gboolean sasl_oauth2_remove_contact( gpointer data, gint fd, b_input_condition cond )
     426        imcb_add_buddy(ic, JABBER_OAUTH_HANDLE, NULL);
     427        url = oauth2_url(jd->oauth2_service);
     428        msg = g_strdup_printf("Open this URL in your browser to authenticate: %s", url);
     429        imcb_buddy_msg(ic, JABBER_OAUTH_HANDLE, msg, 0, 0);
     430        imcb_buddy_msg(ic, JABBER_OAUTH_HANDLE, "Respond to this message with the returned "
     431                       "authorization token.", 0, 0);
     432
     433        g_free(msg);
     434        g_free(url);
     435}
     436
     437static gboolean sasl_oauth2_remove_contact(gpointer data, gint fd, b_input_condition cond)
    461438{
    462439        struct im_connection *ic = data;
    463         if( g_slist_find( jabber_connections, ic ) )
    464                 imcb_remove_buddy( ic, JABBER_OAUTH_HANDLE, NULL );
     440
     441        if (g_slist_find(jabber_connections, ic)) {
     442                imcb_remove_buddy(ic, JABBER_OAUTH_HANDLE, NULL);
     443        }
    465444        return FALSE;
    466445}
    467446
    468 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token, const char *error );
    469 
    470 int sasl_oauth2_get_refresh_token( struct im_connection *ic, const char *msg )
     447static void sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token,
     448                                  const char *error);
     449
     450int sasl_oauth2_get_refresh_token(struct im_connection *ic, const char *msg)
    471451{
    472452        struct jabber_data *jd = ic->proto_data;
    473453        char *code;
    474454        int ret;
    475        
    476         imcb_log( ic, "Requesting OAuth access token" );
    477        
     455
     456        imcb_log(ic, "Requesting OAuth access token");
     457
    478458        /* Don't do it here because the caller may get confused if the contact
    479459           we're currently sending a message to is deleted. */
    480         b_timeout_add( 1, sasl_oauth2_remove_contact, ic );
    481        
    482         code = g_strdup( msg );
    483         g_strstrip( code );
    484         ret = oauth2_access_token( jd->oauth2_service, OAUTH2_AUTH_CODE,
    485                                    code, sasl_oauth2_got_token, ic );
    486        
    487         g_free( code );
     460        b_timeout_add(1, sasl_oauth2_remove_contact, ic);
     461
     462        code = g_strdup(msg);
     463        g_strstrip(code);
     464        ret = oauth2_access_token(jd->oauth2_service, OAUTH2_AUTH_CODE,
     465                                  code, sasl_oauth2_got_token, ic);
     466
     467        g_free(code);
    488468        return ret;
    489469}
    490470
    491 int sasl_oauth2_refresh( struct im_connection *ic, const char *refresh_token )
    492 {
    493         struct jabber_data *jd = ic->proto_data;
    494        
    495         return oauth2_access_token( jd->oauth2_service, OAUTH2_AUTH_REFRESH,
    496                                     refresh_token, sasl_oauth2_got_token, ic );
    497 }
    498 
    499 static void sasl_oauth2_got_token( gpointer data, const char *access_token, const char *refresh_token, const char *error )
     471int sasl_oauth2_refresh(struct im_connection *ic, const char *refresh_token)
     472{
     473        struct jabber_data *jd = ic->proto_data;
     474
     475        return oauth2_access_token(jd->oauth2_service, OAUTH2_AUTH_REFRESH,
     476                                   refresh_token, sasl_oauth2_got_token, ic);
     477}
     478
     479static void sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token, const char *error)
    500480{
    501481        struct im_connection *ic = data;
    502482        struct jabber_data *jd;
    503483        GSList *auth = NULL;
    504        
    505         if( g_slist_find( jabber_connections, ic ) == NULL )
     484
     485        if (g_slist_find(jabber_connections, ic) == NULL) {
    506486                return;
    507        
     487        }
     488
    508489        jd = ic->proto_data;
    509        
    510         if( access_token == NULL )
    511         {
    512                 imcb_error( ic, "OAuth failure (%s)", error );
    513                 imc_logout( ic, TRUE );
     490
     491        if (access_token == NULL) {
     492                imcb_error(ic, "OAuth failure (%s)", error);
     493                imc_logout(ic, TRUE);
    514494                return;
    515495        }
    516        
    517         oauth_params_parse( &auth, ic->acc->pass );
    518         if( refresh_token )
    519                 oauth_params_set( &auth, "refresh_token", refresh_token );
    520         if( access_token )
    521                 oauth_params_set( &auth, "access_token", access_token );
    522        
    523         g_free( ic->acc->pass );
    524         ic->acc->pass = oauth_params_string( auth );
    525         oauth_params_free( &auth );
    526        
    527         g_free( jd->oauth2_access_token );
    528         jd->oauth2_access_token = g_strdup( access_token );
    529        
    530         jabber_connect( ic );
    531 }
     496
     497        oauth_params_parse(&auth, ic->acc->pass);
     498        if (refresh_token) {
     499                oauth_params_set(&auth, "refresh_token", refresh_token);
     500        }
     501        if (access_token) {
     502                oauth_params_set(&auth, "access_token", access_token);
     503        }
     504
     505        g_free(ic->acc->pass);
     506        ic->acc->pass = oauth_params_string(auth);
     507        oauth_params_free(&auth);
     508
     509        g_free(jd->oauth2_access_token);
     510        jd->oauth2_access_token = g_strdup(access_token);
     511
     512        jabber_connect(ic);
     513}
  • protocols/jabber/si.c

    raf359b4 r5ebff60  
    2525#include "sha1.h"
    2626
    27 void jabber_si_answer_request( file_transfer_t *ft );
    28 int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf );
     27void jabber_si_answer_request(file_transfer_t *ft);
     28int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf);
    2929
    3030/* file_transfer free() callback */
    31 void jabber_si_free_transfer( file_transfer_t *ft)
     31void jabber_si_free_transfer(file_transfer_t *ft)
    3232{
    3333        struct jabber_transfer *tf = ft->data;
    3434        struct jabber_data *jd = tf->ic->proto_data;
    3535
    36         if ( tf->watch_in )
    37         {
    38                 b_event_remove( tf->watch_in );
     36        if (tf->watch_in) {
     37                b_event_remove(tf->watch_in);
    3938                tf->watch_in = 0;
    4039        }
    4140
    42         jd->filetransfers = g_slist_remove( jd->filetransfers, tf );
    43 
    44         if( tf->fd != -1 )
    45         {
    46                 closesocket( tf->fd );
     41        jd->filetransfers = g_slist_remove(jd->filetransfers, tf);
     42
     43        if (tf->fd != -1) {
     44                closesocket(tf->fd);
    4745                tf->fd = -1;
    4846        }
    4947
    50         if( tf->disco_timeout )
    51                 b_event_remove( tf->disco_timeout );
    52        
    53         g_free( tf->ini_jid );
    54         g_free( tf->tgt_jid );
    55         g_free( tf->iq_id );
    56         g_free( tf->sid );
    57         g_free( tf );
     48        if (tf->disco_timeout) {
     49                b_event_remove(tf->disco_timeout);
     50        }
     51
     52        g_free(tf->ini_jid);
     53        g_free(tf->tgt_jid);
     54        g_free(tf->iq_id);
     55        g_free(tf->sid);
     56        g_free(tf);
    5857}
    5958
    6059/* file_transfer canceled() callback */
    61 void jabber_si_canceled( file_transfer_t *ft, char *reason )
     60void jabber_si_canceled(file_transfer_t *ft, char *reason)
    6261{
    6362        struct jabber_transfer *tf = ft->data;
    6463        struct xt_node *reply, *iqnode;
    6564
    66         if( tf->accepted )
     65        if (tf->accepted) {
    6766                return;
    68        
    69         iqnode = jabber_make_packet( "iq", "error", tf->ini_jid, NULL );
    70         xt_add_attr( iqnode, "id", tf->iq_id );
    71         reply = jabber_make_error_packet( iqnode, "forbidden", "cancel", "403" );
    72         xt_free_node( iqnode );
    73        
    74         if( !jabber_write_packet( tf->ic, reply ) )
    75                 imcb_log( tf->ic, "WARNING: Error generating reply to file transfer request" );
    76         xt_free_node( reply );
    77 
    78 }
    79 
    80 int jabber_si_check_features( struct jabber_transfer *tf, GSList *features ) {
     67        }
     68
     69        iqnode = jabber_make_packet("iq", "error", tf->ini_jid, NULL);
     70        xt_add_attr(iqnode, "id", tf->iq_id);
     71        reply = jabber_make_error_packet(iqnode, "forbidden", "cancel", "403");
     72        xt_free_node(iqnode);
     73
     74        if (!jabber_write_packet(tf->ic, reply)) {
     75                imcb_log(tf->ic, "WARNING: Error generating reply to file transfer request");
     76        }
     77        xt_free_node(reply);
     78
     79}
     80
     81int jabber_si_check_features(struct jabber_transfer *tf, GSList *features)
     82{
    8183        int foundft = FALSE, foundbt = FALSE, foundsi = FALSE;
    8284
    83         while ( features )
    84         {
    85                 if( !strcmp( features->data, XMLNS_FILETRANSFER ) )
     85        while (features) {
     86                if (!strcmp(features->data, XMLNS_FILETRANSFER)) {
    8687                        foundft = TRUE;
    87                 if( !strcmp( features->data, XMLNS_BYTESTREAMS ) )
     88                }
     89                if (!strcmp(features->data, XMLNS_BYTESTREAMS)) {
    8890                        foundbt = TRUE;
    89                 if( !strcmp( features->data, XMLNS_SI ) )
     91                }
     92                if (!strcmp(features->data, XMLNS_SI)) {
    9093                        foundsi = TRUE;
     94                }
    9195
    9296                features = g_slist_next(features);
    9397        }
    9498
    95         if( !foundft )
    96                 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature file transfers" );
    97         else if( !foundbt )
    98                 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature byte streams (required)" );
    99         else if( !foundsi )
    100                 imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)" );
    101                
     99        if (!foundft) {
     100                imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature file transfers");
     101        } else if (!foundbt) {
     102                imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature byte streams (required)");
     103        } else if (!foundsi) {
     104                imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)");
     105        }
     106
    102107        return foundft && foundbt && foundsi;
    103108}
    104109
    105 void jabber_si_transfer_start( struct jabber_transfer *tf ) {
    106 
    107         if( !jabber_si_check_features( tf, tf->bud->features ) )
     110void jabber_si_transfer_start(struct jabber_transfer *tf)
     111{
     112
     113        if (!jabber_si_check_features(tf, tf->bud->features)) {
    108114                return;
    109                
     115        }
     116
    110117        /* send the request to our buddy */
    111         jabber_si_send_request( tf->ic, tf->bud->full_jid, tf );
     118        jabber_si_send_request(tf->ic, tf->bud->full_jid, tf);
    112119
    113120        /* and start the receive logic */
    114         imcb_file_recv_start( tf->ic, tf->ft );
    115 
    116 }
    117 
    118 gboolean jabber_si_waitfor_disco( gpointer data, gint fd, b_input_condition cond )
     121        imcb_file_recv_start(tf->ic, tf->ft);
     122
     123}
     124
     125gboolean jabber_si_waitfor_disco(gpointer data, gint fd, b_input_condition cond)
    119126{
    120127        struct jabber_transfer *tf = data;
     
    123130        tf->disco_timeout_fired++;
    124131
    125         if( tf->bud->features && jd->have_streamhosts==1 ) {
     132        if (tf->bud->features && jd->have_streamhosts == 1) {
    126133                tf->disco_timeout = 0;
    127                 jabber_si_transfer_start( tf );
     134                jabber_si_transfer_start(tf);
    128135                return FALSE;
    129136        }
    130137
    131138        /* 8 seconds should be enough for server and buddy to respond */
    132         if ( tf->disco_timeout_fired < 16 )
     139        if (tf->disco_timeout_fired < 16) {
    133140                return TRUE;
    134        
    135         if( !tf->bud->features && jd->have_streamhosts!=1 )
    136                 imcb_log( tf->ic, "Couldn't get buddy's features nor discover all services of the server" );
    137         else if( !tf->bud->features )
    138                 imcb_log( tf->ic, "Couldn't get buddy's features" );
    139         else
    140                 imcb_log( tf->ic, "Couldn't discover some of the server's services" );
    141        
     141        }
     142
     143        if (!tf->bud->features && jd->have_streamhosts != 1) {
     144                imcb_log(tf->ic, "Couldn't get buddy's features nor discover all services of the server");
     145        } else if (!tf->bud->features) {
     146                imcb_log(tf->ic, "Couldn't get buddy's features");
     147        } else {
     148                imcb_log(tf->ic, "Couldn't discover some of the server's services");
     149        }
     150
    142151        tf->disco_timeout = 0;
    143         jabber_si_transfer_start( tf );
     152        jabber_si_transfer_start(tf);
    144153        return FALSE;
    145154}
    146155
    147 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who )
     156void jabber_si_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *who)
    148157{
    149158        struct jabber_transfer *tf;
     
    152161        char *server = jd->server, *s;
    153162
    154         if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) )
    155                 bud = jabber_buddy_by_ext_jid( ic, who, 0 );
    156         else
    157                 bud = jabber_buddy_by_jid( ic, who, 0 );
    158 
    159         if( bud == NULL )
    160         {
    161                 imcb_file_canceled( ic, ft, "Couldn't find buddy (BUG?)" );
     163        if ((s = strchr(who, '=')) && jabber_chat_by_jid(ic, s + 1)) {
     164                bud = jabber_buddy_by_ext_jid(ic, who, 0);
     165        } else {
     166                bud = jabber_buddy_by_jid(ic, who, 0);
     167        }
     168
     169        if (bud == NULL) {
     170                imcb_file_canceled(ic, ft, "Couldn't find buddy (BUG?)");
    162171                return;
    163172        }
    164        
    165         imcb_log( ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who );
    166 
    167         tf = g_new0( struct jabber_transfer, 1 );
     173
     174        imcb_log(ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who);
     175
     176        tf = g_new0(struct jabber_transfer, 1);
    168177
    169178        tf->ic = ic;
     
    175184        ft->write = jabber_bs_send_write;
    176185
    177         jd->filetransfers = g_slist_prepend( jd->filetransfers, tf );
     186        jd->filetransfers = g_slist_prepend(jd->filetransfers, tf);
    178187
    179188        /* query buddy's features and server's streaming proxies if neccessary */
    180189
    181         if( !tf->bud->features )
    182                 jabber_iq_query_features( ic, bud->full_jid );
     190        if (!tf->bud->features) {
     191                jabber_iq_query_features(ic, bud->full_jid);
     192        }
    183193
    184194        /* If <auto> is not set don't check for proxies */
    185         if( ( jd->have_streamhosts!=1 ) && ( jd->streamhosts==NULL ) &&
    186             ( strstr( set_getstr( &ic->acc->set, "proxy" ), "<auto>" ) != NULL ) ) {
     195        if ((jd->have_streamhosts != 1) && (jd->streamhosts == NULL) &&
     196            (strstr(set_getstr(&ic->acc->set, "proxy"), "<auto>") != NULL)) {
    187197                jd->have_streamhosts = 0;
    188                 jabber_iq_query_server( ic, server, XMLNS_DISCO_ITEMS );
    189         } else if ( jd->streamhosts!=NULL )
     198                jabber_iq_query_server(ic, server, XMLNS_DISCO_ITEMS);
     199        } else if (jd->streamhosts != NULL) {
    190200                jd->have_streamhosts = 1;
    191 
    192         /* if we had to do a query, wait for the result.
     201        }
     202
     203        /* if we had to do a query, wait for the result.
    193204         * Otherwise fire away. */
    194         if( !tf->bud->features || jd->have_streamhosts!=1 )
    195                 tf->disco_timeout = b_timeout_add( 500, jabber_si_waitfor_disco, tf );
    196         else
    197                 jabber_si_transfer_start( tf );
     205        if (!tf->bud->features || jd->have_streamhosts != 1) {
     206                tf->disco_timeout = b_timeout_add(500, jabber_si_waitfor_disco, tf);
     207        } else {
     208                jabber_si_transfer_start(tf);
     209        }
    198210}
    199211
     
    205217 * Then we wait for imcb to call the accept or cancel callbacks.
    206218 */
    207 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode)
     219int jabber_si_handle_request(struct im_connection *ic, struct xt_node *node, struct xt_node *sinode)
    208220{
    209221        struct xt_node *c, *d, *reply;
     
    216228        struct jabber_data *jd = ic->proto_data;
    217229        file_transfer_t *ft;
    218        
     230
    219231        /* All this means we expect something like this: ( I think )
    220232         * <iq from=... to=... id=...>
    221          *      <si id=id xmlns=si profile=ft>
    222          *              <file xmlns=ft/>
    223          *              <feature xmlns=feature>
    224          *                      <x xmlns=xdata type=submit>
    225          *                              <field var=stream-method>
     233         *      <si id=id xmlns=si profile=ft>
     234         *              <file xmlns=ft/>
     235         *              <feature xmlns=feature>
     236         *                      <x xmlns=xdata type=submit>
     237         *                              <field var=stream-method>
    226238         *
    227239         */
    228         if( !( ini_jid          = xt_find_attr(   node, "from" )                        ) ||
    229             !( tgt_jid          = xt_find_attr(   node, "to" )                          ) ||
    230             !( iq_id            = xt_find_attr(   node, "id" )                          ) ||
    231             !( sid              = xt_find_attr( sinode, "id" )                          ) ||
    232             !( cmp              = xt_find_attr( sinode, "profile" )                     ) ||
    233             !( 0               == strcmp( cmp, XMLNS_FILETRANSFER )                     ) ||
    234             !( d                = xt_find_node( sinode->children, "file" )              ) ||
    235             !( cmp = xt_find_attr( d, "xmlns" )                                         ) ||
    236             !( 0               == strcmp( cmp, XMLNS_FILETRANSFER )                     ) ||
    237             !( name             = xt_find_attr( d, "name" )                             ) ||
    238             !( size_s           = xt_find_attr( d, "size" )                             ) ||
    239             !( 1               == sscanf( size_s, "%zd", &size )                        ) ||
    240             !( d                = xt_find_node( sinode->children, "feature" )           ) ||
    241             !( cmp              = xt_find_attr( d, "xmlns" )                            ) ||
    242             !( 0               == strcmp( cmp, XMLNS_FEATURE )                          ) ||
    243             !( d                = xt_find_node( d->children, "x" )                      ) ||
    244             !( cmp              = xt_find_attr( d, "xmlns" )                            ) ||
    245             !( 0               == strcmp( cmp, XMLNS_XDATA )                            ) ||
    246             !( cmp              = xt_find_attr( d, "type" )                             ) ||
    247             !( 0               == strcmp( cmp, "form" )                                 ) ||
    248             !( d                = xt_find_node( d->children, "field" )                  ) ||
    249             !( cmp              = xt_find_attr( d, "var" )                              ) ||
    250             !( 0               == strcmp( cmp, "stream-method" )                        ) )
    251         {
    252                 imcb_log( ic, "WARNING: Received incomplete Stream Initiation request" );
    253         }
    254         else
    255         {
     240        if (!(ini_jid          = xt_find_attr(node, "from")) ||
     241            !(tgt_jid          = xt_find_attr(node, "to")) ||
     242            !(iq_id            = xt_find_attr(node, "id")) ||
     243            !(sid              = xt_find_attr(sinode, "id")) ||
     244            !(cmp              = xt_find_attr(sinode, "profile")) ||
     245            !(0               == strcmp(cmp, XMLNS_FILETRANSFER)) ||
     246            !(d                = xt_find_node(sinode->children, "file")) ||
     247            !(cmp = xt_find_attr(d, "xmlns")) ||
     248            !(0               == strcmp(cmp, XMLNS_FILETRANSFER)) ||
     249            !(name             = xt_find_attr(d, "name")) ||
     250            !(size_s           = xt_find_attr(d, "size")) ||
     251            !(1               == sscanf(size_s, "%zd", &size)) ||
     252            !(d                = xt_find_node(sinode->children, "feature")) ||
     253            !(cmp              = xt_find_attr(d, "xmlns")) ||
     254            !(0               == strcmp(cmp, XMLNS_FEATURE)) ||
     255            !(d                = xt_find_node(d->children, "x")) ||
     256            !(cmp              = xt_find_attr(d, "xmlns")) ||
     257            !(0               == strcmp(cmp, XMLNS_XDATA)) ||
     258            !(cmp              = xt_find_attr(d, "type")) ||
     259            !(0               == strcmp(cmp, "form")) ||
     260            !(d                = xt_find_node(d->children, "field")) ||
     261            !(cmp              = xt_find_attr(d, "var")) ||
     262            !(0               == strcmp(cmp, "stream-method"))) {
     263                imcb_log(ic, "WARNING: Received incomplete Stream Initiation request");
     264        } else {
    256265                /* Check if we support one of the options */
    257266
    258267                c = d->children;
    259                 while( ( c = xt_find_node( c, "option" ) ) )
    260                         if( ( d = xt_find_node( c->children, "value" ) ) &&
    261                             ( d->text != NULL ) &&
    262                             ( strcmp( d->text, XMLNS_BYTESTREAMS ) == 0 ) )
    263                         {
     268                while ((c = xt_find_node(c, "option"))) {
     269                        if ((d = xt_find_node(c->children, "value")) &&
     270                            (d->text != NULL) &&
     271                            (strcmp(d->text, XMLNS_BYTESTREAMS) == 0)) {
    264272                                requestok = TRUE;
    265273                                break;
    266                         }
    267                         else
    268                         {
     274                        } else {
    269275                                c = c->next;
    270276                        }
    271 
    272                 if ( !requestok )
    273                         imcb_log( ic, "WARNING: Unsupported file transfer request from %s", ini_jid);
    274         }
    275        
    276         if( requestok )
    277         {
     277                }
     278
     279                if (!requestok) {
     280                        imcb_log(ic, "WARNING: Unsupported file transfer request from %s", ini_jid);
     281                }
     282        }
     283
     284        if (requestok) {
    278285                /* Figure out who the transfer should come frome... */
    279286
    280287                ext_jid = ini_jid;
    281                 if( ( s = strchr( ini_jid, '/' ) ) )
    282                 {
    283                         if( ( bud = jabber_buddy_by_jid( ic, ini_jid, GET_BUDDY_EXACT ) ) )
    284                         {
    285                                 bud->last_msg = time( NULL );
     288                if ((s = strchr(ini_jid, '/'))) {
     289                        if ((bud = jabber_buddy_by_jid(ic, ini_jid, GET_BUDDY_EXACT))) {
     290                                bud->last_msg = time(NULL);
    286291                                ext_jid = bud->ext_jid ? : bud->bare_jid;
     292                        } else {
     293                                *s = 0; /* We need to generate a bare JID now. */
    287294                        }
    288                         else
    289                                 *s = 0; /* We need to generate a bare JID now. */
    290                 }
    291 
    292                 if( !( ft = imcb_file_send_start( ic, ext_jid, name, size ) ) )
    293                 {
    294                         imcb_log( ic, "WARNING: Error handling transfer request from %s", ini_jid);
     295                }
     296
     297                if (!(ft = imcb_file_send_start(ic, ext_jid, name, size))) {
     298                        imcb_log(ic, "WARNING: Error handling transfer request from %s", ini_jid);
    295299                        requestok = FALSE;
    296300                }
    297301
    298                 if( s )
     302                if (s) {
    299303                        *s = '/';
    300         }
    301        
    302         if( !requestok )
    303         {
    304                 reply = jabber_make_error_packet( node, "item-not-found", "cancel", NULL );
    305                 if (!jabber_write_packet( ic, reply ))
    306                         imcb_log( ic, "WARNING: Error generating reply to file transfer request" );
    307                 xt_free_node( reply );
     304                }
     305        }
     306
     307        if (!requestok) {
     308                reply = jabber_make_error_packet(node, "item-not-found", "cancel", NULL);
     309                if (!jabber_write_packet(ic, reply)) {
     310                        imcb_log(ic, "WARNING: Error generating reply to file transfer request");
     311                }
     312                xt_free_node(reply);
    308313                return XT_HANDLED;
    309314        }
     
    311316        /* Request is fine. */
    312317
    313         tf = g_new0( struct jabber_transfer, 1 );
    314 
    315         tf->ini_jid = g_strdup( ini_jid );
    316         tf->tgt_jid = g_strdup( tgt_jid );
    317         tf->iq_id = g_strdup( iq_id );
    318         tf->sid = g_strdup( sid );
     318        tf = g_new0(struct jabber_transfer, 1);
     319
     320        tf->ini_jid = g_strdup(ini_jid);
     321        tf->tgt_jid = g_strdup(tgt_jid);
     322        tf->iq_id = g_strdup(iq_id);
     323        tf->sid = g_strdup(sid);
    319324        tf->ic = ic;
    320325        tf->ft = ft;
     
    325330        tf->ft->canceled = jabber_si_canceled;
    326331
    327         jd->filetransfers = g_slist_prepend( jd->filetransfers, tf );
     332        jd->filetransfers = g_slist_prepend(jd->filetransfers, tf);
    328333
    329334        return XT_HANDLED;
     
    336341 * (currently that can only be a SOCKS5 bytestream)
    337342 */
    338 void jabber_si_answer_request( file_transfer_t *ft ) {
     343void jabber_si_answer_request(file_transfer_t *ft)
     344{
    339345        struct jabber_transfer *tf = ft->data;
    340346        struct xt_node *node, *sinode, *reply;
    341347
    342348        /* generate response, start with the SI tag */
    343         sinode = xt_new_node( "si", NULL, NULL );
    344         xt_add_attr( sinode, "xmlns", XMLNS_SI );
    345         xt_add_attr( sinode, "profile", XMLNS_FILETRANSFER );
    346         xt_add_attr( sinode, "id", tf->sid );
     349        sinode = xt_new_node("si", NULL, NULL);
     350        xt_add_attr(sinode, "xmlns", XMLNS_SI);
     351        xt_add_attr(sinode, "profile", XMLNS_FILETRANSFER);
     352        xt_add_attr(sinode, "id", tf->sid);
    347353
    348354        /* now the file tag */
    349         node = xt_new_node( "file", NULL, NULL );
    350         xt_add_attr( node, "xmlns", XMLNS_FILETRANSFER );
    351 
    352         xt_add_child( sinode, node );
     355        node = xt_new_node("file", NULL, NULL);
     356        xt_add_attr(node, "xmlns", XMLNS_FILETRANSFER);
     357
     358        xt_add_child(sinode, node);
    353359
    354360        /* and finally the feature tag */
    355         node = xt_new_node( "field", NULL, NULL );
    356         xt_add_attr( node, "var", "stream-method" );
    357         xt_add_attr( node, "type", "list-single" );
     361        node = xt_new_node("field", NULL, NULL);
     362        xt_add_attr(node, "var", "stream-method");
     363        xt_add_attr(node, "type", "list-single");
    358364
    359365        /* Currently all we can do. One could also implement in-band (IBB) */
    360         xt_add_child( node, xt_new_node( "value", XMLNS_BYTESTREAMS, NULL ) );
    361 
    362         node = xt_new_node( "x", NULL, node );
    363         xt_add_attr( node, "xmlns", XMLNS_XDATA );
    364         xt_add_attr( node, "type", "submit" );
    365 
    366         node = xt_new_node( "feature", NULL, node );
    367         xt_add_attr( node, "xmlns", XMLNS_FEATURE );
    368 
    369         xt_add_child( sinode, node );
    370 
    371         reply = jabber_make_packet( "iq", "result", tf->ini_jid, sinode );
    372         xt_add_attr( reply, "id", tf->iq_id );
    373        
    374         if( !jabber_write_packet( tf->ic, reply ) )
    375                 imcb_log( tf->ic, "WARNING: Error generating reply to file transfer request" );
    376         else
     366        xt_add_child(node, xt_new_node("value", XMLNS_BYTESTREAMS, NULL));
     367
     368        node = xt_new_node("x", NULL, node);
     369        xt_add_attr(node, "xmlns", XMLNS_XDATA);
     370        xt_add_attr(node, "type", "submit");
     371
     372        node = xt_new_node("feature", NULL, node);
     373        xt_add_attr(node, "xmlns", XMLNS_FEATURE);
     374
     375        xt_add_child(sinode, node);
     376
     377        reply = jabber_make_packet("iq", "result", tf->ini_jid, sinode);
     378        xt_add_attr(reply, "id", tf->iq_id);
     379
     380        if (!jabber_write_packet(tf->ic, reply)) {
     381                imcb_log(tf->ic, "WARNING: Error generating reply to file transfer request");
     382        } else {
    377383                tf->accepted = TRUE;
    378         xt_free_node( reply );
    379 }
    380 
    381 static xt_status jabber_si_handle_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
     384        }
     385        xt_free_node(reply);
     386}
     387
     388static xt_status jabber_si_handle_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
    382389{
    383390        struct xt_node *c, *d;
    384391        char *ini_jid = NULL, *tgt_jid, *iq_id, *cmp;
    385392        GSList *tflist;
    386         struct jabber_transfer *tf=NULL;
     393        struct jabber_transfer *tf = NULL;
    387394        struct jabber_data *jd = ic->proto_data;
    388395
    389         if( !( tgt_jid = xt_find_attr( node, "from" ) ) ||
    390             !( ini_jid = xt_find_attr( node, "to" ) ) )
    391         {
    392                 imcb_log( ic, "Invalid SI response from=%s to=%s", tgt_jid, ini_jid );
     396        if (!(tgt_jid = xt_find_attr(node, "from")) ||
     397            !(ini_jid = xt_find_attr(node, "to"))) {
     398                imcb_log(ic, "Invalid SI response from=%s to=%s", tgt_jid, ini_jid);
    393399                return XT_HANDLED;
    394400        }
    395        
     401
    396402        /* All this means we expect something like this: ( I think )
    397403         * <iq from=... to=... id=...>
    398          *      <si xmlns=si>
    399          *      [       <file xmlns=ft/>    ] <-- not neccessary
    400          *              <feature xmlns=feature>
    401          *                      <x xmlns=xdata type=submit>
    402          *                              <field var=stream-method>
    403          *                                      <value>
     404         *      <si xmlns=si>
     405         *      [       <file xmlns=ft/>    ] <-- not neccessary
     406         *              <feature xmlns=feature>
     407         *                      <x xmlns=xdata type=submit>
     408         *                              <field var=stream-method>
     409         *                                      <value>
    404410         */
    405         if( !( tgt_jid = xt_find_attr( node, "from" ) ) ||
    406             !( ini_jid = xt_find_attr( node, "to" ) ) ||
    407             !( iq_id   = xt_find_attr( node, "id" ) ) ||
    408             !( c = xt_find_node( node->children, "si" ) ) ||
    409             !( cmp = xt_find_attr( c, "xmlns" ) ) ||
    410             !( strcmp( cmp, XMLNS_SI ) == 0 ) ||
    411             !( d = xt_find_node( c->children, "feature" ) ) ||
    412             !( cmp = xt_find_attr( d, "xmlns" ) ) ||
    413             !( strcmp( cmp, XMLNS_FEATURE ) == 0 ) ||
    414             !( d = xt_find_node( d->children, "x" ) ) ||
    415             !( cmp = xt_find_attr( d, "xmlns" ) ) ||
    416             !( strcmp( cmp, XMLNS_XDATA ) == 0 ) ||
    417             !( cmp = xt_find_attr( d, "type" ) ) ||
    418             !( strcmp( cmp, "submit" ) == 0 ) ||
    419             !( d = xt_find_node( d->children, "field" ) ) ||
    420             !( cmp = xt_find_attr( d, "var" ) ) ||
    421             !( strcmp( cmp, "stream-method" ) == 0 ) ||
    422             !( d = xt_find_node( d->children, "value" ) ) )
    423         {
    424                 imcb_log( ic, "WARNING: Received incomplete Stream Initiation response" );
     411        if (!(tgt_jid = xt_find_attr(node, "from")) ||
     412            !(ini_jid = xt_find_attr(node, "to")) ||
     413            !(iq_id   = xt_find_attr(node, "id")) ||
     414            !(c = xt_find_node(node->children, "si")) ||
     415            !(cmp = xt_find_attr(c, "xmlns")) ||
     416            !(strcmp(cmp, XMLNS_SI) == 0) ||
     417            !(d = xt_find_node(c->children, "feature")) ||
     418            !(cmp = xt_find_attr(d, "xmlns")) ||
     419            !(strcmp(cmp, XMLNS_FEATURE) == 0) ||
     420            !(d = xt_find_node(d->children, "x")) ||
     421            !(cmp = xt_find_attr(d, "xmlns")) ||
     422            !(strcmp(cmp, XMLNS_XDATA) == 0) ||
     423            !(cmp = xt_find_attr(d, "type")) ||
     424            !(strcmp(cmp, "submit") == 0) ||
     425            !(d = xt_find_node(d->children, "field")) ||
     426            !(cmp = xt_find_attr(d, "var")) ||
     427            !(strcmp(cmp, "stream-method") == 0) ||
     428            !(d = xt_find_node(d->children, "value"))) {
     429                imcb_log(ic, "WARNING: Received incomplete Stream Initiation response");
    425430                return XT_HANDLED;
    426431        }
    427432
    428         if( !( strcmp( d->text, XMLNS_BYTESTREAMS ) == 0 ) ) {
     433        if (!(strcmp(d->text, XMLNS_BYTESTREAMS) == 0)) {
    429434                /* since we should only have advertised what we can do and the peer should
    430435                 * only have chosen what we offered, this should never happen */
    431                 imcb_log( ic, "WARNING: Received invalid Stream Initiation response, method %s", d->text );
    432                        
     436                imcb_log(ic, "WARNING: Received invalid Stream Initiation response, method %s", d->text);
     437
    433438                return XT_HANDLED;
    434439        }
    435        
     440
    436441        /* Let's see if we can find out what this bytestream should be for... */
    437442
    438         for( tflist = jd->filetransfers ; tflist; tflist = g_slist_next(tflist) )
    439         {
     443        for (tflist = jd->filetransfers; tflist; tflist = g_slist_next(tflist)) {
    440444                struct jabber_transfer *tft = tflist->data;
    441                 if( ( strcmp( tft->iq_id, iq_id ) == 0 ) )
    442                 {
    443                         tf = tft;
     445                if ((strcmp(tft->iq_id, iq_id) == 0)) {
     446                        tf = tft;
    444447                        break;
    445448                }
    446449        }
    447450
    448         if (!tf)
    449         {
    450                 imcb_log( ic, "WARNING: Received bytestream request from %s that doesn't match an SI request", ini_jid );
     451        if (!tf) {
     452                imcb_log(ic, "WARNING: Received bytestream request from %s that doesn't match an SI request", ini_jid);
    451453                return XT_HANDLED;
    452454        }
    453455
    454         tf->ini_jid = g_strdup( ini_jid );
    455         tf->tgt_jid = g_strdup( tgt_jid );
    456 
    457         imcb_log( ic, "File %s: %s accepted the transfer!", tf->ft->file_name, tgt_jid );
    458 
    459         jabber_bs_send_start( tf );
     456        tf->ini_jid = g_strdup(ini_jid);
     457        tf->tgt_jid = g_strdup(tgt_jid);
     458
     459        imcb_log(ic, "File %s: %s accepted the transfer!", tf->ft->file_name, tgt_jid);
     460
     461        jabber_bs_send_start(tf);
    460462
    461463        return XT_HANDLED;
    462464}
    463465
    464 int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf )
     466int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf)
    465467{
    466468        struct xt_node *node, *sinode;
     
    468470
    469471        /* who knows how many bits the future holds :) */
    470         char filesizestr[ 1 + ( int ) ( 0.301029995663981198f * sizeof( size_t ) * 8 ) ];
    471 
    472         const char *methods[] = 
    473         {       
     472        char filesizestr[ 1 + ( int ) (0.301029995663981198f * sizeof(size_t) * 8) ];
     473
     474        const char *methods[] =
     475        {
    474476                XMLNS_BYTESTREAMS,
    475477                //XMLNS_IBB,
    476                 NULL 
     478                NULL
    477479        };
    478480        const char **m;
     
    480482
    481483        /* Maybe we should hash this? */
    482         tf->sid = g_strdup_printf( "BitlBeeJabberSID%d", tf->ft->local_id );
    483        
    484         if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) )
    485                 bud = jabber_buddy_by_ext_jid( ic, who, 0 );
    486         else
    487                 bud = jabber_buddy_by_jid( ic, who, 0 );
     484        tf->sid = g_strdup_printf("BitlBeeJabberSID%d", tf->ft->local_id);
     485
     486        if ((s = strchr(who, '=')) && jabber_chat_by_jid(ic, s + 1)) {
     487                bud = jabber_buddy_by_ext_jid(ic, who, 0);
     488        } else {
     489                bud = jabber_buddy_by_jid(ic, who, 0);
     490        }
    488491
    489492        /* start with the SI tag */
    490         sinode = xt_new_node( "si", NULL, NULL );
    491         xt_add_attr( sinode, "xmlns", XMLNS_SI );
    492         xt_add_attr( sinode, "profile", XMLNS_FILETRANSFER );
    493         xt_add_attr( sinode, "id", tf->sid );
    494 
    495 /*      if( mimetype ) 
    496                 xt_add_attr( node, "mime-type", mimetype ); */
     493        sinode = xt_new_node("si", NULL, NULL);
     494        xt_add_attr(sinode, "xmlns", XMLNS_SI);
     495        xt_add_attr(sinode, "profile", XMLNS_FILETRANSFER);
     496        xt_add_attr(sinode, "id", tf->sid);
     497
     498/*      if( mimetype )
     499                xt_add_attr( node, "mime-type", mimetype ); */
    497500
    498501        /* now the file tag */
    499502/*      if( desc )
    500                 node = xt_new_node( "desc", descr, NULL ); */
    501         node = xt_new_node( "range", NULL, NULL );
    502 
    503         sprintf( filesizestr, "%zd", tf->ft->file_size );
    504         node = xt_new_node( "file", NULL, node );
    505         xt_add_attr( node, "xmlns", XMLNS_FILETRANSFER );
    506         xt_add_attr( node, "name", tf->ft->file_name );
    507         xt_add_attr( node, "size", filesizestr );
     503                node = xt_new_node( "desc", descr, NULL ); */
     504        node = xt_new_node("range", NULL, NULL);
     505
     506        sprintf(filesizestr, "%zd", tf->ft->file_size);
     507        node = xt_new_node("file", NULL, node);
     508        xt_add_attr(node, "xmlns", XMLNS_FILETRANSFER);
     509        xt_add_attr(node, "name", tf->ft->file_name);
     510        xt_add_attr(node, "size", filesizestr);
    508511/*      if (hash)
    509                 xt_add_attr( node, "hash", hash );
    510         if (date)
    511                 xt_add_attr( node, "date", date ); */
    512 
    513         xt_add_child( sinode, node );
     512                xt_add_attr( node, "hash", hash );
     513        if (date)
     514                xt_add_attr( node, "date", date ); */
     515
     516        xt_add_child(sinode, node);
    514517
    515518        /* and finally the feature tag */
    516         node = xt_new_node( "field", NULL, NULL );
    517         xt_add_attr( node, "var", "stream-method" );
    518         xt_add_attr( node, "type", "list-single" );
    519 
    520         for ( m = methods ; *m ; m ++ )
    521                 xt_add_child( node, xt_new_node( "option", NULL, xt_new_node( "value", (char *)*m, NULL ) ) );
    522 
    523         node = xt_new_node( "x", NULL, node );
    524         xt_add_attr( node, "xmlns", XMLNS_XDATA );
    525         xt_add_attr( node, "type", "form" );
    526 
    527         node = xt_new_node( "feature", NULL, node );
    528         xt_add_attr( node, "xmlns", XMLNS_FEATURE );
    529 
    530         xt_add_child( sinode, node );
     519        node = xt_new_node("field", NULL, NULL);
     520        xt_add_attr(node, "var", "stream-method");
     521        xt_add_attr(node, "type", "list-single");
     522
     523        for (m = methods; *m; m++) {
     524                xt_add_child(node, xt_new_node("option", NULL, xt_new_node("value", (char *) *m, NULL)));
     525        }
     526
     527        node = xt_new_node("x", NULL, node);
     528        xt_add_attr(node, "xmlns", XMLNS_XDATA);
     529        xt_add_attr(node, "type", "form");
     530
     531        node = xt_new_node("feature", NULL, node);
     532        xt_add_attr(node, "xmlns", XMLNS_FEATURE);
     533
     534        xt_add_child(sinode, node);
    531535
    532536        /* and we are there... */
    533         node = jabber_make_packet( "iq", "set", bud ? bud->full_jid : who, sinode );
    534         jabber_cache_add( ic, node, jabber_si_handle_response );
    535         tf->iq_id = g_strdup( xt_find_attr( node, "id" ) );
    536        
    537         return jabber_write_packet( ic, node );
    538 }
     537        node = jabber_make_packet("iq", "set", bud ? bud->full_jid : who, sinode);
     538        jabber_cache_add(ic, node, jabber_si_handle_response);
     539        tf->iq_id = g_strdup(xt_find_attr(node, "id"));
     540
     541        return jabber_write_packet(ic, node);
     542}
Note: See TracChangeset for help on using the changeset viewer.