source: protocols/jabber/presence.c @ 9da0bbf

Last change on this file since 9da0bbf was 9c9b37c, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-07-01T19:58:23Z

Keeping an original (not normalized) copy of the user's nickname. This
fixes a bug reported by James Teh in the monster ticket #20. There's no
proper garbage collection yet in the Jabber conference code, really have
to do that soon. :-(

  • Property mode set to 100644
File size: 7.0 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_name( 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, GET_BUDDY_EXACT ) ) == 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                jabber_buddy_remove( ic, from );
104               
105                if( is_chat )
106                {
107                        /* Nothing else to do for now? */
108                }
109                else if( ( s = strchr( from, '/' ) ) )
110                {
111                        *s = 0;
112               
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. */
128                                imcb_buddy_status( ic, from, 0, NULL, NULL );
129                        }
130                       
131                        *s = '/';
132                }
133                else
134                {
135                        imcb_buddy_status( ic, from, 0, NULL, NULL );
136                }
137        }
138        else if( strcmp( type, "subscribe" ) == 0 )
139        {
140                jabber_buddy_ask( ic, from );
141        }
142        else if( strcmp( type, "subscribed" ) == 0 )
143        {
144                /* Not sure about this one, actually... */
145                imcb_log( ic, "%s just accepted your authorization request", from );
146        }
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        }
158        else if( strcmp( type, "error" ) == 0 )
159        {
160                /* What to do with it? */
161        }
162        else
163        {
164                printf( "Received PRES from %s:\n", from );
165                xt_print( node );
166        }
167       
168        return XT_HANDLED;
169}
170
171/* Whenever presence information is updated, call this function to inform the
172   server. */
173int presence_send_update( struct im_connection *ic )
174{
175        struct jabber_data *jd = ic->proto_data;
176        struct xt_node *node;
177        char *show = jd->away_state->code;
178        char *status = jd->away_message;
179        struct groupchat *c;
180        int st;
181       
182        node = jabber_make_packet( "presence", NULL, NULL, NULL );
183        xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) );
184        if( show && *show )
185                xt_add_child( node, xt_new_node( "show", show, NULL ) );
186        if( status )
187                xt_add_child( node, xt_new_node( "status", status, NULL ) );
188       
189        st = jabber_write_packet( ic, node );
190       
191        /* Have to send this update to all groupchats too, the server won't
192           do this automatically. */
193        for( c = ic->groupchats; c && st; c = c->next )
194        {
195                struct jabber_chat *jc = c->data;
196               
197                xt_add_attr( node, "to", jc->my_full_jid );
198                st = jabber_write_packet( ic, node );
199        }
200       
201        xt_free_node( node );
202        return st;
203}
204
205/* Send a subscribe/unsubscribe request to a buddy. */
206int presence_send_request( struct im_connection *ic, char *handle, char *request )
207{
208        struct xt_node *node;
209        int st;
210       
211        node = jabber_make_packet( "presence", NULL, NULL, NULL );
212        xt_add_attr( node, "to", handle );
213        xt_add_attr( node, "type", request );
214       
215        st = jabber_write_packet( ic, node );
216       
217        xt_free_node( node );
218        return st;
219}
Note: See TracBrowser for help on using the repository browser.