]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-channel.c
Add missong Doxygen @file tags to ngircd.h and irc-op.h
[ngircd-alex.git] / src / ngircd / irc-channel.c
index 3bf02c67893ee551c6c2b7ebe08d846044881d05..a7a273d88935776b3b008a6bd854ec7ca427f24a 100644 (file)
@@ -7,13 +7,15 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
- *
- * IRC channel commands
  */
 
-
 #include "portab.h"
 
+/**
+ * @file
+ * IRC channel commands
+ */
+
 #include "imp.h"
 #include <assert.h>
 #include <stdlib.h>
@@ -122,6 +124,13 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
                return false;
        }
 
+       if (strchr(channel_modes, 'O') && !Client_OperByMe(Client)) {
+               /* Only IRC operators are allowed! */
+               IRC_WriteStrClient(Client, ERR_OPONLYCHANNEL_MSG,
+                                  Client_ID(Client), channame);
+               return false;
+       }
+
        return true;
 }
 
@@ -407,49 +416,64 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
        CHANNEL *chan;
        CLIENT *from;
        char *topic;
-       bool r;
+       bool onchannel, topicok, use_servermode, r;
 
        assert( Client != NULL );
        assert( Req != NULL );
 
-       if ((Req->argc < 1) || (Req->argc > 2))
-               return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
+       if (Req->argc < 1 || Req->argc > 2)
+               return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+                                         Client_ID(Client), Req->command);
+
+       if (Client_Type(Client) == CLIENT_SERVER)
+               from = Client_Search(Req->prefix);
+       else
+               from = Client;
 
-       if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
-       else from = Client;
-       if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
+       if (!from)
+               return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+                                         Client_ID(Client), Req->prefix);
 
-       /* Welcher Channel? */
-       chan = Channel_Search( Req->argv[0] );
-       if( ! chan ) return IRC_WriteStrClient( from, ERR_NOSUCHCHANNEL_MSG, Client_ID( from ), Req->argv[0] );
+       chan = Channel_Search(Req->argv[0]);
+       if (!chan)
+               return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
+                                         Client_ID(from), Req->argv[0]);
 
-       /* Ist der User Mitglied in dem Channel? */
-       if( ! Channel_IsMemberOf( chan, from )) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( from ), Req->argv[0] );
+       Channel_CheckAdminRights(chan, Client, from,
+                                &onchannel, &topicok, &use_servermode);
 
-       if( Req->argc == 1 )
-       {
+       if (!onchannel && !topicok)
+               return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
+                                         Client_ID(from), Req->argv[0]);
+
+       if (Req->argc == 1) {
                /* Request actual topic */
                topic = Channel_Topic(chan);
                if (*topic) {
                        r = IRC_WriteStrClient(from, RPL_TOPIC_MSG,
-                               Client_ID(Client), Channel_Name(chan), topic);
+                                              Client_ID(Client),
+                                              Channel_Name(chan), topic);
 #ifndef STRICT_RFC
                        r = IRC_WriteStrClient(from, RPL_TOPICSETBY_MSG,
-                               Client_ID(Client), Channel_Name(chan),
-                               Channel_TopicWho(chan),
-                               Channel_TopicTime(chan));
+                                              Client_ID(Client),
+                                              Channel_Name(chan),
+                                              Channel_TopicWho(chan),
+                                              Channel_TopicTime(chan));
 #endif
                        return r;
                }
                else
-                        return IRC_WriteStrClient(from, RPL_NOTOPIC_MSG,
-                                       Client_ID(from), Channel_Name(chan));
+                       return IRC_WriteStrClient(from, RPL_NOTOPIC_MSG,
+                                                 Client_ID(from),
+                                                 Channel_Name(chan));
        }
 
-       if( strchr( Channel_Modes( chan ), 't' ))
-       {
-               /* Topic Lock. Ist der User ein Channel Operator? */
-               if( ! strchr( Channel_UserModes( chan, from ), 'o' )) return IRC_WriteStrClient( from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( from ), Channel_Name( chan ));
+       if (strchr(Channel_Modes(chan), 't')) {
+               /* Topic Lock. Is the user a channel or IRC operator? */
+               if (!topicok)
+                       return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
+                                                 Client_ID(from),
+                                                 Channel_Name(chan));
        }
 
        /* Set new topic */
@@ -458,6 +482,9 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
                 Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
                 Req->argv[1][0] ? Req->argv[1] : "<none>");
 
+       if (use_servermode)
+               from = Client_ThisServer();
+
        /* Update channel and forward new topic to other servers */
        if (!Channel_IsLocal(chan))
                IRC_WriteStrServersPrefix(Client, from, "TOPIC %s :%s",