]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-mode.c
Fixed propagation of channel mode 'P' on server links.
[ngircd-alex.git] / src / ngircd / irc-mode.c
index d83355690b86f8e1b6d1ff3f1c97539376abd3ef..c26984d8208ec5eb0e4201bd2bebe694dd0b6097 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: irc-mode.c,v 1.40 2005/03/19 18:43:48 fw Exp $";
+static char UNUSED id[] = "$Id: irc-mode.c,v 1.50 2007/10/14 12:08:57 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
@@ -22,10 +22,10 @@ static char UNUSED id[] = "$Id: irc-mode.c,v 1.40 2005/03/19 18:43:48 fw Exp $";
 #include <stdlib.h>
 #include <string.h>
 
+#include "defines.h"
 #include "conn.h"
 #include "client.h"
 #include "channel.h"
-#include "defines.h"
 #include "irc-write.h"
 #include "lists.h"
 #include "log.h"
@@ -38,16 +38,16 @@ static char UNUSED id[] = "$Id: irc-mode.c,v 1.40 2005/03/19 18:43:48 fw Exp $";
 #include "irc-mode.h"
 
 
-LOCAL bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ));
-LOCAL bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ));
+static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ));
+static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ));
 
-LOCAL bool Add_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
-LOCAL bool Add_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
+static bool Add_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
+static bool Add_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
 
-LOCAL bool Del_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
-LOCAL bool Del_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
+static bool Del_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
+static bool Del_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
 
-LOCAL bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask ));
+static bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask ));
 
 
 GLOBAL bool
@@ -69,21 +69,26 @@ IRC_MODE( CLIENT *Client, REQUEST *Req )
                if( ! origin ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
        }
        else origin = Client;
-       
+
        /* Channel or user mode? */
-       cl = chan = NULL;
-       if( Client_IsValidNick( Req->argv[0] )) cl = Client_Search( Req->argv[0] );
-       if( Channel_IsValidName( Req->argv[0] )) chan = Channel_Search( Req->argv[0] );
+       cl = NULL; chan = NULL;
+       if (Client_IsValidNick(Req->argv[0]))
+               cl = Client_Search(Req->argv[0]);
+       if (Channel_IsValidName(Req->argv[0]))
+               chan = Channel_Search(Req->argv[0]);
 
-       if( cl ) return Client_Mode( Client, Req, origin, cl );
-       if( chan ) return Channel_Mode( Client, Req, origin, chan );
+       if (cl)
+               return Client_Mode(Client, Req, origin, cl);
+       if (chan)
+               return Channel_Mode(Client, Req, origin, chan);
 
        /* No target found! */
-       return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
+       return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+                       Client_ID(Client), Req->argv[0]);
 } /* IRC_MODE */
 
 
-LOCAL bool
+static bool
 Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 {
        /* Handle client mode requests */
@@ -159,6 +164,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                {
                        case 'i': /* Invisible */
                        case 's': /* Server messages */
+                       case 'w': /* Wallops messages */
                                x[0] = *mode_ptr;
                                break;
 
@@ -166,7 +172,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                                if( Client_Type( Client ) == CLIENT_SERVER )
                                {
                                        x[0] = 'a';
-                                       Client_SetAway( Client, DEFAULT_AWAY_MSG );
+                                       Client_SetAway( Origin, DEFAULT_AWAY_MSG );
                                }
                                else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
                                break;
@@ -236,7 +242,7 @@ client_exit:
 } /* Client_Mode */
 
 
-LOCAL bool
+static bool
 Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 {
        /* Handle channel and channel-user modes */
@@ -257,13 +263,13 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *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, "" );
+               the_args[0] = '\0';
                while( *mode_ptr )
                {
                        switch( *mode_ptr )
                        {
                                case 'l':
-                                       snprintf( argadd, sizeof( argadd ), " %ld", Channel_MaxUsers( Channel ));
+                                       snprintf( argadd, sizeof( argadd ), " %lu", Channel_MaxUsers( Channel ));
                                        strlcat( the_args, argadd, sizeof( the_args ));
                                        break;
                                case 'k':
@@ -426,16 +432,21 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
                                break;
 
                        case 'P': /* Persistent channel */
-                               if( modeok )
-                               {
-                                       if( set && ( ! Client_OperByMe( Client )))
-                                       {
-                                               /* Only IRC operators are allowed to set P mode */
-                                               ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
-                                       }
-                                       else x[0] = 'P';
-                               }
-                               else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
+                               if (modeok) {
+                                       /* Only IRC operators are allowed to
+                                        * set the 'P' channel mode! */
+                                       if (set && ! (Client_OperByMe(Client)
+                                           || Client_Type(Client) == CLIENT_SERVER)) {
+                                               ok = IRC_WriteStrClient(Origin,
+                                                       ERR_NOPRIVILEGES_MSG,
+                                                       Client_ID(Origin));
+                                       } else
+                                               x[0] = 'P';
+                               } else
+                                       ok = IRC_WriteStrClient(Origin,
+                                               ERR_CHANOPRIVSNEEDED_MSG,
+                                               Client_ID(Origin),
+                                               Channel_Name(Channel));
                                break;
 
                        /* --- Channel user modes --- */
@@ -472,7 +483,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
                                        Req->argv[arg_arg][0] = '\0';
                                        arg_arg++;
                                }
-                               else Lists_ShowInvites( Origin, Channel );
+                               else Channel_ShowInvites( Origin, Channel );
                                break;
 
                        case 'b': /* Ban lists */
@@ -488,7 +499,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
                                        Req->argv[arg_arg][0] = '\0';
                                        arg_arg++;
                                }
-                               else Lists_ShowBans( Origin, Channel );
+                               else Channel_ShowBans( Origin, Channel );
                                break;
 
                        default:
@@ -627,7 +638,7 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req )
 } /* IRC_AWAY */
 
 
-LOCAL bool
+static bool
 Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 {
        char *mask;
@@ -639,17 +650,19 @@ Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 
        mask = Lists_MakeMask( Pattern );
 
-       already = Lists_IsInviteEntry( mask, Channel );
-       
-       if( ! Lists_AddInvited( mask, Channel, false )) return CONNECTED;
-       
-       if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED;
+       already = Lists_CheckDupeMask(Channel_GetListInvites(Channel), mask );
+       if (!already) {
+               if( ! Channel_AddInvite(Channel, mask, false ))
+                       return CONNECTED;
+       }
+       if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER ))
+               return CONNECTED;
 
        return Send_ListChange( "+I", Prefix, Client, Channel, mask );
 } /* Add_Invite */
 
 
-LOCAL bool
+static bool
 Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 {
        char *mask;
@@ -661,17 +674,19 @@ Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 
        mask = Lists_MakeMask( Pattern );
 
-       already = Lists_IsBanEntry( mask, Channel );
-
-       if( ! Lists_AddBanned( mask, Channel )) return CONNECTED;
-
-       if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED;
+       already = Lists_CheckDupeMask(Channel_GetListBans(Channel), mask );
+       if (!already) {
+               if( ! Channel_AddBan(Channel, mask))
+                       return CONNECTED;
+       }
+       if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER ))
+               return CONNECTED;
 
        return Send_ListChange( "+b", Prefix, Client, Channel, mask );
 } /* Add_Ban */
 
 
-LOCAL bool
+static bool
 Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 {
        char *mask;
@@ -681,12 +696,12 @@ Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
        assert( Pattern != NULL );
 
        mask = Lists_MakeMask( Pattern );
-       Lists_DelInvited( mask, Channel );
+       Lists_Del(Channel_GetListInvites(Channel), mask);
        return Send_ListChange( "-I", Prefix, Client, Channel, mask );
 } /* Del_Invite */
 
 
-LOCAL bool
+static bool
 Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 {
        char *mask;
@@ -696,12 +711,12 @@ Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
        assert( Pattern != NULL );
 
        mask = Lists_MakeMask( Pattern );
-       Lists_DelBanned( mask, Channel );
+       Lists_Del(Channel_GetListBans(Channel), mask);
        return Send_ListChange( "-b", Prefix, Client, Channel, mask );
 } /* Del_Ban */
 
 
-LOCAL bool
+static bool
 Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask )
 {
        /* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */