X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Fchannel.c;h=aec6aa2da9e9a6b686535040e46432099c424fd0;hb=b92a7627f3dc6b85310964d4b602bea2509dade6;hp=a4eca1f18425f0b79a05ef225f129544b1f1f75d;hpb=54b17fc20162941d03a17ddf78706c5fdc5cfff4;p=ngircd-alex.git diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index a4eca1f1..aec6aa2d 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -89,18 +89,18 @@ Channel_GetListInvites(CHANNEL *c) GLOBAL void Channel_InitPredefined( void ) { - /* Vordefinierte persistente Channels erzeugen */ + /* Generate predefined persistent channels */ CHANNEL *chan; char *c; unsigned int i; - + for( i = 0; i < Conf_Channel_Count; i++ ) { - /* Ist ein Name konfiguriert? */ + /* Check for Name configuration */ if( ! Conf_Channel[i].name[0] ) continue; - /* Gueltiger Channel-Name? */ + /* Check for invalid channel name */ if( ! Channel_IsValidName( Conf_Channel[i].name )) { Log( LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"!", Conf_Channel[i].name ); @@ -108,7 +108,7 @@ Channel_InitPredefined( void ) continue; } - /* Gibt es den Channel bereits? */ + /* Check if the channel name is already in use */ chan = Channel_Search( Conf_Channel[i].name ); if( chan ) { @@ -149,7 +149,7 @@ Channel_Exit( void ) CHANNEL *c, *c_next; CL2CHAN *cl2chan, *cl2chan_next; - /* Channel-Strukturen freigeben */ + /* free struct Channel */ c = My_Channels; while( c ) { @@ -159,7 +159,7 @@ Channel_Exit( void ) c = c_next; } - /* Channel-Zuordnungstabelle freigeben */ + /* Free Channel allocation table */ cl2chan = My_Cl2Chan; while( c ) { @@ -170,40 +170,53 @@ Channel_Exit( void ) } /* Channel_Exit */ +/** + * Join Channel + * This function lets a client join a channel. First, the function + * checks that the specified channel name is valid and that the client + * isn't already a member. If the specified channel doesn't exist, + * a new channel is created. Client is added to channel by function + * Add_Client(). + */ GLOBAL bool Channel_Join( CLIENT *Client, char *Name ) { CHANNEL *chan; - - assert( Client != NULL ); - assert( Name != NULL ); - if( ! Channel_IsValidName( Name )) { - IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name ); + assert(Client != NULL); + assert(Name != NULL); + + /* Check that the channel name is valid */ + if (! Channel_IsValidName(Name)) { + IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG, + Client_ID(Client), Name); return false; } - chan = Channel_Search( Name ); - if( chan ) { - /* Ist der Client bereits Mitglied? */ - if( Get_Cl2Chan( chan, Client )) return false; - } - else - { - /* Gibt es noch nicht? Dann neu anlegen: */ - chan = Channel_Create( Name ); - if (!chan) return false; + chan = Channel_Search(Name); + if(chan) { + /* Check if the client is already in the channel */ + if (Get_Cl2Chan(chan, Client)) + return false; + } else { + /* If the specified channel does not exist, the channel + * is now created */ + chan = Channel_Create(Name); + if (!chan) + return false; } - /* User dem Channel hinzufuegen */ - if( ! Add_Client( chan, Client )) return false; - else return true; + /* Add user to Channel */ + if (! Add_Client(chan, Client)) + return false; + + return true; } /* Channel_Join */ /** - * Remove client from channel. - * This function lets a client lead a channel. First, the function checks + * Part client from channel. + * This function lets a client part from a channel. First, the function checks * if the channel exists and the client is a member of it and sends out * appropriate error messages if not. The real work is done by the function * Remove_Client(). @@ -217,13 +230,22 @@ Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Rea assert(Name != NULL); assert(Reason != NULL); + /* Check that specified channel exists */ chan = Channel_Search(Name); - if ((!chan) || (!Get_Cl2Chan(chan, Client))) { + if (!chan) { IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG, Client_ID(Client), Name); return false; } + /* Check that the client is in the channel */ + if (!Get_Cl2Chan(chan, Client)) { + IRC_WriteStrClient(Client, ERR_NOTONCHANNEL_MSG, + Client_ID(Client), Name); + return false; + } + + /* Part client from channel */ if (!Remove_Client(REMOVE_PART, chan, Client, Origin, Reason, true)) return false; else @@ -231,8 +253,9 @@ Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Rea } /* Channel_Part */ +/* Kick user from Channel */ GLOBAL void -Channel_Kick( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ) +Channel_Kick( CLIENT *Client, CLIENT *Origin, const char *Name, const char *Reason ) { CHANNEL *chan; @@ -241,6 +264,7 @@ Channel_Kick( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ) assert( Name != NULL ); assert( Reason != NULL ); + /* Check that channel exists */ chan = Channel_Search( Name ); if( ! chan ) { @@ -248,26 +272,28 @@ Channel_Kick( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ) return; } + /* Check that user is on the specified channel */ if( ! Channel_IsMemberOf( chan, Origin )) { IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Name ); return; } - /* Is User Channel-Operator? */ + /* Check if user has operator status */ if( ! strchr( Channel_UserModes( chan, Origin ), 'o' )) { IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Name); return; } - /* Ist the kickED User member of channel? */ + /* Check that the client to be kicked is on the specified channel */ if( ! Channel_IsMemberOf( chan, Client )) { IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( Client ), Name ); return; } + /* Kick Client from channel */ Remove_Client( REMOVE_KICK, chan, Client, Origin, Reason, true); } /* Channel_Kick */ @@ -297,7 +323,7 @@ Channel_Count( void ) { CHANNEL *c; unsigned long count = 0; - + c = My_Channels; while( c ) { @@ -333,9 +359,9 @@ Channel_CountForUser( CLIENT *Client ) CL2CHAN *cl2chan; int count = 0; - + assert( Client != NULL ); - + cl2chan = My_Cl2Chan; while( cl2chan ) { @@ -347,7 +373,6 @@ Channel_CountForUser( CLIENT *Client ) } /* Channel_CountForUser */ - GLOBAL const char * Channel_Name( const CHANNEL *Chan ) { @@ -398,8 +423,8 @@ Channel_Next( CHANNEL *Chan ) GLOBAL CHANNEL * Channel_Search( const char *Name ) { - /* Channel-Struktur suchen */ - + /* Search channel structure */ + CHANNEL *c; UINT32 search_hash; @@ -411,7 +436,7 @@ Channel_Search( const char *Name ) { if( search_hash == c->hash ) { - /* lt. Hash-Wert: Treffer! */ + /* hash hit */ if( strcasecmp( Name, c->name ) == 0 ) return c; } c = c->next; @@ -475,7 +500,14 @@ Channel_IsValidName( const char *Name ) { assert( Name != NULL ); - if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return false; +#ifdef STRICT_RFC + if (strlen(Name) <= 1) + return false; +#endif + if (strchr("+#", Name[0]) == NULL) + return false; + if (strlen(Name) >= CHANNEL_NAME_LEN) + return false; return Name[strcspn(Name, " ,:\007")] == 0; } /* Channel_IsValidName */ @@ -623,7 +655,7 @@ Channel_Topic( CHANNEL *Chan ) return ret ? ret : ""; } /* Channel_Topic */ - + #ifndef STRICT_RFC GLOBAL unsigned int @@ -815,7 +847,7 @@ Add_Client( CHANNEL *Chan, CLIENT *Client ) assert( Chan != NULL ); assert( Client != NULL ); - /* neue CL2CHAN-Struktur anlegen */ + /* Create new CL2CHAN structure */ cl2chan = (CL2CHAN *)malloc( sizeof( CL2CHAN )); if( ! cl2chan ) { @@ -826,7 +858,7 @@ Add_Client( CHANNEL *Chan, CLIENT *Client ) cl2chan->client = Client; strcpy( cl2chan->modes, "" ); - /* Verketten */ + /* concatenate */ cl2chan->next = My_Cl2Chan; My_Cl2Chan = cl2chan; @@ -841,7 +873,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch { CL2CHAN *cl2chan, *last_cl2chan; CHANNEL *c; - + assert( Chan != NULL ); assert( Client != NULL ); assert( Origin != NULL ); @@ -860,7 +892,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch c = cl2chan->channel; assert( c != NULL ); - /* Aus Verkettung loesen und freigeben */ + /* maintain cl2chan list */ if( last_cl2chan ) last_cl2chan->next = cl2chan->next; else My_Cl2Chan = cl2chan->next; free( cl2chan ); @@ -887,7 +919,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch IRC_WriteStrClientPrefix(Client, Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason); } - LogDebug("User \"%s\" has been kicked of \"%s\" by \"%s\": %s.", + LogDebug("User \"%s\" has been kicked off \"%s\" by \"%s\": %s.", Client_Mask( Client ), c->name, Client_ID(Origin), Reason); break; default: /* PART */ @@ -906,7 +938,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch } } - /* Wenn Channel nun leer und nicht pre-defined: loeschen */ + /* When channel is empty and is not pre-defined, delete */ if( ! strchr( Channel_Modes( Chan ), 'P' )) { if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan ); @@ -991,7 +1023,7 @@ Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel ) CL2CHAN *cl2chan; assert( Client != NULL || Channel != NULL ); - + cl2chan = Start; while( cl2chan ) { @@ -1006,7 +1038,7 @@ Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel ) static bool Delete_Channel( CHANNEL *Chan ) { - /* Channel-Struktur loeschen */ + /* delete channel structure */ CHANNEL *chan, *last_chan; @@ -1022,11 +1054,11 @@ Delete_Channel( CHANNEL *Chan ) Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name ); - /* Invite- und Ban-Lists aufraeumen */ + /* free invite and ban lists */ Lists_Free( &chan->list_bans ); Lists_Free( &chan->list_invites ); - /* Neu verketten und freigeben */ + /* maintain channel list */ if( last_chan ) last_chan->next = chan->next; else My_Channels = chan->next; free( chan );