source: protocols/jabber/presence.c @ 0e7ab64

Last change on this file since 0e7ab64 was e35d1a1, checked in by Wilmer van der Gaast <wilmer@…>, at 2007-04-22T20:44:27Z

Read-only support for Jabber conferences (non-anonymous rooms only).
Just don't use this, you're really not going to like it. :-)

  • Property mode set to 100644
File size: 6.4 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        int st;
171       
172        node = jabber_make_packet( "presence", NULL, NULL, NULL );
173        xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) );
174        if( show && *show )
175                xt_add_child( node, xt_new_node( "show", show, NULL ) );
176        if( status )
177                xt_add_child( node, xt_new_node( "status", status, NULL ) );
178       
179        st = jabber_write_packet( ic, node );
180       
181        xt_free_node( node );
182        return st;
183}
184
185/* Send a subscribe/unsubscribe request to a buddy. */
186int presence_send_request( struct im_connection *ic, char *handle, char *request )
187{
188        struct xt_node *node;
189        int st;
190       
191        node = jabber_make_packet( "presence", NULL, NULL, NULL );
192        xt_add_attr( node, "to", handle );
193        xt_add_attr( node, "type", request );
194       
195        st = jabber_write_packet( ic, node );
196       
197        xt_free_node( node );
198        return st;
199}
Note: See TracBrowser for help on using the repository browser.