Commit Diff


commit - 2e88dd72d1776695fa223cea65953ba4642992f4
commit + 69ad0e386e064bf95fc77d179f88d3ae04405d30
blob - 528751e48d0f013291ace866a66f071323f78967
blob + 926d345e9dbf5267302e6a59a0699afb33e01f21
--- src/ngircd/irc-channel.c
+++ src/ngircd/irc-channel.c
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: irc-channel.c,v 1.20 2002/12/14 13:23:11 alex Exp $";
+static char UNUSED id[] = "$Id: irc-channel.c,v 1.21 2002/12/16 23:06:46 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -41,7 +41,7 @@ static char UNUSED id[] = "$Id: irc-channel.c,v 1.20 2
 GLOBAL BOOLEAN
 IRC_JOIN( CLIENT *Client, REQUEST *Req )
 {
-	CHAR *channame, *flags, *topic, modes[8];
+	CHAR *channame, *key, *flags, *topic, modes[8];
 	BOOLEAN is_new_chan, is_invited, is_banned;
 	CLIENT *target;
 	CHANNEL *chan;
@@ -49,14 +49,18 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 	assert( Client != NULL );
 	assert( Req != NULL );
 
-	/* Falsche Anzahl Parameter? */
-	if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
+	/* Bad number of arguments? */
+	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 
-	/* Wer ist der Absender? */
+	/* Who is the sender? */
 	if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
 	else target = Client;
 	if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 
+	/* Are channel keys given? */
+	if( Req->argc > 1 ) key = Req->argv[1];
+	else key = NULL;
+
 	/* Channel-Namen durchgehen */
 	chan = NULL;
 	channame = strtok( Req->argv[0], "," );
@@ -114,18 +118,40 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 					/* Client ist gebanned (und nicht invited): */
 					IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
 
-					/* naechsten Namen ermitteln */
+					/* Try next name, if any */
 					channame = strtok( NULL, "," );
 					continue;
 				}
 
 				/* Ist der Channel "invite-only"? */
-				if(( strchr( Channel_Modes( chan ), 'i' ) != NULL ) && ( is_invited == FALSE ))
+				if(( strchr( Channel_Modes( chan ), 'i' )) && ( is_invited == FALSE ))
 				{
 					/* Channel ist "invite-only" und Client wurde nicht invited: */
 					IRC_WriteStrClient( Client, ERR_INVITEONLYCHAN_MSG, Client_ID( Client ), channame );
 
-					/* naechsten Namen ermitteln */
+					/* Try next name, if any */
+					channame = strtok( NULL, "," );
+					continue;
+				}
+
+				/* Is the channel protected by a key? */
+				if(( strchr( Channel_Modes( chan ), 'k' )) && ( strcmp( Channel_Key( chan ), key ? key : "" ) != 0 ))
+				{
+					/* Bad channel key! */
+					IRC_WriteStrClient( Client, ERR_BADCHANNELKEY_MSG, Client_ID( Client ), channame );
+
+					/* Try next name, if any */
+					channame = strtok( NULL, "," );
+					continue;
+				}
+
+				/* Are there already too many members? */
+				if(( strchr( Channel_Modes( chan ), 'l' )) && ( Channel_MaxUsers( chan ) <= Channel_MemberCount( chan )))
+				{
+					/* Bad channel key! */
+					IRC_WriteStrClient( Client, ERR_CHANNELISFULL_MSG, Client_ID( Client ), channame );
+
+					/* Try next name, if any */
 					channame = strtok( NULL, "," );
 					continue;
 				}
blob - 381811e456c5ee6a3830e22fee44c1a7c23eca8f
blob + 148698ac48096ab562fb28f393e9eaea968e53d6
--- src/ngircd/irc-mode.c
+++ src/ngircd/irc-mode.c
@@ -14,10 +14,12 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: irc-mode.c,v 1.22 2002/12/16 10:52:53 alex Exp $";
+static char UNUSED id[] = "$Id: irc-mode.c,v 1.23 2002/12/16 23:06:46 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "conn.h"
@@ -178,6 +180,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Ori
 				Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ));
 				if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
 				x[0] = '\0';
+				goto client_exit;
 		}
 		if( ! ok ) break;
 
@@ -196,7 +199,8 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Ori
 			if( Client_ModeDel( Target, x[0] )) strcat( the_modes, x );
 		}		
 	}
-
+client_exit:
+	
 	/* Are there changed modes? */
 	if( the_modes[1] )
 	{
@@ -226,10 +230,11 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Or
 {
 	/* Handle channel and channel-user modes */
 
-	CHAR the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], *mode_ptr;
+	CHAR the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr;
 	BOOLEAN ok, set, modeok, skiponce;
 	INT mode_arg, arg_arg;
 	CLIENT *client;
+	LONG l;
 
 	/* Mode request: let's answer it :-) */
 	if( Req->argc == 1 ) return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), Channel_Modes( Channel ));
@@ -308,6 +313,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Or
 
 		/* Validate modes */
 		x[0] = '\0';
+		argadd[0] = '\0';
 		client = NULL;
 		switch( *mode_ptr )
 		{
@@ -365,6 +371,56 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Or
 				}
 				else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
 				break;
+			case 'k':
+				/* Channel key */
+				if( ! set )
+				{
+					if( modeok ) x[0] = *mode_ptr;
+					else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
+					break;
+				}
+				if( arg_arg > mode_arg )
+				{
+					if( modeok )
+					{
+						Channel_ModeDel( Channel, 'k' );
+						Channel_SetKey( Channel, Req->argv[arg_arg] );
+						strcpy( argadd, Channel_Key( Channel ));
+						x[0] = *mode_ptr;
+					}
+					else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
+					Req->argv[arg_arg][0] = '\0';
+					arg_arg++;
+				}
+				else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
+				break;
+			case 'l':
+				/* Member limit */
+				if( ! set )
+				{
+					if( modeok ) x[0] = *mode_ptr;
+					else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
+					break;
+				}
+				if( arg_arg > mode_arg )
+				{
+					if( modeok )
+					{
+						l = atol( Req->argv[arg_arg] );
+						if( l > 0 && l < 0xFFFF )
+						{
+							Channel_ModeDel( Channel, 'l' );
+							Channel_SetMaxUsers( Channel, l );
+							sprintf( argadd, "%ld", l );
+							x[0] = *mode_ptr;
+						}
+					}
+					else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
+					Req->argv[arg_arg][0] = '\0';
+					arg_arg++;
+				}
+				else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
+				break;
 
 			/* Channel lists */
 			case 'I':
@@ -404,6 +460,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Or
 				Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\" on %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ), Channel_Name( Channel ));
 				if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
 				x[0] = '\0';
+				goto chan_exit;
 		}
 		if( ! ok ) break;
 
@@ -455,8 +512,16 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Or
 					Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel ));
 				}
 			}
-		}		
+		}
+
+		/* Are there additional arguments to add? */
+		if( argadd[0] )
+		{
+			if( the_args[strlen( the_args ) - 1] != ' ' ) strcat( the_args, " " );
+			strcat( the_args, argadd );
+		}
 	}
+chan_exit:
 
 	/* Are there changed modes? */
 	if( the_modes[1] )