source: irc_im.c @ e00da63

Last change on this file since e00da63 was 17a6ee9, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-04-11T14:37:06Z

Including DCC stuff again, with a wonderful extra layer of abstraction.
Some hooks are missing so sending files doesn't work yet. Receiving also
still seems to have some issues. On the plus side, at least the MSN/Jabber
modules work again.

  • Property mode set to 100644
File size: 5.5 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/* Some glue to put the IRC and the IM stuff together.                  */
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#include "bitlbee.h"
27#include "dcc.h"
28
29/* IM->IRC callbacks */
30
31static const struct irc_user_funcs irc_user_im_funcs;
32
33static gboolean bee_irc_user_new( bee_t *bee, bee_user_t *bu )
34{
35        irc_user_t *iu;
36        char nick[MAX_NICK_LENGTH+1], *s;
37       
38        memset( nick, 0, MAX_NICK_LENGTH + 1 );
39        strcpy( nick, nick_get( bu->ic->acc, bu->handle ) );
40       
41        bu->ui_data = iu = irc_user_new( (irc_t*) bee->ui_data, nick );
42        iu->bu = bu;
43       
44        if( ( s = strchr( bu->handle, '@' ) ) )
45        {
46                iu->host = g_strdup( s + 1 );
47                iu->user = g_strndup( bu->handle, s - bu->handle );
48        }
49        else if( bu->ic->acc->server )
50        {
51                iu->host = g_strdup( bu->ic->acc->server );
52                iu->user = g_strdup( bu->handle );
53               
54                /* s/ /_/ ... important for AOL screennames */
55                for( s = iu->user; *s; s ++ )
56                        if( *s == ' ' )
57                                *s = '_';
58        }
59        else
60        {
61                iu->host = g_strdup( bu->ic->acc->prpl->name );
62                iu->user = g_strdup( bu->handle );
63        }
64       
65        if( set_getbool( &bee->set, "private" ) )
66                iu->flags |= IRC_USER_PRIVATE;
67       
68        iu->f = &irc_user_im_funcs;
69        //iu->last_typing_notice = 0;
70       
71        return TRUE;
72}
73
74static gboolean bee_irc_user_free( bee_t *bee, bee_user_t *bu )
75{
76        return irc_user_free( bee->ui_data, bu->ui_data );
77}
78
79static gboolean bee_irc_user_status( bee_t *bee, bee_user_t *bu, bee_user_t *old )
80{
81        irc_t *irc = bee->ui_data;
82        irc_channel_t *ic = irc->channels->data; /* For now, just pick the first channel. */
83       
84        if( ( bu->flags & BEE_USER_ONLINE ) != ( old->flags & BEE_USER_ONLINE ) )
85        {
86                if( bu->flags & BEE_USER_ONLINE )
87                        irc_channel_add_user( ic, (irc_user_t*) bu->ui_data );
88                else
89                        irc_channel_del_user( ic, (irc_user_t*) bu->ui_data );
90        }
91       
92        return TRUE;
93}
94
95static gboolean bee_irc_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, time_t sent_at )
96{
97        irc_t *irc = bee->ui_data;
98        irc_channel_t *ic = irc->channels->data;
99        irc_user_t *iu = (irc_user_t *) bu->ui_data;
100        char *dst, *prefix = NULL;
101        char *wrapped;
102       
103        if( iu->flags & IRC_USER_PRIVATE )
104        {
105                dst = irc->user->nick;
106        }
107        else
108        {
109                dst = ic->name;
110                prefix = g_strdup_printf( "%s%s", irc->user->nick, set_getstr( &bee->set, "to_char" ) );
111        }
112       
113        wrapped = word_wrap( msg, 425 );
114        irc_send_msg( iu, "PRIVMSG", dst, wrapped, prefix );
115       
116        g_free( wrapped );
117        g_free( prefix );
118       
119        return TRUE;
120}
121
122static gboolean bee_irc_user_fullname( bee_t *bee, bee_user_t *bu )
123{
124        irc_user_t *iu = (irc_user_t *) bu->ui_data;
125        irc_t *irc = (irc_t *) bee->ui_data;
126        char *s;
127       
128        if( iu->fullname != iu->nick )
129                g_free( iu->fullname );
130        iu->fullname = g_strdup( bu->fullname );
131       
132        /* Strip newlines (unlikely, but IRC-unfriendly so they must go)
133           TODO(wilmer): Do the same with away msgs again! */
134        for( s = iu->fullname; *s; s ++ )
135                if( isspace( *s ) ) *s = ' ';
136       
137        if( ( bu->ic->flags & OPT_LOGGED_IN ) && set_getbool( &bee->set, "display_namechanges" ) )
138        {
139                char *msg = g_strdup_printf( "<< \002BitlBee\002 - Changed name to `%s' >>", iu->fullname );
140                irc_send_msg( iu, "NOTICE", irc->user->nick, msg, NULL );
141        }
142       
143        s = set_getstr( &bu->ic->acc->set, "nick_source" );
144        if( strcmp( s, "handle" ) != 0 )
145        {
146                char *name = g_strdup( bu->fullname );
147               
148                if( strcmp( s, "first_name" ) == 0 )
149                {
150                        int i;
151                        for( i = 0; name[i] && !isspace( name[i] ); i ++ ) {}
152                        name[i] = '\0';
153                }
154               
155                imcb_buddy_nick_hint( bu->ic, bu->handle, name );
156               
157                g_free( name );
158        }
159       
160        return TRUE;
161}
162
163/* File transfers */
164static file_transfer_t *bee_irc_ft_in_start( bee_t *bee, bee_user_t *bu, const char *file_name, size_t file_size )
165{
166        return dccs_send_start( bu->ic, (irc_user_t *) bu->ui_data, file_name, file_size );
167}
168
169gboolean bee_irc_ft_out_start( struct im_connection *ic, file_transfer_t *ft )
170{
171        return dccs_recv_start( ft );
172}
173
174void bee_irc_ft_close( struct im_connection *ic, file_transfer_t *ft )
175{
176        return dcc_close( ft );
177}
178
179void bee_irc_ft_finished( struct im_connection *ic, file_transfer_t *file )
180{
181        dcc_file_transfer_t *df = file->priv;
182
183        if( file->bytes_transferred >= file->file_size )
184                dcc_finish( file );
185        else
186                df->proto_finished = TRUE;
187}
188
189const struct bee_ui_funcs irc_ui_funcs = {
190        bee_irc_user_new,
191        bee_irc_user_free,
192        bee_irc_user_fullname,
193        bee_irc_user_status,
194        bee_irc_user_msg,
195       
196        bee_irc_ft_in_start,
197        bee_irc_ft_out_start,
198        bee_irc_ft_close,
199        bee_irc_ft_finished,
200};
201
202
203/* IRC->IM calls */
204
205static gboolean bee_irc_user_privmsg( irc_user_t *iu, const char *msg )
206{
207        if( iu->bu )
208                return bee_user_msg( iu->irc->b, iu->bu, msg, 0 );
209        else
210                return FALSE;
211}
212
213static const struct irc_user_funcs irc_user_im_funcs = {
214        bee_irc_user_privmsg,
215};
Note: See TracBrowser for help on using the repository browser.