X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Fchannel.c;h=3c740ff0d406b94e9fe438fbb93d900157eec941;hb=ff2c1efae8b8b1bf30013123bb17243dc682f7d3;hp=e314fd9ffaf3648af078344a1f583f8bf6481992;hpb=adcd9289c2a2ca3472fe42541b223bbe689fac8e;p=ngircd-alex.git diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index e314fd9f..3c740ff0 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -2,16 +2,13 @@ * ngIRCd -- The Next Generation IRC Daemon * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) * - * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen - * der GNU General Public License (GPL), wie von der Free Software Foundation - * herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2 - * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version. - * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste - * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: channel.c,v 1.31 2002/09/02 18:23:35 alex Exp $ - * - * channel.c: Management der Channels + * Channel management */ @@ -20,12 +17,14 @@ #include "portab.h" +static char UNUSED id[] = "$Id: channel.c,v 1.43 2003/11/06 01:07:44 alex Exp $"; + #include "imp.h" #include #include #include -#include "conn.h" +#include "conn-func.h" #include "client.h" #include "exp.h" @@ -52,7 +51,6 @@ LOCAL CHANNEL *My_Channels; LOCAL CL2CHAN *My_Cl2Chan; -LOCAL CHANNEL *New_Chan PARAMS(( CHAR *Name )); LOCAL CL2CHAN *Get_Cl2Chan PARAMS(( CHANNEL *Chan, CLIENT *Client )); LOCAL CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client )); LOCAL BOOLEAN Remove_Client PARAMS(( INT Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, CHAR *Reason, BOOLEAN InformServer )); @@ -89,14 +87,19 @@ Channel_InitPredefined( VOID ) Log( LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"!", Conf_Channel[i].name ); continue; } + + /* Gibt es den Channel bereits? */ + chan = Channel_Search( Conf_Channel[i].name ); + if( chan ) + { + Log( LOG_INFO, "Can't create pre-defined channel \"%s\": name already in use.", Conf_Channel[i].name ); + continue; + } /* Channel anlegen */ - chan = New_Chan( Conf_Channel[i].name ); + chan = Channel_Create( Conf_Channel[i].name ); if( chan ) { - /* Verketten */ - chan->next = My_Channels; - My_Channels = chan; Channel_ModeAdd( chan, 'P' ); Channel_SetTopic( chan, Conf_Channel[i].topic ); c = Conf_Channel[i].modes; @@ -159,12 +162,8 @@ Channel_Join( CLIENT *Client, CHAR *Name ) else { /* Gibt es noch nicht? Dann neu anlegen: */ - chan = New_Chan( Name ); + chan = Channel_Create( Name ); if( ! chan ) return FALSE; - - /* Verketten */ - chan->next = My_Channels; - My_Channels = chan; } /* User dem Channel hinzufuegen */ @@ -257,11 +256,11 @@ Channel_Quit( CLIENT *Client, CHAR *Reason ) } /* Channel_Quit */ -GLOBAL INT +GLOBAL LONG Channel_Count( VOID ) { CHANNEL *c; - INT count; + LONG count; count = 0; c = My_Channels; @@ -274,11 +273,11 @@ Channel_Count( VOID ) } /* Channel_Count */ -GLOBAL INT +GLOBAL LONG Channel_MemberCount( CHANNEL *Chan ) { CL2CHAN *cl2chan; - INT count; + LONG count; assert( Chan != NULL ); @@ -293,6 +292,48 @@ Channel_MemberCount( CHANNEL *Chan ) } /* Channel_MemberCount */ +GLOBAL INT +Channel_CountForUser( CLIENT *Client ) +{ + /* Count number of channels a user is member of. */ + + CL2CHAN *cl2chan; + INT count; + + assert( Client != NULL ); + + count = 0; + cl2chan = My_Cl2Chan; + while( cl2chan ) + { + if( cl2chan->client == Client ) count++; + cl2chan = cl2chan->next; + } + + return count; +} /* Channel_CountForUser */ + + +GLOBAL INT +Channel_PCount( VOID ) +{ + /* Count the number of persistent (mode 'P') channels */ + + CHANNEL *chan; + INT count; + + count = 0; + chan = My_Channels; + while( chan ) + { + if( strchr( chan->modes, 'P' )) count++; + chan = chan->next; + } + + return count; +} /* Channel_PCount */ + + GLOBAL CHAR * Channel_Name( CHANNEL *Chan ) { @@ -309,6 +350,22 @@ Channel_Modes( CHANNEL *Chan ) } /* Channel_Modes */ +GLOBAL CHAR * +Channel_Key( CHANNEL *Chan ) +{ + assert( Chan != NULL ); + return Chan->key; +} /* Channel_Key */ + + +GLOBAL LONG +Channel_MaxUsers( CHANNEL *Chan ) +{ + assert( Chan != NULL ); + return Chan->maxusers; +} /* Channel_MaxUsers */ + + GLOBAL CHANNEL * Channel_First( VOID ) { @@ -411,7 +468,7 @@ Channel_IsValidName( CHAR *Name ) if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return FALSE; ptr = Name; - strcpy( badchars, " ,:\x07" ); + strcpy( badchars, " ,:\007" ); while( *ptr ) { if( strchr( badchars, *ptr )) return FALSE; @@ -437,7 +494,7 @@ Channel_ModeAdd( CHANNEL *Chan, CHAR Mode ) if( ! strchr( Chan->modes, x[0] )) { /* Client hat den Mode noch nicht -> setzen */ - strcat( Chan->modes, x ); + strlcat( Chan->modes, x, sizeof( Chan->modes )); return TRUE; } else return FALSE; @@ -490,7 +547,7 @@ Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, CHAR Mode ) if( ! strchr( cl2chan->modes, x[0] )) { /* Client hat den Mode noch nicht -> setzen */ - strcat( cl2chan->modes, x ); + strlcat( cl2chan->modes, x, sizeof( cl2chan->modes )); return TRUE; } else return FALSE; @@ -572,17 +629,47 @@ Channel_SetTopic( CHANNEL *Chan, CHAR *Topic ) assert( Chan != NULL ); assert( Topic != NULL ); - strncpy( Chan->topic, Topic, CHANNEL_TOPIC_LEN - 1 ); - Chan->topic[CHANNEL_TOPIC_LEN - 1] = '\0'; + strlcpy( Chan->topic, Topic, sizeof( Chan->topic )); } /* Channel_SetTopic */ +GLOBAL VOID +Channel_SetModes( CHANNEL *Chan, CHAR *Modes ) +{ + assert( Chan != NULL ); + assert( Modes != NULL ); + + strlcpy( Chan->modes, Modes, sizeof( Chan->modes )); +} /* Channel_SetModes */ + + +GLOBAL VOID +Channel_SetKey( CHANNEL *Chan, CHAR *Key ) +{ + assert( Chan != NULL ); + assert( Key != NULL ); + + strlcpy( Chan->key, Key, sizeof( Chan->key )); + Log( LOG_DEBUG, "Channel %s: Key is now \"%s\".", Chan->name, Chan->key ); +} /* Channel_SetKey */ + + +GLOBAL VOID +Channel_SetMaxUsers( CHANNEL *Chan, LONG Count ) +{ + assert( Chan != NULL ); + + Chan->maxusers = Count; + Log( LOG_DEBUG, "Channel %s: Member limit is now %ld.", Chan->name, Chan->maxusers ); +} /* Channel_SetMaxUsers */ + + GLOBAL BOOLEAN Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, CHAR *Text ) { BOOLEAN is_member, has_voice, is_op, ok; - /* Okay, Ziel ist ein Channel */ + /* Okay, target is a channel */ is_member = has_voice = is_op = FALSE; if( Channel_IsMemberOf( Chan, From )) { @@ -591,22 +678,28 @@ Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, CHAR *Text ) if( strchr( Channel_UserModes( Chan, From ), 'o' )) is_op = TRUE; } - /* pruefen, ob Client in Channel schreiben darf */ + /* Check weather client is allowed to write to channel */ ok = TRUE; if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = FALSE; if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = FALSE; + + /* Is the client banned? */ + if( Lists_CheckBanned( From, Chan )) + { + /* Client is banned, bus is he channel operator or has voice? */ + if(( ! has_voice ) && ( ! is_op )) ok = FALSE; + } if( ! ok ) return IRC_WriteStrClient( From, ERR_CANNOTSENDTOCHAN_MSG, Client_ID( From ), Channel_Name( Chan )); - /* Text senden */ + /* Send text */ if( Client_Conn( From ) > NONE ) Conn_UpdateIdle( Client_Conn( From )); return IRC_WriteStrChannelPrefix( Client, Chan, From, TRUE, "PRIVMSG %s :%s", Channel_Name( Chan ), Text ); } /* Channel_Write */ - -LOCAL CHANNEL * -New_Chan( CHAR *Name ) +GLOBAL CHANNEL * +Channel_Create( CHAR *Name ) { /* Neue Channel-Struktur anlegen */ @@ -621,16 +714,22 @@ New_Chan( CHAR *Name ) return NULL; } c->next = NULL; - strncpy( c->name, Name, CHANNEL_NAME_LEN - 1 ); + strlcpy( c->name, Name, sizeof( c->name )); c->name[CHANNEL_NAME_LEN - 1] = '\0'; strcpy( c->modes, "" ); strcpy( c->topic, "" ); c->hash = Hash( c->name ); + strcpy( c->key, "" ); + c->maxusers = 0; + /* Verketten */ + c->next = My_Channels; + My_Channels = c; + Log( LOG_DEBUG, "Created new channel structure for \"%s\".", Name ); return c; -} /* New_Chan */ +} /* Channel_Create */ LOCAL CL2CHAN *