source: protocols/bee_user.c @ 51e9a1d

Last change on this file since 51e9a1d was 934db064, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-09-01T22:09:27Z

Do encryption and decryption. Somehow SMP and other things aren't working
so well yet, at least when testing with Pidgin on the other side. Not sure
where the bug is.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* Stuff to handle, save and search buddies                             */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#define BITLBEE_CORE
27#include "bitlbee.h"
28
29bee_user_t *bee_user_new( bee_t *bee, struct im_connection *ic, const char *handle, bee_user_flags_t flags )
30{
31        bee_user_t *bu;
32       
33        if( bee_user_by_handle( bee, ic, handle ) != NULL )
34                return NULL;
35       
36        bu = g_new0( bee_user_t, 1 );
37        bu->bee = bee;
38        bu->ic = ic;
39        bu->flags = flags;
40        bu->handle = g_strdup( handle );
41        bee->users = g_slist_prepend( bee->users, bu );
42       
43        if( bee->ui->user_new )
44                bee->ui->user_new( bee, bu );
45        if( ic->acc->prpl->buddy_data_add )
46                ic->acc->prpl->buddy_data_add( bu );
47       
48        /* Offline by default. This will set the right flags. */
49        imcb_buddy_status( ic, handle, 0, NULL, NULL );
50       
51        return bu;
52}
53
54int bee_user_free( bee_t *bee, bee_user_t *bu )
55{
56        if( !bu )
57                return 0;
58       
59        if( bee->ui->user_free )
60                bee->ui->user_free( bee, bu );
61        if( bu->ic->acc->prpl->buddy_data_free )
62                bu->ic->acc->prpl->buddy_data_free( bu );
63       
64        g_free( bu->handle );
65        g_free( bu->fullname );
66        g_free( bu->nick );
67        g_free( bu->status );
68        g_free( bu->status_msg );
69        g_free( bu );
70       
71        bee->users = g_slist_remove( bee->users, bu );
72       
73        return 1;
74}
75
76bee_user_t *bee_user_by_handle( bee_t *bee, struct im_connection *ic, const char *handle )
77{
78        GSList *l;
79       
80        for( l = bee->users; l; l = l->next )
81        {
82                bee_user_t *bu = l->data;
83               
84                if( bu->ic == ic && ic->acc->prpl->handle_cmp( bu->handle, handle ) == 0 )
85                        return bu;
86        }
87       
88        return NULL;
89}
90
91int bee_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, int flags )
92{
93        char *buf = NULL;
94        int st;
95       
96        if( ( bu->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
97        {
98                buf = escape_html( msg );
99                msg = buf;
100        }
101        else
102                buf = g_strdup( msg );
103       
104        st = bu->ic->acc->prpl->buddy_msg( bu->ic, bu->handle, buf, flags );
105        g_free( buf );
106       
107        return st;
108}
109
110
111/* Groups */
112static bee_group_t *bee_group_new( bee_t *bee, const char *name )
113{
114        bee_group_t *bg = g_new0( bee_group_t, 1 );
115       
116        bg->name = g_strdup( name );
117        bg->key = g_utf8_casefold( name, -1 );
118        bee->groups = g_slist_prepend( bee->groups, bg );
119       
120        return bg;
121}
122
123bee_group_t *bee_group_by_name( bee_t *bee, const char *name, gboolean creat )
124{
125        GSList *l;
126        char *key;
127       
128        if( name == NULL )
129                return NULL;
130       
131        key = g_utf8_casefold( name, -1 );
132        for( l = bee->groups; l; l = l->next )
133        {
134                bee_group_t *bg = l->data;
135                if( strcmp( bg->key, key ) == 0 )
136                        break;
137        }
138        g_free( key );
139       
140        if( !l )
141                return creat ? bee_group_new( bee, name ) : NULL;
142        else
143                return l->data;
144}
145
146void bee_group_free( bee_t *bee )
147{
148        while( bee->groups )
149        {
150                bee_group_t *bg = bee->groups->data;
151                g_free( bg->name );
152                g_free( bg->key );
153                g_free( bg );
154                bee->groups = g_slist_remove( bee->groups, bee->groups->data );
155        }
156}
157
158
159/* IM->UI callbacks */
160void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message )
161{
162        bee_t *bee = ic->bee;
163        bee_user_t *bu, *old;
164       
165        if( !( bu = bee_user_by_handle( bee, ic, handle ) ) )
166        {
167                if( g_strcasecmp( set_getstr( &ic->bee->set, "handle_unknown" ), "add" ) == 0 )
168                {
169                        bu = bee_user_new( bee, ic, handle, BEE_USER_LOCAL );
170                }
171                else
172                {
173                        if( g_strcasecmp( set_getstr( &ic->bee->set, "handle_unknown" ), "ignore" ) != 0 )
174                        {
175                                imcb_log( ic, "imcb_buddy_status() for unknown handle %s:\n"
176                                              "flags = %d, state = %s, message = %s", handle, flags,
177                                              state ? state : "NULL", message ? message : "NULL" );
178                        }
179                       
180                        return;
181                }
182        }
183       
184        /* May be nice to give the UI something to compare against. */
185        old = g_memdup( bu, sizeof( bee_user_t ) );
186       
187        /* TODO(wilmer): OPT_AWAY, or just state == NULL ? */
188        bu->flags = flags;
189        bu->status = g_strdup( ( flags & OPT_AWAY ) && state == NULL ? "Away" : state );
190        bu->status_msg = g_strdup( message );
191       
192        if( bu->status == NULL && ( flags & OPT_MOBILE ) &&
193            set_getbool( &bee->set, "mobile_is_away" ) )
194        {
195                bu->flags |= BEE_USER_AWAY;
196                bu->status = g_strdup( "Mobile" );
197        }
198       
199        if( bee->ui->user_status )
200                bee->ui->user_status( bee, bu, old );
201       
202        g_free( old->status_msg );
203        g_free( old->status );
204        g_free( old );
205}
206
207void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle )
208{
209        bee_t *bee = ic->bee;
210        bee_user_t *bu;
211       
212        if( !( bu = bee_user_by_handle( bee, ic, handle ) ) )
213                return;
214       
215        bu->login_time = login;
216        bu->idle_time = idle;
217}
218
219void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at )
220{
221        bee_t *bee = ic->bee;
222        bee_user_t *bu;
223       
224        bu = bee_user_by_handle( bee, ic, handle );
225       
226        if( !bu )
227        {
228                char *h = set_getstr( &bee->set, "handle_unknown" );
229               
230                if( g_strcasecmp( h, "ignore" ) == 0 )
231                {
232                        return;
233                }
234                else if( g_strncasecmp( h, "add", 3 ) == 0 )
235                {
236                        bu = bee_user_new( bee, ic, handle, BEE_USER_LOCAL );
237                }
238        }
239       
240        if( bee->ui->user_msg && bu )
241                bee->ui->user_msg( bee, bu, msg, sent_at );
242        else
243                imcb_log( ic, "Message from unknown handle %s:\n%s", handle, msg );
244}
245
246void imcb_buddy_typing( struct im_connection *ic, const char *handle, uint32_t flags )
247{
248        bee_user_t *bu;
249       
250        if( ic->bee->ui->user_typing &&
251            ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) )
252        {
253                ic->bee->ui->user_typing( ic->bee, bu, flags );
254        }
255}
Note: See TracBrowser for help on using the repository browser.