source: protocols/jabber/presence.c @ 998b103

Last change on this file since 998b103 was 2d317bb, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-04-23T05:18:47Z

Fixes: handling of being kicked, now sending <presence/> tags to all
conferences the user's in.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/***************************************************************************\
2*                                                                           *
3*  BitlBee - An IRC to IM gateway                                           *
4*  Jabber module - Handling of presence (tags), etc                         *
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{
28        struct im_connection *ic = data;
29        char *from = xt_find_attr( node, "from" );
30        char *type = xt_find_attr( node, "type" );      /* NULL should mean the person is online. */
31        struct xt_node *c;
32        struct jabber_buddy *bud;
33        int is_chat = 0;
34        char *s;
35       
36        if( !from )
37                return XT_HANDLED;
38       
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       
47        if( type == NULL )
48        {
49                int is_away = 0;
50               
51                if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
52                {
53                        if( set_getbool( &ic->irc->set, "debug" ) )
54                                imcb_log( ic, "WARNING: Could not handle presence information from JID: %s", from );
55                        return XT_HANDLED;
56                }
57               
58                g_free( bud->away_message );
59                if( ( c = xt_find_node( node->children, "status" ) ) && c->text_len > 0 )
60                        bud->away_message = g_strdup( c->text );
61                else
62                        bud->away_message = NULL;
63               
64                if( ( c = xt_find_node( node->children, "show" ) ) && c->text_len > 0 )
65                {
66                        bud->away_state = (void*) jabber_away_state_by_code( c->text );
67                        if( strcmp( c->text, "chat" ) != 0 )
68                                is_away = OPT_AWAY;
69                }
70                else
71                {
72                        bud->away_state = NULL;
73                        /* Let's only set last_act if there's *no* away state,
74                           since it could be some auto-away thingy. */
75                        bud->last_act = time( NULL );
76                }
77               
78                if( ( c = xt_find_node( node->children, "priority" ) ) && c->text_len > 0 )
79                        bud->priority = atoi( c->text );
80                else
81                        bud->priority = 0;
82               
83                if( is_chat )
84                        jabber_chat_pkt_presence( ic, bud, node );
85                else if( bud == jabber_buddy_by_jid( ic, bud->bare_jid, 0 ) )
86                        imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,
87                                           ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,
88                                           bud->away_message );
89        }
90        else if( strcmp( type, "unavailable" ) == 0 )
91        {
92                if( ( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT ) ) == NULL )
93                {
94                        if( set_getbool( &ic->irc->set, "debug" ) )
95                                imcb_log( ic, "WARNING: Received presence information from unknown JID: %s", from );
96                        return XT_HANDLED;
97                }
98               
99                /* Handle this before we delete the JID. */
100                if( is_chat )
101                {
102                        jabber_chat_pkt_presence( ic, bud, node );
103                }
104               
105                jabber_buddy_remove( ic, from );
106               
107                if( is_chat )
108                {
109                        /* Nothing else to do for now? */
110                }
111                else if( ( s = strchr( from, '/' ) ) )
112                {
113                        *s = 0;
114               
115                        /* Only count this as offline if there's no other resource
116                           available anymore. */
117                        if( jabber_buddy_by_jid( ic, from, 0 ) == NULL )
118                                imcb_buddy_status( ic, from, 0, NULL, NULL );
119                        /* FIXME: If this resource was not away and another resource is,
120                           we should definitely send an update here. */
121                       
122                        *s = '/';
123                }
124                else
125                {
126                        imcb_buddy_status( ic, from, 0, NULL, NULL );
127                }
128        }
129        else if( strcmp( type, "subscribe" ) == 0 )
130        {
131                jabber_buddy_ask( ic, from );
132        }
133        else if( strcmp( type, "subscribed" ) == 0 )
134        {
135                /* Not sure about this one, actually... */
136                imcb_log( ic, "%s just accepted your authorization request", from );
137        }
138        else if( strcmp( type, "unsubscribe" ) == 0 || strcmp( type, "unsubscribed" ) == 0 )
139        {
140                /* Do nothing here. Plenty of control freaks or over-curious
141                   souls get excited when they can see who still has them in
142                   their buddy list and who finally removed them. Somehow I
143                   got the impression that those are the people who get
144                   removed from many buddy lists for "some" reason...
145                   
146                   If you're one of those people, this is your chance to write
147                   your first line of code in C... */
148        }
149        else if( strcmp( type, "error" ) == 0 )
150        {
151                /* What to do with it? */
152        }
153        else
154        {
155                printf( "Received PRES from %s:\n", from );
156                xt_print( node );
157        }
158       
159        return XT_HANDLED;
160}
161
162/* Whenever presence information is updated, call this function to inform the
163   server. */
164int presence_send_update( struct im_connection *ic )
165{
166        struct jabber_data *jd = ic->proto_data;
167        struct xt_node *node;
168        char *show = jd->away_state->code;
169        char *status = jd->away_message;
170        struct groupchat *c;
171        int st;
172       
173        node = jabber_make_packet( "presence", NULL, NULL, NULL );
174        xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) );
175        if( show && *show )
176                xt_add_child( node, xt_new_node( "show", show, NULL ) );
177        if( status )
178                xt_add_child( node, xt_new_node( "status", status, NULL ) );
179       
180        st = jabber_write_packet( ic, node );
181       
182        /* Have to send this update to all groupchats too, the server won't
183           do this automatically. */
184        for( c = ic->groupchats; c && st; c = c->next )
185        {
186                struct jabber_chat *jc = c->data;
187               
188                xt_add_attr( node, "to", jc->me->full_jid );
189                st = jabber_write_packet( ic, node );
190        }
191       
192        xt_free_node( node );
193        return st;
194}
195
196/* Send a subscribe/unsubscribe request to a buddy. */
197int presence_send_request( struct im_connection *ic, char *handle, char *request )
198{
199        struct xt_node *node;
200        int st;
201       
202        node = jabber_make_packet( "presence", NULL, NULL, NULL );
203        xt_add_attr( node, "to", handle );
204        xt_add_attr( node, "type", request );
205       
206        st = jabber_write_packet( ic, node );
207       
208        xt_free_node( node );
209        return st;
210}
Note: See TracBrowser for help on using the repository browser.