]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-mode.c
Added missing include for <sys/select.h>.
[ngircd-alex.git] / src / ngircd / irc-mode.c
index aac8769512ac87eaf252feecb305ea8303aedf44..cf6354171df7a454dbd704163b0a146e90673729 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: irc-mode.c,v 1.28 2003/01/02 17:57:09 alex Exp $";
+static char UNUSED id[] = "$Id: irc-mode.c,v 1.31 2003/01/21 21:04:16 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -247,11 +247,42 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
        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 ));
+       if( Req->argc == 1 )
+       {
+               /* Member or not? -- That's the question! */
+               if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), Channel_Modes( Channel ));
+
+               /* The sender is a member: generate extended reply */
+               strlcpy( the_modes, Channel_Modes( Channel ), sizeof( the_modes ));
+               mode_ptr = the_modes;
+               strcpy( the_args, "" );
+               while( *mode_ptr )
+               {
+                       switch( *mode_ptr )
+                       {
+                               case 'l':
+                                       snprintf( argadd, sizeof( argadd ), " %ld", Channel_MaxUsers( Channel ));
+                                       strlcat( the_args, argadd, sizeof( the_args ));
+                                       break;
+                               case 'k':
+                                       strlcat( the_args, " ", sizeof( the_args ));
+                                       strlcat( the_args, Channel_Key( Channel ), sizeof( the_args ));
+                                       break;
+                       }
+                       mode_ptr++;
+               }
+               if( the_args[0] ) strlcat( the_modes, the_args, sizeof( the_modes ));
+
+               return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), the_modes );
+       }
 
        /* Is the user allowed to change modes? */
        if( Client_Type( Client ) == CLIENT_USER )
        {
+               /* Is the originating user on that channel? */
+               if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Channel_Name( Channel ));
+
+               /* Is he channel operator? */
                if( strchr( Channel_UserModes( Channel, Origin ), 'o' )) modeok = TRUE;
                else modeok = FALSE;
                if( Conf_OperCanMode )
@@ -478,6 +509,13 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
                /* Is there a valid mode change? */
                if( ! x[0] ) continue;
 
+               /* Validate target client */
+               if( client && ( ! Channel_IsMemberOf( Channel, client )))
+               {
+                       if( ! IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( client ), Channel_Name( Channel ))) break;
+                       continue;
+               }
+
                if( set )
                {
                        /* Set mode */