Changeset 5ebff60 for protocols


Ignore:
Timestamp:
2015-02-20T22:50:54Z (5 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
Files:
84 edited

Legend:

Unmodified
Added
Removed
  • protocols/account.c

    raf359b4 r5ebff60  
    1   /********************************************************************\
     1/********************************************************************\
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
     
    3232};
    3333
    34 static char *set_eval_nick_source( set_t *set, char *value );
    35 
    36 account_t *account_add( bee_t *bee, struct prpl *prpl, char *user, char *pass )
     34static char *set_eval_nick_source(set_t *set, char *value);
     35
     36account_t *account_add(bee_t *bee, struct prpl *prpl, char *user, char *pass)
    3737{
    3838        account_t *a;
    3939        set_t *s;
    40         char tag[strlen(prpl->name)+10];
    41        
    42         if( bee->accounts )
    43         {
    44                 for( a = bee->accounts; a->next; a = a->next );
    45                 a = a->next = g_new0( account_t, 1 );
    46         }
    47         else
    48         {
    49                 bee->accounts = a = g_new0 ( account_t, 1 );
    50         }
    51        
     40        char tag[strlen(prpl->name) + 10];
     41
     42        if (bee->accounts) {
     43                for (a = bee->accounts; a->next; a = a->next) {
     44                        ;
     45                }
     46                a = a->next = g_new0(account_t, 1);
     47        } else {
     48                bee->accounts = a = g_new0(account_t, 1);
     49        }
     50
    5251        a->prpl = prpl;
    53         a->user = g_strdup( user );
    54         a->pass = g_strdup( pass );
     52        a->user = g_strdup(user);
     53        a->pass = g_strdup(pass);
    5554        a->auto_connect = 1;
    5655        a->bee = bee;
    57        
    58         s = set_add( &a->set, "auto_connect", "true", set_eval_account, a );
     56
     57        s = set_add(&a->set, "auto_connect", "true", set_eval_account, a);
    5958        s->flags |= SET_NOSAVE;
    60        
    61         s = set_add( &a->set, "auto_reconnect", "true", set_eval_bool, a );
    62        
    63         s = set_add( &a->set, "nick_format", NULL, NULL, a );
     59
     60        s = set_add(&a->set, "auto_reconnect", "true", set_eval_bool, a);
     61
     62        s = set_add(&a->set, "nick_format", NULL, NULL, a);
    6463        s->flags |= SET_NULL_OK;
    65        
    66         s = set_add( &a->set, "nick_source", "handle", set_eval_nick_source, a );
     64
     65        s = set_add(&a->set, "nick_source", "handle", set_eval_nick_source, a);
    6766        s->flags |= SET_NOSAVE; /* Just for bw compatibility! */
    68        
    69         s = set_add( &a->set, "password", NULL, set_eval_account, a );
     67
     68        s = set_add(&a->set, "password", NULL, set_eval_account, a);
    7069        s->flags |= SET_NOSAVE | SET_NULL_OK | SET_PASSWORD;
    71        
    72         s = set_add( &a->set, "tag", NULL, set_eval_account, a );
     70
     71        s = set_add(&a->set, "tag", NULL, set_eval_account, a);
    7372        s->flags |= SET_NOSAVE;
    74        
    75         s = set_add( &a->set, "username", NULL, set_eval_account, a );
     73
     74        s = set_add(&a->set, "username", NULL, set_eval_account, a);
    7675        s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
    77         set_setstr( &a->set, "username", user );
    78        
     76        set_setstr(&a->set, "username", user);
     77
    7978        /* Hardcode some more clever tag guesses. */
    80         strcpy( tag, prpl->name );
    81         if( strcmp( prpl->name, "oscar" ) == 0 )
    82         {
    83                 if( g_ascii_isdigit( a->user[0] ) )
    84                         strcpy( tag, "icq" );
    85                 else
    86                         strcpy( tag, "aim" );
    87         }
    88         else if( strcmp( prpl->name, "jabber" ) == 0 )
    89         {
    90                 if( strstr( a->user, "@gmail.com" ) ||
    91                     strstr( a->user, "@googlemail.com" ) )
    92                         strcpy( tag, "gtalk" );
    93                 else if( strstr( a->user, "@chat.facebook.com" ) )
    94                         strcpy( tag, "fb" );
    95         }
    96        
    97         if( account_by_tag( bee, tag ) )
    98         {
    99                 char *numpos = tag + strlen( tag );
     79        strcpy(tag, prpl->name);
     80        if (strcmp(prpl->name, "oscar") == 0) {
     81                if (g_ascii_isdigit(a->user[0])) {
     82                        strcpy(tag, "icq");
     83                } else {
     84                        strcpy(tag, "aim");
     85                }
     86        } else if (strcmp(prpl->name, "jabber") == 0) {
     87                if (strstr(a->user, "@gmail.com") ||
     88                    strstr(a->user, "@googlemail.com")) {
     89                        strcpy(tag, "gtalk");
     90                } else if (strstr(a->user, "@chat.facebook.com")) {
     91                        strcpy(tag, "fb");
     92                }
     93        }
     94
     95        if (account_by_tag(bee, tag)) {
     96                char *numpos = tag + strlen(tag);
    10097                int i;
    10198
    102                 for( i = 2; i < 10000; i ++ )
    103                 {
    104                         sprintf( numpos, "%d", i );
    105                         if( !account_by_tag( bee, tag ) )
     99                for (i = 2; i < 10000; i++) {
     100                        sprintf(numpos, "%d", i);
     101                        if (!account_by_tag(bee, tag)) {
    106102                                break;
    107                 }
    108         }
    109         set_setstr( &a->set, "tag", tag );
    110        
    111         a->nicks = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free );
    112        
     103                        }
     104                }
     105        }
     106        set_setstr(&a->set, "tag", tag);
     107
     108        a->nicks = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
     109
    113110        /* This function adds some more settings (and might want to do more
    114111           things that have to be done now, although I can't think of anything. */
    115         if( prpl->init )
    116                 prpl->init( a );
    117        
    118         s = set_add( &a->set, "away", NULL, set_eval_account, a );
     112        if (prpl->init) {
     113                prpl->init(a);
     114        }
     115
     116        s = set_add(&a->set, "away", NULL, set_eval_account, a);
    119117        s->flags |= SET_NULL_OK;
    120        
    121         if( a->flags & ACC_FLAG_STATUS_MESSAGE )
    122         {
    123                 s = set_add( &a->set, "status", NULL, set_eval_account, a );
     118
     119        if (a->flags & ACC_FLAG_STATUS_MESSAGE) {
     120                s = set_add(&a->set, "status", NULL, set_eval_account, a);
    124121                s->flags |= SET_NULL_OK;
    125122        }
    126        
     123
    127124        return a;
    128125}
    129126
    130 char *set_eval_account( set_t *set, char *value )
     127char *set_eval_account(set_t *set, char *value)
    131128{
    132129        account_t *acc = set->data;
    133        
     130
    134131        /* Double-check: We refuse to edit on-line accounts. */
    135         if( set->flags & ACC_SET_OFFLINE_ONLY && acc->ic )
     132        if (set->flags & ACC_SET_OFFLINE_ONLY && acc->ic) {
    136133                return SET_INVALID;
    137        
    138         if( strcmp( set->key, "server" ) == 0 )
    139         {
    140                 g_free( acc->server );
    141                 if( value && *value )
    142                 {
    143                         acc->server = g_strdup( value );
     134        }
     135
     136        if (strcmp(set->key, "server") == 0) {
     137                g_free(acc->server);
     138                if (value && *value) {
     139                        acc->server = g_strdup(value);
    144140                        return value;
    145                 }
    146                 else
    147                 {
    148                         acc->server = g_strdup( set->def );
    149                         return g_strdup( set->def );
    150                 }
    151         }
    152         else if( strcmp( set->key, "username" ) == 0 )
    153         {
    154                 g_free( acc->user );
    155                 acc->user = g_strdup( value );
     141                } else {
     142                        acc->server = g_strdup(set->def);
     143                        return g_strdup(set->def);
     144                }
     145        } else if (strcmp(set->key, "username") == 0) {
     146                g_free(acc->user);
     147                acc->user = g_strdup(value);
    156148                return value;
    157         }
    158         else if( strcmp( set->key, "password" ) == 0 )
    159         {
     149        } else if (strcmp(set->key, "password") == 0) {
    160150                /* set -del allows /oper to be used to change the password or,
    161151                   iff oauth is enabled, reset the oauth credential magic.
    162152                */
    163                 if( !value ) {
    164                         if ( set_getbool( &(acc->set), "oauth" ) ) {
     153                if (!value) {
     154                        if (set_getbool(&(acc->set), "oauth")) {
    165155                                value = "";
    166156                        } else {
    167157                                value = PASSWORD_PENDING;
    168                                 ((irc_t *)acc->bee->ui_data)->status |= OPER_HACK_ACCOUNT_PASSWORD;
    169                                 irc_rootmsg((irc_t *)acc->bee->ui_data, "You may now use /OPER to set the password");
    170                         }
    171                 }
    172                
    173                 g_free( acc->pass );
    174                 acc->pass = g_strdup( value );
    175                 return NULL;    /* password shouldn't be visible in plaintext! */
    176         }
    177         else if( strcmp( set->key, "tag" ) == 0 )
    178         {
     158                                ((irc_t *) acc->bee->ui_data)->status |= OPER_HACK_ACCOUNT_PASSWORD;
     159                                irc_rootmsg((irc_t *) acc->bee->ui_data, "You may now use /OPER to set the password");
     160                        }
     161                }
     162
     163                g_free(acc->pass);
     164                acc->pass = g_strdup(value);
     165                return NULL;    /* password shouldn't be visible in plaintext! */
     166        } else if (strcmp(set->key, "tag") == 0) {
    179167                account_t *oa;
    180                
     168
    181169                /* Enforce uniqueness. */
    182                 if( ( oa = account_by_tag( acc->bee, value ) ) && oa != acc )
     170                if ((oa = account_by_tag(acc->bee, value)) && oa != acc) {
    183171                        return SET_INVALID;
    184                
    185                 g_free( acc->tag );
    186                 acc->tag = g_strdup( value );
     172                }
     173
     174                g_free(acc->tag);
     175                acc->tag = g_strdup(value);
    187176                return value;
    188         }
    189         else if( strcmp( set->key, "auto_connect" ) == 0 )
    190         {
    191                 if( !is_bool( value ) )
     177        } else if (strcmp(set->key, "auto_connect") == 0) {
     178                if (!is_bool(value)) {
    192179                        return SET_INVALID;
    193                
    194                 acc->auto_connect = bool2int( value );
     180                }
     181
     182                acc->auto_connect = bool2int(value);
    195183                return value;
    196         }
    197         else if( strcmp( set->key, "away" ) == 0 ||
    198                  strcmp( set->key, "status" ) == 0 )
    199         {
    200                 if( acc->ic && acc->ic->flags & OPT_LOGGED_IN )
    201                 {
     184        } else if (strcmp(set->key, "away") == 0 ||
     185                   strcmp(set->key, "status") == 0) {
     186                if (acc->ic && acc->ic->flags & OPT_LOGGED_IN) {
    202187                        /* If we're currently on-line, set the var now already
    203188                           (bit of a hack) and send an update. */
    204                         g_free( set->value );
    205                         set->value = g_strdup( value );
    206                        
    207                         imc_away_send_update( acc->ic );
    208                 }
    209                
     189                        g_free(set->value);
     190                        set->value = g_strdup(value);
     191
     192                        imc_away_send_update(acc->ic);
     193                }
     194
    210195                return value;
    211196        }
    212        
     197
    213198        return SET_INVALID;
    214199}
    215200
    216201/* For bw compatibility, have this write-only setting. */
    217 static char *set_eval_nick_source( set_t *set, char *value )
     202static char *set_eval_nick_source(set_t *set, char *value)
    218203{
    219204        account_t *a = set->data;
    220        
    221         if( strcmp( value, "full_name" ) == 0 )
    222                 set_setstr( &a->set, "nick_format", "%full_name" );
    223         else if( strcmp( value, "first_name" ) == 0 )
    224                 set_setstr( &a->set, "nick_format", "%first_name" );
    225         else
    226                 set_setstr( &a->set, "nick_format", "%-@nick" );
    227        
     205
     206        if (strcmp(value, "full_name") == 0) {
     207                set_setstr(&a->set, "nick_format", "%full_name");
     208        } else if (strcmp(value, "first_name") == 0) {
     209                set_setstr(&a->set, "nick_format", "%first_name");
     210        } else {
     211                set_setstr(&a->set, "nick_format", "%-@nick");
     212        }
     213
    228214        return value;
    229215}
    230216
    231 account_t *account_get( bee_t *bee, const char *id )
     217account_t *account_get(bee_t *bee, const char *id)
    232218{
    233219        account_t *a, *ret = NULL;
    234220        char *handle, *s;
    235221        int nr;
    236        
     222
    237223        /* Tags get priority above anything else. */
    238         if( ( a = account_by_tag( bee, id ) ) )
     224        if ((a = account_by_tag(bee, id))) {
    239225                return a;
    240        
     226        }
     227
    241228        /* This checks if the id string ends with (...) */
    242         if( ( handle = strchr( id, '(' ) ) && ( s = strchr( handle, ')' ) ) && s[1] == 0 )
    243         {
     229        if ((handle = strchr(id, '(')) && (s = strchr(handle, ')')) && s[1] == 0) {
    244230                struct prpl *proto;
    245                
     231
    246232                *s = *handle = 0;
    247                 handle ++;
    248                
    249                 if( ( proto = find_protocol( id ) ) )
    250                 {
    251                         for( a = bee->accounts; a; a = a->next )
    252                                 if( a->prpl == proto &&
    253                                     a->prpl->handle_cmp( handle, a->user ) == 0 )
     233                handle++;
     234
     235                if ((proto = find_protocol(id))) {
     236                        for (a = bee->accounts; a; a = a->next) {
     237                                if (a->prpl == proto &&
     238                                    a->prpl->handle_cmp(handle, a->user) == 0) {
    254239                                        ret = a;
    255                 }
    256                
     240                                }
     241                        }
     242                }
     243
    257244                /* Restore the string. */
    258                 handle --;
     245                handle--;
    259246                *handle = '(';
    260247                *s = ')';
    261                
    262                 if( ret )
     248
     249                if (ret) {
    263250                        return ret;
    264         }
    265        
    266         if( sscanf( id, "%d", &nr ) == 1 && nr < 1000 )
    267         {
    268                 for( a = bee->accounts; a; a = a->next )
    269                         if( ( nr-- ) == 0 )
    270                                 return( a );
    271                
    272                 return( NULL );
    273         }
    274        
    275         for( a = bee->accounts; a; a = a->next )
    276         {
    277                 if( g_strcasecmp( id, a->prpl->name ) == 0 )
    278                 {
    279                         if( !ret )
     251                }
     252        }
     253
     254        if (sscanf(id, "%d", &nr) == 1 && nr < 1000) {
     255                for (a = bee->accounts; a; a = a->next) {
     256                        if ((nr--) == 0) {
     257                                return(a);
     258                        }
     259                }
     260
     261                return(NULL);
     262        }
     263
     264        for (a = bee->accounts; a; a = a->next) {
     265                if (g_strcasecmp(id, a->prpl->name) == 0) {
     266                        if (!ret) {
    280267                                ret = a;
    281                         else
    282                                 return( NULL ); /* We don't want to match more than one... */
    283                 }
    284                 else if( strstr( a->user, id ) )
    285                 {
    286                         if( !ret )
     268                        } else {
     269                                return(NULL);   /* We don't want to match more than one... */
     270                        }
     271                } else if (strstr(a->user, id)) {
     272                        if (!ret) {
    287273                                ret = a;
    288                         else
    289                                 return( NULL );
    290                 }
    291         }
    292        
    293         return( ret );
    294 }
    295 
    296 account_t *account_by_tag( bee_t *bee, const char *tag )
     274                        } else {
     275                                return(NULL);
     276                        }
     277                }
     278        }
     279
     280        return(ret);
     281}
     282
     283account_t *account_by_tag(bee_t *bee, const char *tag)
    297284{
    298285        account_t *a;
    299        
    300         for( a = bee->accounts; a; a = a->next )
    301                 if( a->tag && g_strcasecmp( tag, a->tag ) == 0 )
     286
     287        for (a = bee->accounts; a; a = a->next) {
     288                if (a->tag && g_strcasecmp(tag, a->tag) == 0) {
    302289                        return a;
    303        
     290                }
     291        }
     292
    304293        return NULL;
    305294}
    306295
    307 void account_del( bee_t *bee, account_t *acc )
     296void account_del(bee_t *bee, account_t *acc)
    308297{
    309298        account_t *a, *l = NULL;
    310        
    311         if( acc->ic )
     299
     300        if (acc->ic) {
    312301                /* Caller should have checked, accounts still in use can't be deleted. */
    313302                return;
    314        
    315         for( a = bee->accounts; a; a = (l=a)->next )
    316                 if( a == acc )
    317                 {
    318                         if( l )
     303        }
     304
     305        for (a = bee->accounts; a; a = (l = a)->next) {
     306                if (a == acc) {
     307                        if (l) {
    319308                                l->next = a->next;
    320                         else
     309                        } else {
    321310                                bee->accounts = a->next;
    322                        
     311                        }
     312
    323313                        /** FIXME
    324314                        for( c = bee->chatrooms; c; c = nc )
    325315                        {
    326                                 nc = c->next;
    327                                 if( acc == c->acc )
    328                                         chat_del( bee, c );
     316                                nc = c->next;
     317                                if( acc == c->acc )
     318                                        chat_del( bee, c );
    329319                        }
    330320                        */
    331                        
    332                         while( a->set )
    333                                 set_del( &a->set, a->set->key );
    334                        
    335                         g_hash_table_destroy( a->nicks );
    336                        
    337                         g_free( a->tag );
    338                         g_free( a->user );
    339                         g_free( a->pass );
    340                         g_free( a->server );
    341                         if( a->reconnect )      /* This prevents any reconnect still queued to happen */
    342                                 cancel_auto_reconnect( a );
    343                         g_free( a );
    344                        
     321
     322                        while (a->set) {
     323                                set_del(&a->set, a->set->key);
     324                        }
     325
     326                        g_hash_table_destroy(a->nicks);
     327
     328                        g_free(a->tag);
     329                        g_free(a->user);
     330                        g_free(a->pass);
     331                        g_free(a->server);
     332                        if (a->reconnect) {     /* This prevents any reconnect still queued to happen */
     333                                cancel_auto_reconnect(a);
     334                        }
     335                        g_free(a);
     336
    345337                        break;
    346338                }
    347 }
    348 
    349 static gboolean account_on_timeout( gpointer d, gint fd, b_input_condition cond );
    350 
    351 void account_on( bee_t *bee, account_t *a )
    352 {
    353         if( a->ic )
    354         {
     339        }
     340}
     341
     342static gboolean account_on_timeout(gpointer d, gint fd, b_input_condition cond);
     343
     344void account_on(bee_t *bee, account_t *a)
     345{
     346        if (a->ic) {
    355347                /* Trying to enable an already-enabled account */
    356348                return;
    357349        }
    358        
    359         cancel_auto_reconnect( a );
    360        
     350
     351        cancel_auto_reconnect(a);
     352
    361353        a->reconnect = 0;
    362         a->prpl->login( a );
    363        
    364         if( a->ic && !( a->ic->flags & ( OPT_SLOW_LOGIN | OPT_LOGGED_IN ) ) )
    365                 a->ic->keepalive = b_timeout_add( 120000, account_on_timeout, a->ic );
    366 }
    367 
    368 void account_off( bee_t *bee, account_t *a )
    369 {
    370         imc_logout( a->ic, FALSE );
     354        a->prpl->login(a);
     355
     356        if (a->ic && !(a->ic->flags & (OPT_SLOW_LOGIN | OPT_LOGGED_IN))) {
     357                a->ic->keepalive = b_timeout_add(120000, account_on_timeout, a->ic);
     358        }
     359}
     360
     361void account_off(bee_t *bee, account_t *a)
     362{
     363        imc_logout(a->ic, FALSE);
    371364        a->ic = NULL;
    372         if( a->reconnect )
    373         {
     365        if (a->reconnect) {
    374366                /* Shouldn't happen */
    375                 cancel_auto_reconnect( a );
    376         }
    377 }
    378 
    379 static gboolean account_on_timeout( gpointer d, gint fd, b_input_condition cond )
     367                cancel_auto_reconnect(a);
     368        }
     369}
     370
     371static gboolean account_on_timeout(gpointer d, gint fd, b_input_condition cond)
    380372{
    381373        struct im_connection *ic = d;
    382        
    383         if( !( ic->flags & ( OPT_SLOW_LOGIN | OPT_LOGGED_IN ) ) )
    384         {
    385                 imcb_error( ic, "Connection timeout" );
    386                 imc_logout( ic, TRUE );
    387         }
    388        
     374
     375        if (!(ic->flags & (OPT_SLOW_LOGIN | OPT_LOGGED_IN))) {
     376                imcb_error(ic, "Connection timeout");
     377                imc_logout(ic, TRUE);
     378        }
     379
    389380        return FALSE;
    390381}
    391382
    392 struct account_reconnect_delay
    393 {
     383struct account_reconnect_delay {
    394384        int start;
    395385        char op;
     
    398388};
    399389
    400 int account_reconnect_delay_parse( char *value, struct account_reconnect_delay *p )
    401 {
    402         memset( p, 0, sizeof( *p ) );
     390int account_reconnect_delay_parse(char *value, struct account_reconnect_delay *p)
     391{
     392        memset(p, 0, sizeof(*p));
    403393        /* A whole day seems like a sane "maximum maximum". */
    404394        p->max = 86400;
    405        
     395
    406396        /* Format: /[0-9]+([*+][0-9]+(<[0-9+])?)?/ */
    407         while( *value && g_ascii_isdigit( *value ) )
     397        while (*value && g_ascii_isdigit(*value)) {
    408398                p->start = p->start * 10 + *value++ - '0';
    409        
     399        }
     400
    410401        /* Sure, call me evil for implementing my own fscanf here, but it's
    411402           dead simple and I immediately know where to continue parsing. */
    412        
    413         if( *value == 0 )
     403
     404        if (*value == 0) {
    414405                /* If the string ends now, the delay is constant. */
    415406                return 1;
    416         else if( *value != '+' && *value != '*' )
     407        } else if (*value != '+' && *value != '*') {
    417408                /* Otherwise allow either a + or a * */
    418409                return 0;
    419        
     410        }
     411
    420412        p->op = *value++;
    421        
     413
    422414        /* + or * the delay by this number every time. */
    423         while( *value && g_ascii_isdigit( *value ) )
     415        while (*value && g_ascii_isdigit(*value)) {
    424416                p->step = p->step * 10 + *value++ - '0';
    425        
    426         if( *value == 0 )
     417        }
     418
     419        if (*value == 0) {
    427420                /* Use the default maximum (one day). */
    428421                return 1;
    429         else if( *value != '<' )
     422        } else if (*value != '<') {
    430423                return 0;
    431        
     424        }
     425
    432426        p->max = 0;
    433         value ++;
    434         while( *value && g_ascii_isdigit( *value ) )
     427        value++;
     428        while (*value && g_ascii_isdigit(*value)) {
    435429                p->max = p->max * 10 + *value++ - '0';
    436        
     430        }
     431
    437432        return p->max > 0;
    438433}
    439434
    440 char *set_eval_account_reconnect_delay( set_t *set, char *value )
     435char *set_eval_account_reconnect_delay(set_t *set, char *value)
    441436{
    442437        struct account_reconnect_delay p;
    443        
    444         return account_reconnect_delay_parse( value, &p ) ? value : SET_INVALID;
    445 }
    446 
    447 int account_reconnect_delay( account_t *a )
    448 {
    449         char *setting = set_getstr( &a->bee->set, "auto_reconnect_delay" );
     438
     439        return account_reconnect_delay_parse(value, &p) ? value : SET_INVALID;
     440}
     441
     442int account_reconnect_delay(account_t *a)
     443{
     444        char *setting = set_getstr(&a->bee->set, "auto_reconnect_delay");
    450445        struct account_reconnect_delay p;
    451        
    452         if( account_reconnect_delay_parse( setting, &p ) )
    453         {
    454                 if( a->auto_reconnect_delay == 0 )
     446
     447        if (account_reconnect_delay_parse(setting, &p)) {
     448                if (a->auto_reconnect_delay == 0) {
    455449                        a->auto_reconnect_delay = p.start;
    456                 else if( p.op == '+' )
     450                } else if (p.op == '+') {
    457451                        a->auto_reconnect_delay += p.step;
    458                 else if( p.op == '*' )
     452                } else if (p.op == '*') {
    459453                        a->auto_reconnect_delay *= p.step;
    460                
    461                 if( a->auto_reconnect_delay > p.max )
     454                }
     455
     456                if (a->auto_reconnect_delay > p.max) {
    462457                        a->auto_reconnect_delay = p.max;
    463         }
    464         else
    465         {
     458                }
     459        } else {
    466460                a->auto_reconnect_delay = 0;
    467461        }
    468        
     462
    469463        return a->auto_reconnect_delay;
    470464}
    471465
    472 int protocol_account_islocal( const char* protocol )
     466int protocol_account_islocal(const char* protocol)
    473467{
    474468        const char** p = account_protocols_local;
     469
    475470        do {
    476                 if( strcmp( *p, protocol ) == 0 )
     471                if (strcmp(*p, protocol) == 0) {
    477472                        return 1;
    478         } while( *( ++p ) );
     473                }
     474        } while (*(++p));
    479475        return 0;
    480476}
  • protocols/account.h

    raf359b4 r5ebff60  
    1   /********************************************************************\
     1/********************************************************************\
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
     
    2727#define _ACCOUNT_H
    2828
    29 typedef struct account
    30 {
     29typedef struct account {
    3130        struct prpl *prpl;
    3231        char *user;
     
    3433        char *server;
    3534        char *tag;
    36        
     35
    3736        int auto_connect;
    3837        int auto_reconnect_delay;
    3938        int reconnect;
    4039        int flags;
    41        
     40
    4241        set_t *set;
    4342        GHashTable *nicks;
    44        
     43
    4544        struct bee *bee;
    4645        struct im_connection *ic;
     
    4847} account_t;
    4948
    50 account_t *account_add( bee_t *bee, struct prpl *prpl, char *user, char *pass );
    51 account_t *account_get( bee_t *bee, const char *id );
    52 account_t *account_by_tag( bee_t *bee, const char *tag );
    53 void account_del( bee_t *bee, account_t *acc );
    54 void account_on( bee_t *bee, account_t *a );
    55 void account_off( bee_t *bee, account_t *a );
     49account_t *account_add(bee_t *bee, struct prpl *prpl, char *user, char *pass);
     50account_t *account_get(bee_t *bee, const char *id);
     51account_t *account_by_tag(bee_t *bee, const char *tag);
     52void account_del(bee_t *bee, account_t *acc);
     53void account_on(bee_t *bee, account_t *a);
     54void account_off(bee_t *bee, account_t *a);
    5655
    57 char *set_eval_account( set_t *set, char *value );
    58 char *set_eval_account_reconnect_delay( set_t *set, char *value );
    59 int account_reconnect_delay( account_t *a );
     56char *set_eval_account(set_t *set, char *value);
     57char *set_eval_account_reconnect_delay(set_t *set, char *value);
     58int account_reconnect_delay(account_t *a);
    6059
    61 int protocol_account_islocal( const char* protocol );
     60int protocol_account_islocal(const char* protocol);
    6261
    63 typedef enum
    64 {
     62typedef enum {
    6563        ACC_SET_OFFLINE_ONLY = 0x02,    /* Allow changes only if the acct is offline. */
    6664        ACC_SET_ONLINE_ONLY = 0x04,     /* Allow changes only if the acct is online. */
    6765} account_set_flag_t;
    6866
    69 typedef enum
    70 {
     67typedef enum {
    7168        ACC_FLAG_AWAY_MESSAGE = 0x01,   /* Supports away messages instead of just states. */
    7269        ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */
  • protocols/bee.c

    raf359b4 r5ebff60  
    1   /********************************************************************\
     1/********************************************************************\
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
     
    2727#include "bitlbee.h"
    2828
    29 static char *set_eval_away_status( set_t *set, char *value );
     29static char *set_eval_away_status(set_t *set, char *value);
    3030
    3131bee_t *bee_new()
    3232{
    33         bee_t *b = g_new0( bee_t, 1 );
     33        bee_t *b = g_new0(bee_t, 1);
    3434        set_t *s;
    35        
    36         s = set_add( &b->set, "auto_connect", "true", set_eval_bool, b );
    37         s = set_add( &b->set, "auto_reconnect", "true", set_eval_bool, b );
    38         s = set_add( &b->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, b );
    39         s = set_add( &b->set, "away", NULL, set_eval_away_status, b );
     35
     36        s = set_add(&b->set, "auto_connect", "true", set_eval_bool, b);
     37        s = set_add(&b->set, "auto_reconnect", "true", set_eval_bool, b);
     38        s = set_add(&b->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, b);
     39        s = set_add(&b->set, "away", NULL, set_eval_away_status, b);
    4040        s->flags |= SET_NULL_OK | SET_HIDDEN;
    41         s = set_add( &b->set, "debug", "false", set_eval_bool, b );
    42         s = set_add( &b->set, "mobile_is_away", "false", set_eval_bool, b );
    43         s = set_add( &b->set, "save_on_quit", "true", set_eval_bool, b );
    44         s = set_add( &b->set, "status", NULL, set_eval_away_status, b );
     41        s = set_add(&b->set, "debug", "false", set_eval_bool, b);
     42        s = set_add(&b->set, "mobile_is_away", "false", set_eval_bool, b);
     43        s = set_add(&b->set, "save_on_quit", "true", set_eval_bool, b);
     44        s = set_add(&b->set, "status", NULL, set_eval_away_status, b);
    4545        s->flags |= SET_NULL_OK;
    46         s = set_add( &b->set, "strip_html", "true", NULL, b );
    47        
    48         b->user = g_malloc( 1 );
    49        
     46        s = set_add(&b->set, "strip_html", "true", NULL, b);
     47
     48        b->user = g_malloc(1);
     49
    5050        return b;
    5151}
    5252
    53 void bee_free( bee_t *b )
     53void bee_free(bee_t *b)
    5454{
    55         while( b->accounts )
    56         {
    57                 if( b->accounts->ic )
    58                         imc_logout( b->accounts->ic, FALSE );
    59                 else if( b->accounts->reconnect )
    60                         cancel_auto_reconnect( b->accounts );
    61                
    62                 if( b->accounts->ic == NULL )
    63                         account_del( b, b->accounts );
    64                 else
     55        while (b->accounts) {
     56                if (b->accounts->ic) {
     57                        imc_logout(b->accounts->ic, FALSE);
     58                } else if (b->accounts->reconnect) {
     59                        cancel_auto_reconnect(b->accounts);
     60                }
     61
     62                if (b->accounts->ic == NULL) {
     63                        account_del(b, b->accounts);
     64                } else {
    6565                        /* Nasty hack, but account_del() doesn't work in this
    6666                           case and we don't want infinite loops, do we? ;-) */
    6767                        b->accounts = b->accounts->next;
     68                }
    6869        }
    69        
    70         while( b->set )
    71                 set_del( &b->set, b->set->key );
    72        
    73         bee_group_free( b );
    74        
    75         g_free( b->user );
    76         g_free( b );
     70
     71        while (b->set) {
     72                set_del(&b->set, b->set->key);
     73        }
     74
     75        bee_group_free(b);
     76
     77        g_free(b->user);
     78        g_free(b);
    7779}
    7880
    79 static char *set_eval_away_status( set_t *set, char *value )
     81static char *set_eval_away_status(set_t *set, char *value)
    8082{
    8183        bee_t *bee = set->data;
    8284        account_t *a;
    83        
    84         g_free( set->value );
    85         set->value = g_strdup( value );
    86        
    87         for( a = bee->accounts; a; a = a->next )
    88         {
     85
     86        g_free(set->value);
     87        set->value = g_strdup(value);
     88
     89        for (a = bee->accounts; a; a = a->next) {
    8990                struct im_connection *ic = a->ic;
    90                
    91                 if( ic && ic->flags & OPT_LOGGED_IN )
    92                         imc_away_send_update( ic );
     91
     92                if (ic && ic->flags & OPT_LOGGED_IN) {
     93                        imc_away_send_update(ic);
     94                }
    9395        }
    94        
     96
    9597        return value;
    9698}
  • protocols/bee.h

    raf359b4 r5ebff60  
    1   /********************************************************************\
     1/********************************************************************\
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
     
    3030struct groupchat;
    3131
    32 typedef struct bee
    33 {
     32typedef struct bee {
    3433        /* Settings. See set.h for how these work. The UI can add its
    3534           own settings here. */
    3635        struct set *set;
    37        
     36
    3837        GSList *users;  /* struct bee_user */
    3938        GSList *groups; /* struct bee_group */
    4039        struct account *accounts; /* TODO(wilmer): Use GSList here too? */
    41        
     40
    4241        /* Symbolic, to refer to the local user (who has no real bee_user
    4342           object). Not to be used by anything except so far imcb_chat_add/
    4443           remove_buddy(). */
    4544        struct bee_user *user;
    46        
     45
    4746        /* Fill in the callbacks for events you care about. */
    4847        const struct bee_ui_funcs *ui;
    49        
     48
    5049        /* And this one will be passed to every callback for any state the
    5150           UI may want to keep. */
     
    5453
    5554bee_t *bee_new();
    56 void bee_free( bee_t *b );
     55void bee_free(bee_t *b);
    5756
    5857/* TODO(wilmer): Kill at least the OPT_ flags that have an equivalent here. */
    59 typedef enum
    60 {
     58typedef enum {
    6159        BEE_USER_ONLINE = 1,    /* Compatibility with old OPT_LOGGED_IN flag */
    6260        BEE_USER_AWAY = 4,      /* Compatibility with old OPT_AWAY flag */
     
    6664} bee_user_flags_t;
    6765
    68 typedef struct bee_user
    69 {
     66typedef struct bee_user {
    7067        struct im_connection *ic;
    7168        char *handle;
     
    7774        char *status;     /* NULL means available, anything else is an away state. */
    7875        char *status_msg; /* Status and/or away message. */
    79        
     76
    8077        /* Set using imcb_buddy_times(). */
    8178        time_t login_time, idle_time;
    82        
     79
    8380        bee_t *bee;
    8481        void *ui_data;
     
    8885/* This one's mostly used so save space and make it easier (cheaper) to
    8986   compare groups of contacts, etc. */
    90 typedef struct bee_group
    91 {
     87typedef struct bee_group {
    9288        char *key;  /* Lower case version of the name. */
    9389        char *name;
    9490} bee_group_t;
    9591
    96 typedef struct bee_ui_funcs
    97 {
    98         void (*imc_connected)( struct im_connection *ic );
    99         void (*imc_disconnected)( struct im_connection *ic );
    100        
    101         gboolean (*user_new)( bee_t *bee, struct bee_user *bu );
    102         gboolean (*user_free)( bee_t *bee, struct bee_user *bu );
     92typedef struct bee_ui_funcs {
     93        void (*imc_connected)(struct im_connection *ic);
     94        void (*imc_disconnected)(struct im_connection *ic);
     95
     96        gboolean (*user_new)(bee_t *bee, struct bee_user *bu);
     97        gboolean (*user_free)(bee_t *bee, struct bee_user *bu);
    10398        /* Set the fullname first, then call this one to notify the UI. */
    104         gboolean (*user_fullname)( bee_t *bee, bee_user_t *bu );
    105         gboolean (*user_nick_hint)( bee_t *bee, bee_user_t *bu, const char *hint );
     99        gboolean (*user_fullname)(bee_t *bee, bee_user_t *bu);
     100        gboolean (*user_nick_hint)(bee_t *bee, bee_user_t *bu, const char *hint);
    106101        /* Notify the UI when an existing user is moved between groups. */
    107         gboolean (*user_group)( bee_t *bee, bee_user_t *bu );
     102        gboolean (*user_group)(bee_t *bee, bee_user_t *bu);
    108103        /* State info is already updated, old is provided in case the UI needs a diff. */
    109         gboolean (*user_status)( bee_t *bee, struct bee_user *bu, struct bee_user *old );
     104        gboolean (*user_status)(bee_t *bee, struct bee_user *bu, struct bee_user *old);
    110105        /* On every incoming message. sent_at = 0 means unknown. */
    111         gboolean (*user_msg)( bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at );
     106        gboolean (*user_msg)(bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at);
    112107        /* Flags currently defined (OPT_TYPING/THINKING) in nogaim.h. */
    113         gboolean (*user_typing)( bee_t *bee, bee_user_t *bu, guint32 flags );
     108        gboolean (*user_typing)(bee_t *bee, bee_user_t *bu, guint32 flags);
    114109        /* CTCP-like stuff (buddy action) response */
    115         gboolean (*user_action_response)( bee_t *bee, bee_user_t *bu, const char *action, char * const args[], void *data );
    116        
     110        gboolean (*user_action_response)(bee_t *bee, bee_user_t *bu, const char *action, char * const args[],
     111                                         void *data);
     112
    117113        /* Called at creation time. Don't show to the user until s/he is
    118114           added using chat_add_user().  UI state can be stored via c->data. */
    119         gboolean (*chat_new)( bee_t *bee, struct groupchat *c );
    120         gboolean (*chat_free)( bee_t *bee, struct groupchat *c );
     115        gboolean (*chat_new)(bee_t *bee, struct groupchat *c);
     116        gboolean (*chat_free)(bee_t *bee, struct groupchat *c);
    121117        /* System messages of any kind. */
    122         gboolean (*chat_log)( bee_t *bee, struct groupchat *c, const char *text );
    123         gboolean (*chat_msg)( bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at );
    124         gboolean (*chat_add_user)( bee_t *bee, struct groupchat *c, bee_user_t *bu );
    125         gboolean (*chat_remove_user)( bee_t *bee, struct groupchat *c, bee_user_t *bu );
    126         gboolean (*chat_topic)( bee_t *bee, struct groupchat *c, const char *new_topic, bee_user_t *bu );
    127         gboolean (*chat_name_hint)( bee_t *bee, struct groupchat *c, const char *name );
    128         gboolean (*chat_invite)( bee_t *bee, bee_user_t *bu, const char *name, const char *msg );
    129        
    130         struct file_transfer* (*ft_in_start)( bee_t *bee, bee_user_t *bu, const char *file_name, size_t file_size );
    131         gboolean (*ft_out_start)( struct im_connection *ic, struct file_transfer *ft );
    132         void (*ft_close)( struct im_connection *ic, struct file_transfer *ft );
    133         void (*ft_finished)( struct im_connection *ic, struct file_transfer *ft );
     118        gboolean (*chat_log)(bee_t *bee, struct groupchat *c, const char *text);
     119        gboolean (*chat_msg)(bee_t *bee, struct groupchat *c, bee_user_t *bu, const char *msg, time_t sent_at);
     120        gboolean (*chat_add_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu);
     121        gboolean (*chat_remove_user)(bee_t *bee, struct groupchat *c, bee_user_t *bu);
     122        gboolean (*chat_topic)(bee_t *bee, struct groupchat *c, const char *new_topic, bee_user_t *bu);
     123        gboolean (*chat_name_hint)(bee_t *bee, struct groupchat *c, const char *name);
     124        gboolean (*chat_invite)(bee_t *bee, bee_user_t *bu, const char *name, const char *msg);
     125
     126        struct file_transfer* (*ft_in_start)(bee_t * bee, bee_user_t * bu, const char *file_name, size_t file_size);
     127        gboolean (*ft_out_start)(struct im_connection *ic, struct file_transfer *ft);
     128        void (*ft_close)(struct im_connection *ic, struct file_transfer *ft);
     129        void (*ft_finished)(struct im_connection *ic, struct file_transfer *ft);
    134130} bee_ui_funcs_t;
    135131
     
    137133/* bee.c */
    138134bee_t *bee_new();
    139 void bee_free( bee_t *b );
     135void bee_free(bee_t *b);
    140136
    141137/* bee_user.c */
    142 bee_user_t *bee_user_new( bee_t *bee, struct im_connection *ic, const char *handle, bee_user_flags_t flags );
    143 int bee_user_free( bee_t *bee, bee_user_t *bu );
    144 bee_user_t *bee_user_by_handle( bee_t *bee, struct im_connection *ic, const char *handle );
    145 int bee_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, int flags );
    146 bee_group_t *bee_group_by_name( bee_t *bee, const char *name, gboolean creat );
    147 void bee_group_free( bee_t *bee );
     138bee_user_t *bee_user_new(bee_t *bee, struct im_connection *ic, const char *handle, bee_user_flags_t flags);
     139int bee_user_free(bee_t *bee, bee_user_t *bu);
     140bee_user_t *bee_user_by_handle(bee_t *bee, struct im_connection *ic, const char *handle);
     141int bee_user_msg(bee_t *bee, bee_user_t *bu, const char *msg, int flags);
     142bee_group_t *bee_group_by_name(bee_t *bee, const char *name, gboolean creat);
     143void bee_group_free(bee_t *bee);
    148144
    149145/* Callbacks from IM modules to core: */
     
    153149 *   OPT_LOGGED_IN and OPT_AWAY.
    154150 * - 'state' and 'message' can be NULL */
    155 G_MODULE_EXPORT void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message );
    156 G_MODULE_EXPORT void imcb_buddy_status_msg( struct im_connection *ic, const char *handle, const char *message );
    157 G_MODULE_EXPORT void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle );
     151G_MODULE_EXPORT void imcb_buddy_status(struct im_connection *ic, const char *handle, int flags, const char *state,
     152                                       const char *message);
     153G_MODULE_EXPORT void imcb_buddy_status_msg(struct im_connection *ic, const char *handle, const char *message);
     154G_MODULE_EXPORT void imcb_buddy_times(struct im_connection *ic, const char *handle, time_t login, time_t idle);
    158155/* Call when a handle says something. 'flags' and 'sent_at may be just 0. */
    159 G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, guint32 flags, time_t sent_at );
     156G_MODULE_EXPORT void imcb_buddy_msg(struct im_connection *ic, const char *handle, char *msg, guint32 flags,
     157                                    time_t sent_at);
    160158
    161159/* bee_chat.c */
     
    163161 * - imcb_chat_new(): the 'handle' parameter identifies the chat, like the
    164162 *   channel name on IRC.
    165  * - After you have a groupchat pointer, you should add the handles, finally 
     163 * - After you have a groupchat pointer, you should add the handles, finally
    166164 *   the user her/himself. At that point the group chat will be visible to the
    167165 *   user, too. */
    168 G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle );
    169 G_MODULE_EXPORT void imcb_chat_name_hint( struct groupchat *c, const char *name );
    170 G_MODULE_EXPORT void imcb_chat_free( struct groupchat *c );
     166G_MODULE_EXPORT struct groupchat *imcb_chat_new(struct im_connection *ic, const char *handle);
     167G_MODULE_EXPORT void imcb_chat_name_hint(struct groupchat *c, const char *name);
     168G_MODULE_EXPORT void imcb_chat_free(struct groupchat *c);
    171169/* To tell BitlBee 'who' said 'msg' in 'c'. 'flags' and 'sent_at' can be 0. */
    172 G_MODULE_EXPORT void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, guint32 flags, time_t sent_at );
     170G_MODULE_EXPORT void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, guint32 flags, time_t sent_at);
    173171/* System messages specific to a groupchat, so they can be displayed in the right context. */
    174 G_MODULE_EXPORT void imcb_chat_log( struct groupchat *c, char *format, ... );
     172G_MODULE_EXPORT void imcb_chat_log(struct groupchat *c, char *format, ...);
    175173/* To tell BitlBee 'who' changed the topic of 'c' to 'topic'. */
    176 G_MODULE_EXPORT void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at );
    177 G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *c, const char *handle );
     174G_MODULE_EXPORT void imcb_chat_topic(struct groupchat *c, char *who, char *topic, time_t set_at);
     175G_MODULE_EXPORT void imcb_chat_add_buddy(struct groupchat *c, const char *handle);
    178176/* To remove a handle from a group chat. Reason can be NULL. */
    179 G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *c, const char *handle, const char *reason );
    180 G_MODULE_EXPORT int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags );
    181 G_MODULE_EXPORT struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title );
    182 G_MODULE_EXPORT void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg );
     177G_MODULE_EXPORT void imcb_chat_remove_buddy(struct groupchat *c, const char *handle, const char *reason);
     178G_MODULE_EXPORT int bee_chat_msg(bee_t *bee, struct groupchat *c, const char *msg, int flags);
     179G_MODULE_EXPORT struct groupchat *bee_chat_by_title(bee_t *bee, struct im_connection *ic, const char *title);
     180G_MODULE_EXPORT void imcb_chat_invite(struct im_connection *ic, const char *name, const char *who, const char *msg);
    183181
    184182#endif /* __BEE_H__ */
  • protocols/bee_chat.c

    raf359b4 r5ebff60  
    1   /********************************************************************\
     1/********************************************************************\
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
     
    2727#include "bitlbee.h"
    2828
    29 struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle )
    30 {
    31         struct groupchat *c = g_new0( struct groupchat, 1 );
    32         bee_t *bee = ic->bee;
    33        
     29struct groupchat *imcb_chat_new(struct im_connection *ic, const char *handle)
     30{
     31        struct groupchat *c = g_new0(struct groupchat, 1);
     32        bee_t *bee = ic->bee;
     33
    3434        /* This one just creates the conversation structure, user won't see
    3535           anything yet until s/he is joined to the conversation. (This
    3636           allows you to add other already present participants first.) */
    37        
    38         ic->groupchats = g_slist_prepend( ic->groupchats, c );
     37
     38        ic->groupchats = g_slist_prepend(ic->groupchats, c);
    3939        c->ic = ic;
    40         c->title = g_strdup( handle );
    41         c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title );
    42        
    43         if( set_getbool( &ic->bee->set, "debug" ) )
    44                 imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle );
    45        
    46         if( bee->ui->chat_new )
    47                 bee->ui->chat_new( bee, c );
    48        
     40        c->title = g_strdup(handle);
     41        c->topic = g_strdup_printf(
     42                "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!",
     43                c->title);
     44
     45        if (set_getbool(&ic->bee->set, "debug")) {
     46                imcb_log(ic, "Creating new conversation: (id=%p,handle=%s)", c, handle);
     47        }
     48
     49        if (bee->ui->chat_new) {
     50                bee->ui->chat_new(bee, c);
     51        }
     52
    4953        return c;
    5054}
    5155
    52 void imcb_chat_name_hint( struct groupchat *c, const char *name )
     56void imcb_chat_name_hint(struct groupchat *c, const char *name)
    5357{
    5458        bee_t *bee = c->ic->bee;
    55        
    56         if( bee->ui->chat_name_hint )
    57                 bee->ui->chat_name_hint( bee, c, name );
    58 }
    59 
    60 void imcb_chat_free( struct groupchat *c )
     59
     60        if (bee->ui->chat_name_hint) {
     61                bee->ui->chat_name_hint(bee, c, name);
     62        }
     63}
     64
     65void imcb_chat_free(struct groupchat *c)
    6166{
    6267        struct im_connection *ic = c->ic;
    6368        bee_t *bee = ic->bee;
    6469        GList *ir;
    65        
    66         if( bee->ui->chat_free )
    67                 bee->ui->chat_free( bee, c );
    68        
    69         if( set_getbool( &ic->bee->set, "debug" ) )
    70                 imcb_log( ic, "You were removed from conversation %p", c );
    71        
    72         ic->groupchats = g_slist_remove( ic->groupchats, c );
    73        
    74         for( ir = c->in_room; ir; ir = ir->next )
    75                 g_free( ir->data );
    76         g_list_free( c->in_room );
    77         g_free( c->title );
    78         g_free( c->topic );
    79         g_free( c );
    80 }
    81 
    82 static gboolean handle_is_self( struct im_connection *ic, const char *handle )
    83 {
    84         return ( ic->acc->prpl->handle_is_self ) ?
    85                  ic->acc->prpl->handle_is_self( ic, handle ) :
    86                  ( ic->acc->prpl->handle_cmp( ic->acc->user, handle ) == 0 );
    87 }
    88 
    89 void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at )
     70
     71        if (bee->ui->chat_free) {
     72                bee->ui->chat_free(bee, c);
     73        }
     74
     75        if (set_getbool(&ic->bee->set, "debug")) {
     76                imcb_log(ic, "You were removed from conversation %p", c);
     77        }
     78
     79        ic->groupchats = g_slist_remove(ic->groupchats, c);
     80
     81        for (ir = c->in_room; ir; ir = ir->next) {
     82                g_free(ir->data);
     83        }
     84        g_list_free(c->in_room);
     85        g_free(c->title);
     86        g_free(c->topic);
     87        g_free(c);
     88}
     89
     90static gboolean handle_is_self(struct im_connection *ic, const char *handle)
     91{
     92        return (ic->acc->prpl->handle_is_self) ?
     93               ic->acc->prpl->handle_is_self(ic, handle) :
     94               (ic->acc->prpl->handle_cmp(ic->acc->user, handle) == 0);
     95}
     96
     97void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at)
    9098{
    9199        struct im_connection *ic = c->ic;
     
    94102        gboolean temp;
    95103        char *s;
    96        
     104
    97105        /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */
    98         if( handle_is_self( ic, who ) )
     106        if (handle_is_self(ic, who)) {
    99107                return;
    100        
    101         bu = bee_user_by_handle( bee, ic, who );
    102         temp = ( bu == NULL );
    103        
    104         if( temp )
    105                 bu = bee_user_new( bee, ic, who, BEE_USER_ONLINE );
    106        
    107         s = set_getstr( &ic->bee->set, "strip_html" );
    108         if( ( g_strcasecmp( s, "always" ) == 0 ) ||
    109             ( ( ic->flags & OPT_DOES_HTML ) && s ) )
    110                 strip_html( msg );
    111        
    112         if( bee->ui->chat_msg )
    113                 bee->ui->chat_msg( bee, c, bu, msg, sent_at );
    114        
    115         if( temp )
    116                 bee_user_free( bee, bu );
    117 }
    118 
    119 void imcb_chat_log( struct groupchat *c, char *format, ... )
     108        }
     109
     110        bu = bee_user_by_handle(bee, ic, who);
     111        temp = (bu == NULL);
     112
     113        if (temp) {
     114                bu = bee_user_new(bee, ic, who, BEE_USER_ONLINE);
     115        }
     116
     117        s = set_getstr(&ic->bee->set, "strip_html");
     118        if ((g_strcasecmp(s, "always") == 0) ||
     119            ((ic->flags & OPT_DOES_HTML) && s)) {
     120                strip_html(msg);
     121        }
     122
     123        if (bee->ui->chat_msg) {
     124                bee->ui->chat_msg(bee, c, bu, msg, sent_at);
     125        }
     126
     127        if (temp) {
     128                bee_user_free(bee, bu);
     129        }
     130}
     131
     132void imcb_chat_log(struct groupchat *c, char *format, ...)
    120133{
    121134        struct im_connection *ic = c->ic;
     
    123136        va_list params;
    124137        char *text;
    125        
    126         if( !bee->ui->chat_log )
     138
     139        if (!bee->ui->chat_log) {
    127140                return;
    128        
    129         va_start( params, format );
    130         text = g_strdup_vprintf( format, params );
    131         va_end( params );
    132        
    133         bee->ui->chat_log( bee, c, text );
    134         g_free( text );
    135 }
    136 
    137 void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at )
     141        }
     142
     143        va_start(params, format);
     144        text = g_strdup_vprintf(format, params);
     145        va_end(params);
     146
     147        bee->ui->chat_log(bee, c, text);
     148        g_free(text);
     149}
     150
     151void imcb_chat_topic(struct groupchat *c, char *who, char *topic, time_t set_at)
    138152{
    139153        struct im_connection *ic = c->ic;
    140154        bee_t *bee = ic->bee;
    141155        bee_user_t *bu;
    142        
    143         if( !bee->ui->chat_topic )
     156
     157        if (!bee->ui->chat_topic) {
    144158                return;
    145        
    146         if( who == NULL)
     159        }
     160
     161        if (who == NULL) {
    147162                bu = NULL;
    148         else if( handle_is_self( ic, who ) )
     163        } else if (handle_is_self(ic, who)) {
    149164                bu = bee->user;
    150         else
    151                 bu = bee_user_by_handle( bee, ic, who );
    152        
    153         if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) ||
    154             ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) )
    155                 strip_html( topic );
    156        
    157         bee->ui->chat_topic( bee, c, topic, bu );
    158 }
    159 
    160 void imcb_chat_add_buddy( struct groupchat *c, const char *handle )
    161 {
    162         struct im_connection *ic = c->ic;
    163         bee_t *bee = ic->bee;
    164         bee_user_t *bu = bee_user_by_handle( bee, ic, handle );
     165        } else {
     166                bu = bee_user_by_handle(bee, ic, who);
     167        }
     168
     169        if ((g_strcasecmp(set_getstr(&ic->bee->set, "strip_html"), "always") == 0) ||
     170            ((ic->flags & OPT_DOES_HTML) && set_getbool(&ic->bee->set, "strip_html"))) {
     171                strip_html(topic);
     172        }
     173
     174        bee->ui->chat_topic(bee, c, topic, bu);
     175}
     176
     177void imcb_chat_add_buddy(struct groupchat *c, const char *handle)
     178{
     179        struct im_connection *ic = c->ic;
     180        bee_t *bee = ic->bee;
     181        bee_user_t *bu = bee_user_by_handle(bee, ic, handle);
    165182        gboolean me;
    166        
    167         if( set_getbool( &c->ic->bee->set, "debug" ) )
    168                 imcb_log( c->ic, "User %s added to conversation %p", handle, c );
    169        
    170         me = handle_is_self( ic, handle );
    171        
     183
     184        if (set_getbool(&c->ic->bee->set, "debug")) {
     185                imcb_log(c->ic, "User %s added to conversation %p", handle, c);
     186        }
     187
     188        me = handle_is_self(ic, handle);
     189
    172190        /* Most protocols allow people to join, even when they're not in
    173191           your contact list. Try to handle that here */
    174         if( !me && !bu )
    175                 bu = bee_user_new( bee, ic, handle, BEE_USER_LOCAL );
    176        
     192        if (!me && !bu) {
     193                bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL);
     194        }
     195
    177196        /* Add the handle to the room userlist */
    178197        /* TODO: Use bu instead of a string */
    179         c->in_room = g_list_append( c->in_room, g_strdup( handle ) );
    180        
    181         if( bee->ui->chat_add_user )
    182                 bee->ui->chat_add_user( bee, c, me ? bee->user : bu );
    183        
    184         if( me )
     198        c->in_room = g_list_append(c->in_room, g_strdup(handle));
     199
     200        if (bee->ui->chat_add_user) {
     201                bee->ui->chat_add_user(bee, c, me ? bee->user : bu);
     202        }
     203
     204        if (me) {
    185205                c->joined = 1;
    186 }
    187 
    188 void imcb_chat_remove_buddy( struct groupchat *c, const char *handle, const char *reason )
     206        }
     207}
     208
     209void imcb_chat_remove_buddy(struct groupchat *c, const char *handle, const char *reason)
    189210{
    190211        struct im_connection *ic = c->ic;
    191212        bee_t *bee = ic->bee;
    192213        bee_user_t *bu = NULL;
    193        
    194         if( set_getbool( &bee->set, "debug" ) )
    195                 imcb_log( ic, "User %s removed from conversation %p (%s)", handle, c, reason ? reason : "" );
    196        
     214
     215        if (set_getbool(&bee->set, "debug")) {
     216                imcb_log(ic, "User %s removed from conversation %p (%s)", handle, c, reason ? reason : "");
     217        }
     218
    197219        /* It might be yourself! */
    198         if( handle_is_self( ic, handle ) )
    199         {
    200                 if( c->joined == 0 )
     220        if (handle_is_self(ic, handle)) {
     221                if (c->joined == 0) {
    201222                        return;
    202                
     223                }
     224
    203225                bu = bee->user;
    204226                c->joined = 0;
    205         }
    206         else
    207         {
    208                 bu = bee_user_by_handle( bee, ic, handle );
    209         }
    210        
    211         if( bee->ui->chat_remove_user && bu )
    212                 bee->ui->chat_remove_user( bee, c, bu );
    213 }
    214 
    215 int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags )
     227        } else {
     228                bu = bee_user_by_handle(bee, ic, handle);
     229        }
     230
     231        if (bee->ui->chat_remove_user && bu) {
     232                bee->ui->chat_remove_user(bee, c, bu);
     233        }
     234}
     235
     236int bee_chat_msg(bee_t *bee, struct groupchat *c, const char *msg, int flags)
    216237{
    217238        struct im_connection *ic = c->ic;
    218239        char *buf = NULL;
    219        
    220         if( ( ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
    221         {
    222                 buf = escape_html( msg );
     240
     241        if ((ic->flags & OPT_DOES_HTML) && (g_strncasecmp(msg, "<html>", 6) != 0)) {
     242                buf = escape_html(msg);
    223243                msg = buf;
    224         }
    225         else
    226                 buf = g_strdup( msg );
    227        
    228         ic->acc->prpl->chat_msg( c, buf, flags );
    229         g_free( buf );
    230        
     244        } else {
     245                buf = g_strdup(msg);
     246        }
     247
     248        ic->acc->prpl->chat_msg(c, buf, flags);
     249        g_free(buf);
     250
    231251        return 1;
    232252}
    233253
    234 struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title )
     254struct groupchat *bee_chat_by_title(bee_t *bee, struct im_connection *ic, const char *title)
    235255{
    236256        struct groupchat *c;
    237257        GSList *l;
    238        
    239         for( l = ic->groupchats; l; l = l->next )
    240         {
     258
     259        for (l = ic->groupchats; l; l = l->next) {
    241260                c = l->data;
    242                 if( strcmp( c->title, title ) == 0 )
     261                if (strcmp(c->title, title) == 0) {
    243262                        return c;
    244         }
    245        
     263                }
     264        }
     265
    246266        return NULL;
    247267}
    248268
    249 void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg )
    250 {
    251         bee_user_t *bu = bee_user_by_handle( ic->bee, ic, who );
    252        
    253         if( bu && ic->bee->ui->chat_invite )
    254                 ic->bee->ui->chat_invite( ic->bee, bu, name, msg );
    255 }
     269void imcb_chat_invite(struct im_connection *ic, const char *name, const char *who, const char *msg)
     270{
     271        bee_user_t *bu = bee_user_by_handle(ic->bee, ic, who);
     272
     273        if (bu && ic->bee->ui->chat_invite) {
     274                ic->bee->ui->chat_invite(ic->bee, bu, name, msg);
     275        }
     276}
  • protocols/bee_ft.c

    raf359b4 r5ebff60  
    2626#include "ft.h"
    2727
    28 file_transfer_t *imcb_file_send_start( struct im_connection *ic, char *handle, char *file_name, size_t file_size )
     28file_transfer_t *imcb_file_send_start(struct im_connection *ic, char *handle, char *file_name, size_t file_size)
    2929{
    30         bee_t *bee = ic->bee; 
    31         bee_user_t *bu = bee_user_by_handle( bee, ic, handle );
    32        
    33         if( bee->ui->ft_in_start )
    34                 return bee->ui->ft_in_start( bee, bu, file_name, file_size );
    35         else
     30        bee_t *bee = ic->bee;
     31        bee_user_t *bu = bee_user_by_handle(bee, ic, handle);
     32
     33        if (bee->ui->ft_in_start) {
     34                return bee->ui->ft_in_start(bee, bu, file_name, file_size);
     35        } else {
    3636                return NULL;
     37        }
    3738}
    3839
    39 gboolean imcb_file_recv_start( struct im_connection *ic, file_transfer_t *ft )
     40gboolean imcb_file_recv_start(struct im_connection *ic, file_transfer_t *ft)
    4041{
    4142        bee_t *bee = ic->bee;
    42        
    43         if( bee->ui->ft_out_start )
    44                 return bee->ui->ft_out_start( ic, ft );
    45         else
     43
     44        if (bee->ui->ft_out_start) {
     45                return bee->ui->ft_out_start(ic, ft);
     46        } else {
    4647                return FALSE;
     48        }
    4749}
    4850
    49 void imcb_file_canceled( struct im_connection *ic, file_transfer_t *file, char *reason )
     51void imcb_file_canceled(struct im_connection *ic, file_transfer_t *file, char *reason)
    5052{
    5153        bee_t *bee = ic->bee;
    52        
    53         if( file->canceled )
    54                 file->canceled( file, reason );
    55        
    56         if( bee->ui->ft_close )
    57                 bee->ui->ft_close( ic, file );
     54
     55        if (file->canceled) {
     56                file->canceled(file, reason);
     57        }
     58
     59        if (bee->ui->ft_close) {
     60                bee->ui->ft_close(ic, file);
     61        }
    5862}
    5963
    60 void imcb_file_finished( struct im_connection *ic, file_transfer_t *file )
     64void imcb_file_finished(struct im_connection *ic, file_transfer_t *file)
    6165{
    6266        bee_t *bee = ic->bee;
    63        
    64         if( bee->ui->ft_finished )
    65                 bee->ui->ft_finished( ic, file );
     67
     68        if (bee->ui->ft_finished) {
     69                bee->ui->ft_finished(ic, file);
     70        }
    6671}
  • protocols/bee_user.c

    raf359b4 r5ebff60  
    1   /********************************************************************\
     1/********************************************************************\
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
     
    2727#include "bitlbee.h"
    2828
    29 bee_user_t *bee_user_new( bee_t *bee, struct im_connection *ic, const char *handle, bee_user_flags_t flags )
    30 {
    31         bee_user_t *bu;
    32        
    33         if( bee_user_by_handle( bee, ic, handle ) != NULL )
     29bee_user_t *bee_user_new(bee_t *bee, struct im_connection *ic, const char *handle, bee_user_flags_t flags)
     30{
     31        bee_user_t *bu;
     32
     33        if (bee_user_by_handle(bee, ic, handle) != NULL) {
    3434                return NULL;
    35        
    36         bu = g_new0( bee_user_t, 1 );
     35        }
     36
     37        bu = g_new0(bee_user_t, 1);
    3738        bu->bee = bee;
    3839        bu->ic = ic;
    3940        bu->flags = flags;
    40         bu->handle = g_strdup( handle );
    41         bee->users = g_slist_prepend( bee->users, bu );
    42        
    43         if( bee->ui->user_new )
    44                 bee->ui->user_new( bee, bu );
    45         if( ic->acc->prpl->buddy_data_add )
    46                 ic->acc->prpl->buddy_data_add( bu );
    47        
     41        bu->handle = g_strdup(handle);
     42        bee->users = g_slist_prepend(bee->users, bu);
     43
     44        if (bee->ui->user_new) {
     45                bee->ui->user_new(bee, bu);
     46        }
     47        if (ic->acc->prpl->buddy_data_add) {
     48                ic->acc->prpl->buddy_data_add(bu);
     49        }
     50
    4851        /* Offline by default. This will set the right flags. */
    49         imcb_buddy_status( ic, handle, 0, NULL, NULL );
    50        
     52        imcb_buddy_status(ic, handle, 0, NULL, NULL);
     53
    5154        return bu;
    5255}
    5356
    54 int bee_user_free( bee_t *bee, bee_user_t *bu )
    55 {
    56         if( !bu )
     57int bee_user_free(bee_t *bee, bee_user_t *bu)
     58{
     59        if (!bu) {
    5760                return 0;
    58        
    59         if( bee->ui->user_free )
    60                 bee->ui->user_free( bee, bu );
    61         if( bu->ic->acc->prpl->buddy_data_free )
    62                 bu->ic->acc->prpl->buddy_data_free( bu );
    63        
    64         g_free( bu->handle );
    65         g_free( bu->fullname );
    66         g_free( bu->nick );
    67         g_free( bu->status );
    68         g_free( bu->status_msg );
    69         g_free( bu );
    70        
    71         bee->users = g_slist_remove( bee->users, bu );
    72        
     61        }
     62
     63        if (bee->ui->user_free) {
     64                bee->ui->user_free(bee, bu);
     65        }
     66        if (bu->ic->acc->prpl->buddy_data_free) {
     67                bu->ic->acc->prpl->buddy_data_free(bu);
     68        }
     69
     70        g_free(bu->handle);
     71        g_free(bu->fullname);
     72        g_free(bu->nick);
     73        g_free(bu->status);
     74        g_free(bu->status_msg);
     75        g_free(bu);
     76
     77        bee->users = g_slist_remove(bee->users, bu);
     78
    7379        return 1;
    7480}
    7581
    76 bee_user_t *bee_user_by_handle( bee_t *bee, struct im_connection *ic, const char *handle )
     82bee_user_t *bee_user_by_handle(bee_t *bee, struct im_connection *ic, const char *handle)
    7783{
    7884        GSList *l;
    79        
    80         for( l = bee->users; l; l = l->next )
    81         {
     85
     86        for (l = bee->users; l; l = l->next) {
    8287                bee_user_t *bu = l->data;
    83                
    84                 if( bu->ic == ic && ic->acc->prpl->handle_cmp( bu->handle, handle ) == 0 )
     88
     89                if (bu->ic == ic && ic->acc->prpl->handle_cmp(bu->handle, handle) == 0) {
    8590                        return bu;
    86         }
    87        
     91                }
     92        }
     93
    8894        return NULL;
    8995}
    9096
    91 int bee_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, int flags )
     97int bee_user_msg(bee_t *bee, bee_user_t *bu, const char *msg, int flags)
    9298{
    9399        char *buf = NULL;
    94100        int st;
    95        
    96         if( ( bu->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
    97         {
    98                 buf = escape_html( msg );
     101
     102        if ((bu->ic->flags & OPT_DOES_HTML) && (g_strncasecmp(msg, "<html>", 6) != 0)) {
     103                buf = escape_html(msg);
    99104                msg = buf;
    100         }
    101         else
    102                 buf = g_strdup( msg );
    103        
    104         st = bu->ic->acc->prpl->buddy_msg( bu->ic, bu->handle, buf, flags );
    105         g_free( buf );
    106        
     105        } else {
     106                buf = g_strdup(msg);
     107        }
     108
     109        st = bu->ic->acc->prpl->buddy_msg(bu->ic, bu->handle, buf, flags);
     110        g_free(buf);
     111
    107112        return st;
    108113}
     
    110115
    111116/* Groups */
    112 static bee_group_t *bee_group_new( bee_t *bee, const char *name )
    113 {
    114         bee_group_t *bg = g_new0( bee_group_t, 1 );
    115        
    116         bg->name = g_strdup( name );
    117         bg->key = g_utf8_casefold( name, -1 );
    118         bee->groups = g_slist_prepend( bee->groups, bg );
    119        
     117static bee_group_t *bee_group_new(bee_t *bee, const char *name)
     118{
     119        bee_group_t *bg = g_new0(bee_group_t, 1);
     120
     121        bg->name = g_strdup(name);
     122        bg->key = g_utf8_casefold(name, -1);
     123        bee->groups = g_slist_prepend(bee->groups, bg);
     124
    120125        return bg;
    121126}
    122127
    123 bee_group_t *bee_group_by_name( bee_t *bee, const char *name, gboolean creat )
     128bee_group_t *bee_group_by_name(bee_t *bee, const char *name, gboolean creat)
    124129{
    125130        GSList *l;
    126131        char *key;
    127        
    128         if( name == NULL )
     132
     133        if (name == NULL) {
    129134                return NULL;
    130        
    131         key = g_utf8_casefold( name, -1 );
    132         for( l = bee->groups; l; l = l->next )
    133         {
     135        }
     136
     137        key = g_utf8_casefold(name, -1);
     138        for (l = bee->groups; l; l = l->next) {
    134139                bee_group_t *bg = l->data;
    135                 if( strcmp( bg->key, key ) == 0 )
     140                if (strcmp(bg->key, key) == 0) {
    136141                        break;
    137         }
    138         g_free( key );
    139        
    140         if( !l )
    141                 return creat ? bee_group_new( bee, name ) : NULL;
    142         else
     142                }
     143        }
     144        g_free(key);
     145
     146        if (!l) {
     147                return creat ? bee_group_new(bee, name) : NULL;
     148        } else {
    143149                return l->data;
    144 }
    145 
    146 void bee_group_free( bee_t *bee )
    147 {
    148         while( bee->groups )
    149         {
     150        }
     151}
     152
     153void bee_group_free(bee_t *bee)
     154{
     155        while (bee->groups) {
    150156                bee_group_t *bg = bee->groups->data;
    151                 g_free( bg->name );
    152                 g_free( bg->key );
    153                 g_free( bg );
    154                 bee->groups = g_slist_remove( bee->groups, bee->groups->data );
     157                g_free(bg->name);
     158                g_free(bg->key);
     159                g_free(bg);
     160                bee->groups = g_slist_remove(bee->groups, bee->groups->data);
    155161        }
    156162}
     
    158164
    159165/* IM->UI callbacks */
    160 void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message )
     166void imcb_buddy_status(struct im_connection *ic, const char *handle, int flags, const char *state, const char *message)
    161167{
    162168        bee_t *bee = ic->bee;
    163169        bee_user_t *bu, *old;
    164        
    165         if( !( bu = bee_user_by_handle( bee, ic, handle ) ) )
    166         {
    167                 if( g_strcasecmp( set_getstr( &ic->bee->set, "handle_unknown" ), "add" ) == 0 )
    168                 {
    169                         bu = bee_user_new( bee, ic, handle, BEE_USER_LOCAL );
    170                 }
    171                 else
    172                 {
    173                         if( g_strcasecmp( set_getstr( &ic->bee->set, "handle_unknown" ), "ignore" ) != 0 )
    174                         {
    175                                 imcb_log( ic, "imcb_buddy_status() for unknown handle %s:\n"
    176                                               "flags = %d, state = %s, message = %s", handle, flags,
    177                                               state ? state : "NULL", message ? message : "NULL" );
     170
     171        if (!(bu = bee_user_by_handle(bee, ic, handle))) {
     172                if (g_strcasecmp(set_getstr(&ic->bee->set, "handle_unknown"), "add") == 0) {
     173                        bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL);
     174                } else {
     175                        if (g_strcasecmp(set_getstr(&ic->bee->set, "handle_unknown"), "ignore") != 0) {
     176                                imcb_log(ic, "imcb_buddy_status() for unknown handle %s:\n"
     177                                         "flags = %d, state = %s, message = %s", handle, flags,
     178                                         state ? state : "NULL", message ? message : "NULL");
    178179                        }
    179                        
     180
    180181                        return;
    181182                }
    182183        }
    183        
     184
    184185        /* May be nice to give the UI something to compare against. */
    185         old = g_memdup( bu, sizeof( bee_user_t ) );
    186        
     186        old = g_memdup(bu, sizeof(bee_user_t));
     187
    187188        /* TODO(wilmer): OPT_AWAY, or just state == NULL ? */
    188189        bu->flags = flags;
    189         bu->status_msg = g_strdup( message );
    190         if( state && *state )
    191                 bu->status = g_strdup( state );
    192         else if( flags & OPT_AWAY )
    193                 bu->status = g_strdup( "Away" );
    194         else
     190        bu->status_msg = g_strdup(message);
     191        if (state && *state) {
     192                bu->status = g_strdup(state);
     193        } else if (flags & OPT_AWAY) {
     194                bu->status = g_strdup("Away");
     195        } else {
    195196                bu->status = NULL;
    196        
    197         if( bu->status == NULL && ( flags & OPT_MOBILE ) &&
    198             set_getbool( &bee->set, "mobile_is_away" ) )
    199         {
     197        }
     198
     199        if (bu->status == NULL && (flags & OPT_MOBILE) &&
     200            set_getbool(&bee->set, "mobile_is_away")) {
    200201                bu->flags |= BEE_USER_AWAY;
    201                 bu->status = g_strdup( "Mobile" );
    202         }
    203        
    204         if( bee->ui->user_status )
    205                 bee->ui->user_status( bee, bu, old );
    206        
    207         g_free( old->status_msg );
    208         g_free( old->status );
    209         g_free( old );
     202                bu->status = g_strdup("Mobile");
     203        }
     204
     205        if (bee->ui->user_status) {
     206                bee->ui->user_status(bee, bu, old);
     207        }
     208
     209        g_free(old->status_msg);
     210        g_free(old->status);
     211        g_free(old);
    210212}
    211213
    212214/* Same, but only change the away/status message, not any away/online state info. */
    213 void imcb_buddy_status_msg( struct im_connection *ic, const char *handle, const char *message )
     215void imcb_buddy_status_msg(struct im_connection *ic, const char *handle, const char *message)
    214216{
    215217        bee_t *bee = ic->bee;
    216218        bee_user_t *bu, *old;
    217        
    218         if( !( bu = bee_user_by_handle( bee, ic, handle ) ) )
    219         {
     219
     220        if (!(bu = bee_user_by_handle(bee, ic, handle))) {
    220221                return;
    221222        }
    222        
    223         old = g_memdup( bu, sizeof( bee_user_t ) );
    224        
    225         bu->status_msg = message && *message ? g_strdup( message ) : NULL;
    226        
    227         if( bee->ui->user_status )
    228                 bee->ui->user_status( bee, bu, old );
    229        
    230         g_free( old->status_msg );
    231         g_free( old );
    232 }
    233 
    234 void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle )
    235 {
    236         bee_t *bee = ic->bee;
    237         bee_user_t *bu;
    238        
    239         if( !( bu = bee_user_by_handle( bee, ic, handle ) ) )
     223
     224        old = g_memdup(bu, sizeof(bee_user_t));
     225
     226        bu->status_msg = message && *message ? g_strdup(message) : NULL;
     227
     228        if (bee->ui->user_status) {
     229                bee->ui->user_status(bee, bu, old);
     230        }
     231
     232        g_free(old->status_msg);
     233        g_free(old);
     234}
     235
     236void imcb_buddy_times(struct im_connection *ic, const char *handle, time_t login, time_t idle)
     237{
     238        bee_t *bee = ic->bee;
     239        bee_user_t *bu;
     240
     241        if (!(bu = bee_user_by_handle(bee, ic, handle))) {
    240242                return;
    241        
     243        }
     244
    242245        bu->login_time = login;
    243246        bu->idle_time = idle;
    244247}
    245248
    246 void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at )
    247 {
    248         bee_t *bee = ic->bee;
    249         bee_user_t *bu;
    250        
    251         bu = bee_user_by_handle( bee, ic, handle );
    252        
    253         if( !bu && !( ic->flags & OPT_LOGGING_OUT ) )
    254         {
    255                 char *h = set_getstr( &bee->set, "handle_unknown" );
    256                
    257                 if( g_strcasecmp( h, "ignore" ) == 0 )
    258                 {
     249void imcb_buddy_msg(struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at)
     250{
     251        bee_t *bee = ic->bee;
     252        bee_user_t *bu;
     253
     254        bu = bee_user_by_handle(bee, ic, handle);
     255
     256        if (!bu && !(ic->flags & OPT_LOGGING_OUT)) {
     257                char *h = set_getstr(&bee->set, "handle_unknown");
     258
     259                if (g_strcasecmp(h, "ignore") == 0) {
    259260                        return;
    260                 }
    261                 else if( g_strncasecmp( h, "add", 3 ) == 0 )
    262                 {
    263                         bu = bee_user_new( bee, ic, handle, BEE_USER_LOCAL );
    264                 }
    265         }
    266        
    267         if( bee->ui->user_msg && bu )
    268                 bee->ui->user_msg( bee, bu, msg, sent_at );
    269         else
    270                 imcb_log( ic, "Message from unknown handle %s:\n%s", handle, msg );
    271 }
    272 
    273 void imcb_buddy_typing( struct im_connection *ic, const char *handle, uint32_t flags )
    274 {
    275         bee_user_t *bu;
    276        
    277         if( ic->bee->ui->user_typing &&
    278             ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) )
    279         {
    280                 ic->bee->ui->user_typing( ic->bee, bu, flags );
    281         }
    282 }
    283 
    284 void imcb_buddy_action_response( bee_user_t *bu, const char *action, char * const args[], void *data )
    285 {
    286         if( bu->bee->ui->user_action_response )
    287                 bu->bee->ui->user_action_response( bu->bee, bu, action, args, data );
    288 }
     261                } else if (g_strncasecmp(h, "add", 3) == 0) {
     262                        bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL);
     263                }
     264        }
     265
     266        if (bee->ui->user_msg && bu) {
     267                bee->ui->user_msg(bee, bu, msg, sent_at);
     268        } else {
     269                imcb_log(ic, "Message from unknown handle %s:\n%s", handle, msg);
     270        }
     271}
     272
     273void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags)
     274{
     275        bee_user_t *bu;
     276
     277        if (ic->bee->ui->user_typing &&
     278            (bu = bee_user_by_handle(ic->bee, ic, handle))) {
     279                ic->bee->ui->user_typing(ic->bee, bu, flags);
     280        }
     281}
     282
     283void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data)
     284{
     285        if (bu->bee->ui->user_action_response) {
     286                bu->bee->ui->user_action_response(bu->bee, bu, action, args, data);
     287        }
     288}
  • protocols/ft.h

    raf359b4 r5ebff60  
    3535
    3636typedef enum {
    37         FT_STATUS_LISTENING     = 1,
    38         FT_STATUS_TRANSFERRING  = 2,
    39         FT_STATUS_FINISHED      = 4,
    40         FT_STATUS_CANCELED      = 8,
    41         FT_STATUS_CONNECTING    = 16
     37        FT_STATUS_LISTENING     = 1,
     38        FT_STATUS_TRANSFERRING  = 2,
     39        FT_STATUS_FINISHED      = 4,
     40        FT_STATUS_CANCELED      = 8,
     41        FT_STATUS_CONNECTING    = 16
    4242} file_status_t;
    4343
     
    7575        /*
    7676         * The current status of this file transfer.
    77          */ 
     77         */
    7878        file_status_t status;
    79        
     79
    8080        /*
    8181         * file size
    8282         */
    8383        size_t file_size;
    84        
     84
    8585        /*
    8686         * Number of bytes that have been successfully transferred.
     
    108108        gpointer data;
    109109        struct im_connection *ic;
    110        
     110
    111111        /*
    112112         * Private data.
    113113         */
    114114        gpointer priv;
    115        
     115
    116116        /*
    117117         * If set, called after succesful connection setup.
    118118         */
    119         void (*accept) ( struct file_transfer *file );
    120        
     119        void (*accept)(struct file_transfer *file);
     120
    121121        /*
    122122         * If set, called when the transfer is canceled or finished.
     
    124124         *
    125125         */
    126         void (*free) ( struct file_transfer *file );
    127        
     126        void (*free)(struct file_transfer *file);
     127
    128128        /*
    129129         * If set, called when the transfer is finished and successful.
    130130         */
    131         void (*finished) ( struct file_transfer *file );
    132        
     131        void (*finished)(struct file_transfer *file);
     132
    133133        /*
    134134         * If set, called when the transfer is canceled.
     
    136136         *  a call to imcb_file_canceled )
    137137         */
    138         void (*canceled) ( struct file_transfer *file, char *reason );
    139        
     138        void (*canceled)(struct file_transfer *file, char *reason);
     139
    140140        /*
    141141         * called by the sending side to indicate that it is writable.
    142          * The callee should check if data is available and call the 
     142         * The callee should check if data is available and call the
    143143         * function(as seen below) if that is the case.
    144144         */
    145         gboolean (*write_request) ( struct file_transfer *file );
     145        gboolean (*write_request)(struct file_transfer *file);
    146146
    147147        /*
     
    151151         * avoids buffering.
    152152         */
    153         gboolean (*write) (struct file_transfer *file, char *buffer, unsigned int len );
     153        gboolean (*write)(struct file_transfer *file, char *buffer, unsigned int len);
    154154
    155155        /* The send buffer associated with this transfer.
     
    163163 * This starts a file transfer from bitlbee to the user.
    164164 */
    165 file_transfer_t *imcb_file_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size );
     165file_transfer_t *imcb_file_send_start(struct im_connection *ic, char *user_nick, char *file_name, size_t file_size);
    166166
    167167/*
     
    169169 * the canceled() and free() callbacks given in file will be called by this function.
    170170 */
    171 void imcb_file_canceled( struct im_connection *ic, file_transfer_t *file, char *reason );
     171void imcb_file_canceled(struct im_connection *ic, file_transfer_t *file, char *reason);
    172172
    173 gboolean imcb_file_recv_start( struct im_connection *ic, file_transfer_t *ft );
     173gboolean imcb_file_recv_start(struct im_connection *ic, file_transfer_t *ft);
    174174
    175 void imcb_file_finished( struct im_connection *ic, file_transfer_t *file );
     175void imcb_file_finished(struct im_connection *ic, file_transfer_t *file);
    176176#endif
  • 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)