source: protocols/jabber/presence.c @ abbd8ed

Last change on this file since abbd8ed was 788a1af, checked in by Wilmer van der Gaast <wilmer@…>, at 2006-10-15T20:24:01Z

Proper cleanup of jabber buddy structures when removing a buddy from the
list, proper checking (and handling) of events related to buddies that
aren't "hashed" yet, limit checks on priorityto setting, renamed JEP85
to XEP85, support for more XEP85 states.

  • Property mode set to 100644
File size: 6.2 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 gaim_connection *gc = 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        char *s;
34       
35        if( !from )
36                return XT_HANDLED;
37       
38        if( type == NULL )
39        {
40                if( ( s = strchr( from, '/' ) ) == NULL )
41                {
42                        char *s = xt_to_string( node );
43                        serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s", s );
44                        g_free( s );
45                        return XT_HANDLED;
46                }
47               
48                if( !( bud = jabber_buddy_by_jid( gc, from ) ) )
49                {
50                        /* FOR NOW, s still contains the location of the /.
51                           Keep this in mind when changing things here. :-) */
52                       
53                        /* We check if the buddy is in the contact list,
54                           because Jabber servers seem to like to send
55                           presence information of buddies we removed
56                           from our list sometimes, for example... */
57                       
58                        *s = 0;
59                        if( find_buddy( gc, from ) == NULL )
60                        {
61                                *s = '/';
62                                serv_got_crap( gc, "WARNING: Ignoring presence information from unknown JID: %s", from );
63                                return XT_HANDLED;
64                        }
65                        *s = '/';
66                       
67                        bud = jabber_buddy_add( gc, from );
68                }
69               
70                g_free( bud->away_message );
71                if( ( c = xt_find_node( node->children, "status" ) ) && c->text_len > 0 )
72                        bud->away_message = g_strdup( c->text );
73                else
74                        bud->away_message = NULL;
75               
76                if( ( c = xt_find_node( node->children, "show" ) ) && c->text_len > 0 )
77                        bud->away_state = (void*) jabber_away_state_by_code( c->text );
78                else
79                {
80                        bud->away_state = NULL;
81                        /* Let's only set last_act if there's *no* away state,
82                           since it could be some auto-away thingy. */
83                        bud->last_act = time( NULL );
84                }
85               
86                if( ( c = xt_find_node( node->children, "priority" ) ) && c->text_len > 0 )
87                        bud->priority = atoi( c->text );
88                else
89                        bud->priority = 0;
90               
91                serv_got_update( gc, bud->handle, 1, 0, 0, 0,
92                                 bud->away_state ? UC_UNAVAILABLE : 0, 0 );
93        }
94        else if( strcmp( type, "unavailable" ) == 0 )
95        {
96                char *s;
97               
98                if( ( s = strchr( from, '/' ) ) == NULL )
99                {
100                        char *s = xt_to_string( node );
101                        serv_got_crap( gc, "WARNING: Ignoring presence tag with bare JID: %s\n", s );
102                        g_free( s );
103                        return XT_HANDLED;
104                }
105               
106                if( jabber_buddy_by_jid( gc, from ) == NULL )
107                {
108                        serv_got_crap( gc, "WARNING: Received presence information from unknown JID: %s", from );
109                        return XT_HANDLED;
110                }
111               
112                jabber_buddy_remove( gc, from );
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( gc, from ) == NULL )
118                        serv_got_update( gc, from, 0, 0, 0, 0, 0, 0 );
119               
120                *s = '/';
121        }
122        else if( strcmp( type, "subscribe" ) == 0 )
123        {
124                jabber_buddy_ask( gc, from );
125        }
126        else if( strcmp( type, "subscribed" ) == 0 )
127        {
128                serv_got_crap( gc, "%s just accepted your authorization request", from );
129        }
130        else if( strcmp( type, "unsubscribe" ) == 0 || strcmp( type, "unsubscribed" ) == 0 )
131        {
132                /* Do nothing here. Plenty of control freaks or over-curious
133                   souls get excited when they can see who still has them in
134                   their buddy list and who finally removed them. Somehow I
135                   got the impression that those are the people who get
136                   removed from many buddy lists for "some" reason...
137                   
138                   If you're one of those people, this is your chance to write
139                   your first line of code in C... */
140        }
141        else if( strcmp( type, "error" ) == 0 )
142        {
143                /* What to do with it? */
144        }
145        else
146        {
147                printf( "Received PRES from %s:\n", from );
148                xt_print( node );
149        }
150       
151        return XT_HANDLED;
152}
153
154/* Whenever presence information is updated, call this function to inform the
155   server. */
156int presence_send_update( struct gaim_connection *gc )
157{
158        struct jabber_data *jd = gc->proto_data;
159        struct xt_node *node;
160        char *show = jd->away_state->code;
161        char *status = jd->away_message;
162        int st;
163       
164        node = jabber_make_packet( "presence", NULL, NULL, NULL );
165        xt_add_child( node, xt_new_node( "priority", set_getstr( &gc->acc->set, "priority" ), NULL ) );
166        if( show && *show )
167                xt_add_child( node, xt_new_node( "show", show, NULL ) );
168        if( status )
169                xt_add_child( node, xt_new_node( "status", status, NULL ) );
170       
171        st = jabber_write_packet( gc, node );
172       
173        xt_free_node( node );
174        return st;
175}
176
177/* Send a subscribe/unsubscribe request to a buddy. */
178int presence_send_request( struct gaim_connection *gc, char *handle, char *request )
179{
180        struct xt_node *node;
181        int st;
182       
183        node = jabber_make_packet( "presence", NULL, NULL, NULL );
184        xt_add_attr( node, "to", handle );
185        xt_add_attr( node, "type", request );
186       
187        st = jabber_write_packet( gc, node );
188       
189        xt_free_node( node );
190        return st;
191}
Note: See TracBrowser for help on using the repository browser.