source: protocols/jabber/presence.c @ ebb95b6

Last change on this file since ebb95b6 was ebb95b6, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-11-14T23:42:07Z

Merging from devel/Jelmer.

  • Property mode set to 100644
File size: 7.2 KB
RevLine 
[f06894d]1/***************************************************************************\
2*                                                                           *
3*  BitlBee - An IRC to IM gateway                                           *
[21167d2]4*  Jabber module - Handling of presence (tags), etc                         *
[f06894d]5*                                                                           *
6*  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
7*                                                                           *
8*  This program is free software; you can redistribute it and/or modify     *
9*  it under the terms of the GNU General Public License as published by     *
10*  the Free Software Foundation; either version 2 of the License, or        *
11*  (at your option) any later version.                                      *
12*                                                                           *
13*  This program is distributed in the hope that it will be useful,          *
14*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
15*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
16*  GNU General Public License for more details.                             *
17*                                                                           *
18*  You should have received a copy of the GNU General Public License along  *
19*  with this program; if not, write to the Free Software Foundation, Inc.,  *
20*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
21*                                                                           *
22\***************************************************************************/
23
24#include "jabber.h"
25
26xt_status jabber_pkt_presence( struct xt_node *node, gpointer data )
27{
[0da65d5]28        struct im_connection *ic = data;
[f06894d]29        char *from = xt_find_attr( node, "from" );
[4a0614e]30        char *type = xt_find_attr( node, "type" );      /* NULL should mean the person is online. */
[6a1128d]31        struct xt_node *c;
[a21a8ac]32        struct jabber_buddy *bud;
[2758cfe]33        int is_chat = 0, is_away = 0;
[788a1af]34        char *s;
[f06894d]35       
[4a0614e]36        if( !from )
37                return XT_HANDLED;
38       
[e35d1a1]39        if( ( s = strchr( from, '/' ) ) )
40        {
41                *s = 0;
42                if( jabber_chat_by_name( ic, from ) )
43                        is_chat = 1;
44                *s = '/';
45        }
46       
[4a0614e]47        if( type == NULL )
[6a1128d]48        {
[0da65d5]49                if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
[a21a8ac]50                {
[0da65d5]51                        if( set_getbool( &ic->irc->set, "debug" ) )
[84b045d]52                                imcb_log( ic, "WARNING: Could not handle presence information from JID: %s", from );
[8eb10c9]53                        return XT_HANDLED;
[a21a8ac]54                }
[6a1128d]55               
56                g_free( bud->away_message );
57                if( ( c = xt_find_node( node->children, "status" ) ) && c->text_len > 0 )
58                        bud->away_message = g_strdup( c->text );
59                else
60                        bud->away_message = NULL;
61               
62                if( ( c = xt_find_node( node->children, "show" ) ) && c->text_len > 0 )
[6bbb939]63                {
[6a1128d]64                        bud->away_state = (void*) jabber_away_state_by_code( c->text );
[6bbb939]65                        if( strcmp( c->text, "chat" ) != 0 )
66                                is_away = OPT_AWAY;
67                }
[6a1128d]68                else
[a21a8ac]69                {
[6a1128d]70                        bud->away_state = NULL;
[a21a8ac]71                        /* Let's only set last_act if there's *no* away state,
72                           since it could be some auto-away thingy. */
73                        bud->last_act = time( NULL );
74                }
[6a1128d]75               
76                if( ( c = xt_find_node( node->children, "priority" ) ) && c->text_len > 0 )
77                        bud->priority = atoi( c->text );
78                else
79                        bud->priority = 0;
80               
[e35d1a1]81                if( is_chat )
82                        jabber_chat_pkt_presence( ic, bud, node );
83                else if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) )
[17fa798]84                        imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,
85                                           ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,
86                                           bud->away_message );
[6a1128d]87        }
[4a0614e]88        else if( strcmp( type, "unavailable" ) == 0 )
[6a1128d]89        {
[e35d1a1]90                if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) == NULL )
[788a1af]91                {
[0da65d5]92                        if( set_getbool( &ic->irc->set, "debug" ) )
[84b045d]93                                imcb_log( ic, "WARNING: Received presence information from unknown JID: %s", from );
[788a1af]94                        return XT_HANDLED;
95                }
96               
[e35d1a1]97                /* Handle this before we delete the JID. */
98                if( is_chat )
99                {
100                        jabber_chat_pkt_presence( ic, bud, node );
101                }
102               
[0da65d5]103                jabber_buddy_remove( ic, from );
[6a1128d]104               
[e35d1a1]105                if( is_chat )
106                {
107                        /* Nothing else to do for now? */
108                }
109                else if( ( s = strchr( from, '/' ) ) )
[0d3f30f]110                {
111                        *s = 0;
[6a1128d]112               
[2758cfe]113                        /* If another resource is still available, send its presence
114                           information. */
115                        if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) )
116                        {
117                                if( bud->away_state && ( *bud->away_state->code == 0 ||
118                                    strcmp( bud->away_state->code, "chat" ) == 0 ) )
119                                        is_away = OPT_AWAY;
120                               
121                                imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,
122                                                   ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,
123                                                   bud->away_message );
124                        }
125                        else
126                        {
127                                /* Otherwise, count him/her as offline now. */
[6bbb939]128                                imcb_buddy_status( ic, from, 0, NULL, NULL );
[2758cfe]129                        }
[0d3f30f]130                       
131                        *s = '/';
132                }
133                else
134                {
[6bbb939]135                        imcb_buddy_status( ic, from, 0, NULL, NULL );
[0d3f30f]136                }
[6a1128d]137        }
[8e5e2e9]138        else if( strcmp( type, "subscribe" ) == 0 )
[6a1128d]139        {
[0da65d5]140                jabber_buddy_ask( ic, from );
[6a1128d]141        }
[8e5e2e9]142        else if( strcmp( type, "subscribed" ) == 0 )
[6a1128d]143        {
[0d3f30f]144                /* Not sure about this one, actually... */
[84b045d]145                imcb_log( ic, "%s just accepted your authorization request", from );
[6a1128d]146        }
[8e5e2e9]147        else if( strcmp( type, "unsubscribe" ) == 0 || strcmp( type, "unsubscribed" ) == 0 )
148        {
149                /* Do nothing here. Plenty of control freaks or over-curious
150                   souls get excited when they can see who still has them in
151                   their buddy list and who finally removed them. Somehow I
152                   got the impression that those are the people who get
153                   removed from many buddy lists for "some" reason...
154                   
155                   If you're one of those people, this is your chance to write
156                   your first line of code in C... */
157        }
[6266fca]158        else if( strcmp( type, "error" ) == 0 )
159        {
[1baaef8]160                struct jabber_error *err;
161               
162                if( ( c = xt_find_node( node->children, "error" ) ) )
163                {
164                        err = jabber_error_parse( c, XMLNS_STANZA_ERROR );
165                        imcb_error( ic, "Stanza (%s) error: %s%s%s", node->name,
166                                    err->code, err->text ? ": " : "",
167                                    err->text ? err->text : "" );
168                        jabber_error_free( err );
169                }
170                /* What else to do with it? */
[6266fca]171        }
[4a0614e]172       
[f06894d]173        return XT_HANDLED;
174}
175
[172a73f1]176/* Whenever presence information is updated, call this function to inform the
177   server. */
[0da65d5]178int presence_send_update( struct im_connection *ic )
[deff040]179{
[0da65d5]180        struct jabber_data *jd = ic->proto_data;
[deff040]181        struct xt_node *node;
[172a73f1]182        char *show = jd->away_state->code;
183        char *status = jd->away_message;
[2d317bb]184        struct groupchat *c;
[deff040]185        int st;
186       
[172a73f1]187        node = jabber_make_packet( "presence", NULL, NULL, NULL );
[0da65d5]188        xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) );
[5e202b0]189        if( show && *show )
[deff040]190                xt_add_child( node, xt_new_node( "show", show, NULL ) );
191        if( status )
192                xt_add_child( node, xt_new_node( "status", status, NULL ) );
193       
[0da65d5]194        st = jabber_write_packet( ic, node );
[deff040]195       
[2d317bb]196        /* Have to send this update to all groupchats too, the server won't
197           do this automatically. */
198        for( c = ic->groupchats; c && st; c = c->next )
199        {
200                struct jabber_chat *jc = c->data;
201               
[9c9b37c]202                xt_add_attr( node, "to", jc->my_full_jid );
[2d317bb]203                st = jabber_write_packet( ic, node );
204        }
205       
[deff040]206        xt_free_node( node );
207        return st;
208}
[cfbb3a6]209
210/* Send a subscribe/unsubscribe request to a buddy. */
[0da65d5]211int presence_send_request( struct im_connection *ic, char *handle, char *request )
[cfbb3a6]212{
213        struct xt_node *node;
214        int st;
215       
216        node = jabber_make_packet( "presence", NULL, NULL, NULL );
217        xt_add_attr( node, "to", handle );
218        xt_add_attr( node, "type", request );
219       
[0da65d5]220        st = jabber_write_packet( ic, node );
[cfbb3a6]221       
222        xt_free_node( node );
223        return st;
224}
Note: See TracBrowser for help on using the repository browser.