]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/channel.c
Remove Can_Send_To_Channel_Identified()
[ngircd-alex.git] / src / ngircd / channel.c
index 4d323f274c46b10d7917c7cab5e347f6a85bc8fd..0f21a459c3a6644c0f14b2c581f8a45aca154bdc 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -87,6 +87,14 @@ Channel_GetListBans(CHANNEL *c)
 }
 
 
+GLOBAL struct list_head *
+Channel_GetListExcepts(CHANNEL *c)
+{
+       assert(c != NULL);
+       return &c->list_excepts;
+}
+
+
 GLOBAL struct list_head *
 Channel_GetListInvites(CHANNEL *c)
 {
@@ -161,6 +169,7 @@ Free_Channel(CHANNEL *chan)
        array_free(&chan->topic);
        array_free(&chan->keyfile);
        Lists_Free(&chan->list_bans);
+       Lists_Free(&chan->list_excepts);
        Lists_Free(&chan->list_invites);
 
        free(chan);
@@ -788,6 +797,13 @@ Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
 } /* Channel_SetMaxUsers */
 
 
+/**
+ * Check if a client is allowed to send to a specific channel.
+ *
+ * @param Chan The channel to check.
+ * @param From The client that wants to send.
+ * @return true if the client is allowed to send, false otherwise.
+ */
 static bool
 Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 {
@@ -816,12 +832,19 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
        if (strchr(Channel_Modes(Chan), 'n') && !is_member)
                return false;
 
+       if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
+           && !Client_HasMode(From, 'o'))
+               return false;
+
        if (is_op || has_voice)
                return true;
 
        if (strchr(Channel_Modes(Chan), 'm'))
                return false;
 
+       if (Lists_Check(&Chan->list_excepts, From))
+               return true;
+
        return !Lists_Check(&Chan->list_bans, From);
 }
 
@@ -1013,7 +1036,16 @@ GLOBAL bool
 Channel_AddBan(CHANNEL *c, const char *mask )
 {
        struct list_head *h = Channel_GetListBans(c);
-       LogDebug("Adding \"%s\" to \"%s\" %s list", mask, Channel_Name(c), "ban");
+       LogDebug("Adding \"%s\" to \"%s\" ban list", mask, Channel_Name(c));
+       return Lists_Add(h, mask, false, NULL);
+}
+
+
+GLOBAL bool
+Channel_AddExcept(CHANNEL *c, const char *mask )
+{
+       struct list_head *h = Channel_GetListExcepts(c);
+       LogDebug("Adding \"%s\" to \"%s\" exception list", mask, Channel_Name(c));
        return Lists_Add(h, mask, false, NULL);
 }
 
@@ -1022,30 +1054,31 @@ GLOBAL bool
 Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce)
 {
        struct list_head *h = Channel_GetListInvites(c);
-       LogDebug("Adding \"%s\" to \"%s\" %s list", mask, Channel_Name(c), "invite");
+       LogDebug("Adding \"%s\" to \"%s\" invite list", mask, Channel_Name(c));
        return Lists_Add(h, mask, onlyonce, NULL);
 }
 
 
 static bool
-ShowInvitesBans(struct list_head *head, CLIENT *Client, CHANNEL *Channel, bool invite)
+ShowChannelList(struct list_head *head, CLIENT *Client, CHANNEL *Channel,
+               char *msg, char *msg_end)
 {
        struct list_elem *e;
-       char *msg = invite ? RPL_INVITELIST_MSG : RPL_BANLIST_MSG;
-       char *msg_end;
 
-       assert( Client != NULL );
-       assert( Channel != NULL );
+       assert (Client != NULL);
+       assert (Channel != NULL);
 
        e = Lists_GetFirst(head);
        while (e) {
-               if( ! IRC_WriteStrClient( Client, msg, Client_ID( Client ),
-                               Channel_Name( Channel ), Lists_GetMask(e) )) return DISCONNECTED;
+               if (!IRC_WriteStrClient(Client, msg, Client_ID(Client),
+                                       Channel_Name(Channel),
+                                       Lists_GetMask(e)))
+                       return DISCONNECTED;
                e = Lists_GetNext(e);
        }
 
-       msg_end = invite ? RPL_ENDOFINVITELIST_MSG : RPL_ENDOFBANLIST_MSG;
-       return IRC_WriteStrClient( Client, msg_end, Client_ID( Client ), Channel_Name( Channel ));
+       return IRC_WriteStrClient(Client, msg_end, Client_ID(Client),
+                                 Channel_Name(Channel));
 }
 
 
@@ -1057,7 +1090,21 @@ Channel_ShowBans( CLIENT *Client, CHANNEL *Channel )
        assert( Channel != NULL );
 
        h = Channel_GetListBans(Channel);
-       return ShowInvitesBans(h, Client, Channel, false);
+       return ShowChannelList(h, Client, Channel, RPL_BANLIST_MSG,
+                              RPL_ENDOFBANLIST_MSG);
+}
+
+
+GLOBAL bool
+Channel_ShowExcepts( CLIENT *Client, CHANNEL *Channel )
+{
+       struct list_head *h;
+
+       assert( Channel != NULL );
+
+       h = Channel_GetListExcepts(Channel);
+       return ShowChannelList(h, Client, Channel, RPL_EXCEPTLIST_MSG,
+                              RPL_ENDOFEXCEPTLIST_MSG);
 }
 
 
@@ -1069,7 +1116,8 @@ Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
        assert( Channel != NULL );
 
        h = Channel_GetListInvites(Channel);
-       return ShowInvitesBans(h, Client, Channel, true);
+       return ShowChannelList(h, Client, Channel, RPL_INVITELIST_MSG,
+                              RPL_ENDOFINVITELIST_MSG);
 }