source: protocols/jabber/presence.c @ 3f2bc2d

Last change on this file since 3f2bc2d was 5bd21df, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-12-02T17:25:57Z

Handling of presence-error packets (only useful for groupchats now), moved
jabber_chat_by_jid() (with the right name) to conference.c, I don't know
what it was doing in jabber_util.c.

  • Property mode set to 100644
File size: 7.5 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, is_away = 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_jid( ic, from ) )
43                        is_chat = 1;
44                *s = '/';
45        }
46       
47        if( type == NULL )
48        {
49                if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) )
50                {
51                        if( set_getbool( &ic->irc->set, "debug" ) )
52                                imcb_log( ic, "WARNING: Could not handle presence information from JID: %s", from );
53                        return XT_HANDLED;
54                }
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 )
63                {
64                        bud->away_state = (void*) jabber_away_state_by_code( c->text );
65                        if( strcmp( c->text, "chat" ) != 0 )
66                                is_away = OPT_AWAY;
67                }
68                else
69                {
70                        bud->away_state = NULL;
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                }
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               
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 ) )
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 );
87        }
88        else if( strcmp( type, "unavailable" ) == 0 )
89        {
90                if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL )
91                {
92                        if( set_getbool( &ic->irc->set, "debug" ) )
93                                imcb_log( ic, "WARNING: Received presence information from unknown JID: %s", from );
94                        return XT_HANDLED;
95                }
96               
97                /* Handle this before we delete the JID. */
98                if( is_chat )
99                {
100                        jabber_chat_pkt_presence( ic, bud, node );
101                }
102               
103                if( strchr( from, '/' ) == NULL )
104                        /* Sometimes servers send a type="unavailable" from a
105                           bare JID, which should mean that suddenly all
106                           resources for this JID disappeared. */
107                        jabber_buddy_remove_bare( ic, from );
108                else
109                        jabber_buddy_remove( ic, from );
110               
111                if( is_chat )
112                {
113                        /* Nothing else to do for now? */
114                }
115                else if( ( s = strchr( from, '/' ) ) )
116                {
117                        *s = 0;
118               
119                        /* If another resource is still available, send its presence
120                           information. */
121                        if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) )
122                        {
123                                if( bud->away_state && ( *bud->away_state->code == 0 ||
124                                    strcmp( bud->away_state->code, "chat" ) == 0 ) )
125                                        is_away = OPT_AWAY;
126                               
127                                imcb_buddy_status( ic, bud->bare_jid, OPT_LOGGED_IN | is_away,
128                                                   ( is_away && bud->away_state ) ? bud->away_state->full_name : NULL,
129                                                   bud->away_message );
130                        }
131                        else
132                        {
133                                /* Otherwise, count him/her as offline now. */
134                                imcb_buddy_status( ic, from, 0, NULL, NULL );
135                        }
136                       
137                        *s = '/';
138                }
139                else
140                {
141                        imcb_buddy_status( ic, from, 0, NULL, NULL );
142                }
143        }
144        else if( strcmp( type, "subscribe" ) == 0 )
145        {
146                jabber_buddy_ask( ic, from );
147        }
148        else if( strcmp( type, "subscribed" ) == 0 )
149        {
150                /* Not sure about this one, actually... */
151                imcb_log( ic, "%s just accepted your authorization request", from );
152        }
153        else if( strcmp( type, "unsubscribe" ) == 0 || strcmp( type, "unsubscribed" ) == 0 )
154        {
155                /* Do nothing here. Plenty of control freaks or over-curious
156                   souls get excited when they can see who still has them in
157                   their buddy list and who finally removed them. Somehow I
158                   got the impression that those are the people who get
159                   removed from many buddy lists for "some" reason...
160                   
161                   If you're one of those people, this is your chance to write
162                   your first line of code in C... */
163        }
164        else if( strcmp( type, "error" ) == 0 )
165        {
166                return jabber_cache_handle_packet( ic, node );
167               
168                /*
169                struct jabber_error *err;
170                if( ( c = xt_find_node( node->children, "error" ) ) )
171                {
172                        err = jabber_error_parse( c, XMLNS_STANZA_ERROR );
173                        imcb_error( ic, "Stanza (%s) error: %s%s%s", node->name,
174                                    err->code, err->text ? ": " : "",
175                                    err->text ? err->text : "" );
176                        jabber_error_free( err );
177                } */
178        }
179       
180        return XT_HANDLED;
181}
182
183/* Whenever presence information is updated, call this function to inform the
184   server. */
185int presence_send_update( struct im_connection *ic )
186{
187        struct jabber_data *jd = ic->proto_data;
188        struct xt_node *node;
189        char *show = jd->away_state->code;
190        char *status = jd->away_message;
191        struct groupchat *c;
192        int st;
193       
194        node = jabber_make_packet( "presence", NULL, NULL, NULL );
195        xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) );
196        if( show && *show )
197                xt_add_child( node, xt_new_node( "show", show, NULL ) );
198        if( status )
199                xt_add_child( node, xt_new_node( "status", status, NULL ) );
200       
201        st = jabber_write_packet( ic, node );
202       
203        /* Have to send this update to all groupchats too, the server won't
204           do this automatically. */
205        for( c = ic->groupchats; c && st; c = c->next )
206        {
207                struct jabber_chat *jc = c->data;
208               
209                xt_add_attr( node, "to", jc->my_full_jid );
210                st = jabber_write_packet( ic, node );
211        }
212       
213        xt_free_node( node );
214        return st;
215}
216
217/* Send a subscribe/unsubscribe request to a buddy. */
218int presence_send_request( struct im_connection *ic, char *handle, char *request )
219{
220        struct xt_node *node;
221        int st;
222       
223        node = jabber_make_packet( "presence", NULL, NULL, NULL );
224        xt_add_attr( node, "to", handle );
225        xt_add_attr( node, "type", request );
226       
227        st = jabber_write_packet( ic, node );
228       
229        xt_free_node( node );
230        return st;
231}
Note: See TracBrowser for help on using the repository browser.