source: irc_channel.c @ aea8b68

Last change on this file since aea8b68 was 9438323, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-05-04T23:38:18Z

Use irc_channel_name_ok() and check if a channel with that name already
exists before creating it.

  • Property mode set to 100644
File size: 5.9 KB
RevLine 
[4be8239]1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* The IRC-based UI - Representing (virtual) channels.                  */
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
[e54112f]28static gint irc_channel_user_cmp( gconstpointer a_, gconstpointer b_ );
[280c56a]29static const struct irc_channel_funcs control_channel_funcs;
30
[4be8239]31irc_channel_t *irc_channel_new( irc_t *irc, const char *name )
32{
33        irc_channel_t *ic;
34       
[9438323]35        if( !irc_channel_name_ok( name ) || irc_channel_by_name( irc, name ) )
[4be8239]36                return NULL;
37       
38        ic = g_new0( irc_channel_t, 1 );
[280c56a]39        ic->f = &control_channel_funcs;
[4be8239]40        ic->irc = irc;
41        ic->name = g_strdup( name );
42        strcpy( ic->mode, CMODE );
43       
44        irc_channel_add_user( ic, irc->root );
[6a9d068]45        if( strcmp( set_getstr( &irc->b->set, "ops" ), "both" ) == 0 ||
46            strcmp( set_getstr( &irc->b->set, "ops" ), "root" ) == 0 )
47                irc_channel_user_set_mode( ic, irc->root, IRC_CHANNEL_USER_OP );
[4be8239]48       
49        irc->channels = g_slist_prepend( irc->channels, ic );
50       
51        return ic;
52}
53
[b9e020a]54irc_channel_t *irc_channel_by_name( irc_t *irc, const char *name )
55{
56        GSList *l;
57       
58        for( l = irc->channels; l; l = l->next )
59        {
60                irc_channel_t *ic = l->data;
61               
62                if( name[0] == ic->name[0] && nick_cmp( name + 1, ic->name + 1 ) == 0 )
63                        return ic;
64        }
65       
66        return NULL;
67}
68
[63a520b]69int irc_channel_free( irc_channel_t *ic )
70{
71        irc_t *irc = ic->irc;
72       
73        if( ic->flags & IRC_CHANNEL_JOINED )
74                irc_channel_del_user( ic, irc->user );
75       
76        irc->channels = g_slist_remove( irc->channels, ic );
[e54112f]77        while( ic->users )
78        {
79                g_free( ic->users->data );
80                ic->users = g_slist_remove( ic->users, ic->users->data );
81        }
[63a520b]82       
83        g_free( ic->name );
84        g_free( ic->topic );
85        g_free( ic );
86       
87        return 1;
88}
89
[4be8239]90int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu )
91{
[e54112f]92        irc_channel_user_t *icu;
93       
[57c96f7]94        if( irc_channel_has_user( ic, iu ) )
[4be8239]95                return 0;
96       
[e54112f]97        icu = g_new0( irc_channel_user_t, 1 );
98        icu->iu = iu;
99       
100        ic->users = g_slist_insert_sorted( ic->users, icu, irc_channel_user_cmp );
[4be8239]101       
102        if( iu == ic->irc->user || ic->flags & IRC_CHANNEL_JOINED )
103        {
104                ic->flags |= IRC_CHANNEL_JOINED;
105                irc_send_join( ic, iu );
106        }
107       
108        return 1;
109}
110
111int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu )
112{
[e54112f]113        irc_channel_user_t *icu;
114       
115        if( !( icu = irc_channel_has_user( ic, iu ) ) )
[4be8239]116                return 0;
117       
[e54112f]118        ic->users = g_slist_remove( ic->users, icu );
119        g_free( icu );
[4be8239]120       
121        if( ic->flags & IRC_CHANNEL_JOINED )
122                irc_send_part( ic, iu, "" );
123       
124        if( iu == ic->irc->user )
125                ic->flags &= ~IRC_CHANNEL_JOINED;
126       
127        return 1;
128}
129
[e54112f]130irc_channel_user_t *irc_channel_has_user( irc_channel_t *ic, irc_user_t *iu )
[0b5cc72]131{
[e54112f]132        GSList *l;
133       
134        for( l = ic->users; l; l = l->next )
135        {
136                irc_channel_user_t *icu = l->data;
137               
138                if( icu->iu == iu )
139                        return icu;
140        }
141       
142        return NULL;
[0b5cc72]143}
144
[83e92bf]145int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *iu )
[4be8239]146{
147        g_free( ic->topic );
148        ic->topic = g_strdup( topic );
149       
[83e92bf]150        g_free( ic->topic_who );
151        if( iu )
152                ic->topic_who = g_strdup_printf( "%s!%s@%s", iu->nick, iu->user, iu->host );
153        else
154                ic->topic_who = NULL;
155       
156        ic->topic_time = time( NULL );
157       
[4be8239]158        if( ic->flags & IRC_CHANNEL_JOINED )
[83e92bf]159                irc_send_topic( ic, TRUE );
[4be8239]160       
161        return 1;
162}
[b919363]163
[6a9d068]164void irc_channel_user_set_mode( irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags )
165{
166        irc_channel_user_t *icu = irc_channel_has_user( ic, iu );
167       
168        if( icu->flags == flags )
169                return;
170       
171        if( ic->flags & IRC_CHANNEL_JOINED )
172                irc_send_channel_user_mode_diff( ic, iu, icu->flags, flags );
173       
174        icu->flags = flags;
175}
176
[9893da3]177void irc_channel_printf( irc_channel_t *ic, char *format, ... )
178{
179        va_list params;
180        char *text;
181       
182        va_start( params, format );
183        text = g_strdup_vprintf( format, params );
184        va_end( params );
185       
186        irc_send_msg( ic->irc->root, "PRIVMSG", ic->name, text, NULL );
187        g_free( text );
188}
189
[b919363]190gboolean irc_channel_name_ok( const char *name )
191{
192        return strchr( CTYPES, name[0] ) != NULL && nick_ok( name + 1 );
193}
[280c56a]194
[e54112f]195static gint irc_channel_user_cmp( gconstpointer a_, gconstpointer b_ )
196{
197        const irc_channel_user_t *a = a_, *b = b_;
198       
199        return irc_user_cmp( a->iu, b->iu );
200}
201
[280c56a]202/* Channel-type dependent functions, for control channels: */
203static gboolean control_channel_privmsg( irc_channel_t *ic, const char *msg )
204{
[bce78c8]205        irc_t *irc = ic->irc;
206        const char *s;
[fb117aee]207       
[bce78c8]208        /* Scan for non-whitespace chars followed by a colon: */
209        for( s = msg; *s && !isspace( *s ) && *s != ':'; s ++ ) {}
[74f1cde]210       
[bce78c8]211        if( *s == ':' )
212        {
213                char to[s-msg+1];
214                irc_user_t *iu;
215               
[1a3ba05]216                memset( to, 0, sizeof( to ) );
[bce78c8]217                strncpy( to, msg, s - msg );
218                while( *(++s) && isspace( *s ) ) {}
219               
220                iu = irc_user_by_name( irc, to );
221                if( iu && iu->f->privmsg )
222                {
223                        iu->flags &= ~IRC_USER_PRIVATE;
224                        iu->f->privmsg( iu, s );
225                }
[1a3ba05]226                else
227                {
[9893da3]228                        irc_channel_printf( ic, "User does not exist: %s", to );
[1a3ba05]229                }
[bce78c8]230        }
231        else
232        {
233                /* TODO: Maybe just use root->privmsg here now? */
234                char cmd[strlen(msg)+1];
235               
236                g_free( ic->irc->last_root_cmd );
237                ic->irc->last_root_cmd = g_strdup( ic->name );
238               
239                strcpy( cmd, msg );
240                root_command_string( ic->irc, cmd );
241        }
[280c56a]242       
243        return TRUE;
244}
245
246static const struct irc_channel_funcs control_channel_funcs = {
247        control_channel_privmsg,
248};
Note: See TracBrowser for help on using the repository browser.