]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-mode.c
New configuration option "OperServerMode".
[ngircd-alex.git] / src / ngircd / irc-mode.c
index 368185f6e3be86f78aa204a8311a0dd44adf3b88..6fcb9e3307efd7a65084865651562c330ebeb7aa 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: irc-mode.c,v 1.37 2005/03/02 16:35:11 alex Exp $";
+static char UNUSED id[] = "$Id: irc-mode.c,v 1.39 2005/03/15 16:56:18 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -91,6 +91,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
        CHAR the_modes[COMMAND_LEN], x[2], *mode_ptr;
        BOOLEAN ok, set;
        INT mode_arg;
+       size_t len;
 
        /* Is the client allowed to request or change the modes? */
        if( Client_Type( Client ) == CLIENT_USER )
@@ -134,10 +135,11 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                                if((( *mode_ptr == '+' ) && ( ! set )) || (( *mode_ptr == '-' ) && ( set )))
                                {
                                        /* Action modifier ("+"/"-") must be changed ... */
-                                       if(( the_modes[strlen( the_modes ) - 1] == '+' ) || ( the_modes[strlen( the_modes ) - 1] == '-' ))
+                                       len = strlen( the_modes ) - 1;
+                                       if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' ))
                                        {
                                                /* Adjust last action modifier in result */
-                                               the_modes[strlen( the_modes ) - 1] = *mode_ptr;
+                                               the_modes[len] = *mode_ptr;
                                        }
                                        else
                                        {
@@ -212,7 +214,8 @@ client_exit:
        if( the_modes[1] )
        {
                /* Remoce needless action modifier characters */
-               if(( the_modes[strlen( the_modes ) - 1] == '+' ) || ( the_modes[strlen( the_modes ) - 1] == '-' )) the_modes[strlen( the_modes ) - 1] = '\0';
+               len = strlen( the_modes ) - 1;
+               if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = '\0';
 
                if( Client_Type( Client ) == CLIENT_SERVER )
                {
@@ -239,10 +242,11 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
        /* Handle channel and channel-user modes */
 
        CHAR the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr;
-       BOOLEAN ok, set, modeok, skiponce;
+       BOOLEAN ok, set, modeok = FALSE, skiponce, use_servermode = FALSE;
        INT mode_arg, arg_arg;
        CLIENT *client;
        LONG l;
+       size_t len;
 
        /* Mode request: let's answer it :-) */
        if( Req->argc == 1 )
@@ -282,11 +286,13 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 
                /* Is he channel operator? */
                if( strchr( Channel_UserModes( Channel, Origin ), 'o' )) modeok = TRUE;
-               else modeok = FALSE;
-               if( Conf_OperCanMode )
+               else if( Conf_OperCanMode )
                {
-                       /* auch IRC-Operatoren duerfen MODE verwenden */
-                       if( Client_OperByMe( Origin )) modeok = TRUE;
+                       /* IRC-Operators can use MODE as well */
+                       if( Client_OperByMe( Origin )) {
+                               modeok = TRUE;
+                               if ( Conf_OperServerMode ) use_servermode = TRUE; /* Change Origin to Server */
+                       }
                }
        }
        else modeok = TRUE;
@@ -331,10 +337,11 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
                                if((( *mode_ptr == '+' ) && ( ! set )) || (( *mode_ptr == '-' ) && ( set )))
                                {
                                        /* Action modifier ("+"/"-") must be changed ... */
-                                       if(( the_modes[strlen( the_modes ) - 1] == '+' ) || ( the_modes[strlen( the_modes ) - 1] == '-' ))
+                                       len = strlen( the_modes ) - 1;
+                                       if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' ))
                                        {
                                                /* Adjust last action modifier in result */
-                                               the_modes[strlen( the_modes ) - 1] = *mode_ptr;
+                                               the_modes[len] = *mode_ptr;
                                        }
                                        else
                                        {
@@ -554,7 +561,8 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
                /* Are there additional arguments to add? */
                if( argadd[0] )
                {
-                       if( the_args[strlen( the_args ) - 1] != ' ' ) strlcat( the_args, " ", sizeof( the_args ));
+                       len = strlen( the_args ) - 1;
+                       if( the_args[len] != ' ' ) strlcat( the_args, " ", sizeof( the_args ));
                        strlcat( the_args, argadd, sizeof( the_args ));
                }
        }
@@ -564,7 +572,8 @@ chan_exit:
        if( the_modes[1] )
        {
                /* Clean up mode string */
-               if(( the_modes[strlen( the_modes ) - 1] == '+' ) || ( the_modes[strlen( the_modes ) - 1] == '-' )) the_modes[strlen( the_modes ) - 1] = '\0';
+               len = strlen( the_modes ) - 1;
+               if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = '\0';
 
                /* Clean up argument string if there are none */
                if( ! the_args[1] ) the_args[0] = '\0';
@@ -577,6 +586,8 @@ chan_exit:
                }
                else
                {
+                       if ( use_servermode ) Origin = Client_ThisServer();
+
                        /* Send reply to client and inform other servers and channel users */
                        ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
                        IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );