The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

cmode_b.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *            the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 #include "inspircd.h"
00015 #include <string>
00016 #include <vector>
00017 #include "inspircd_config.h"
00018 #include "configreader.h"
00019 #include "hash_map.h"
00020 #include "mode.h"
00021 #include "channels.h"
00022 #include "users.h"
00023 #include "modules.h"
00024 #include "inspstring.h"
00025 #include "hashcomp.h"
00026 #include "modes/cmode_b.h"
00027 
00028 ModeChannelBan::ModeChannelBan(InspIRCd* Instance) : ModeHandler(Instance, 'b', 1, 1, true, MODETYPE_CHANNEL, false)
00029 {
00030 }
00031 
00032 ModeAction ModeChannelBan::OnModeChange(User* source, User*, Channel* channel, std::string &parameter, bool adding, bool servermode)
00033 {
00034         int status = channel->GetStatus(source);
00035         /* Call the correct method depending on wether we're adding or removing the mode */
00036         if (adding)
00037         {
00038                 parameter = this->AddBan(source, parameter, channel, status, servermode);
00039         }
00040         else
00041         {
00042                 parameter = this->DelBan(source, parameter, channel, status);
00043         }
00044         /* If the method above 'ate' the parameter by reducing it to an empty string, then
00045          * it won't matter wether we return ALLOW or DENY here, as an empty string overrides
00046          * the return value and is always MODEACTION_DENY if the mode is supposed to have
00047          * a parameter.
00048          */
00049         return MODEACTION_ALLOW;
00050 }
00051 
00052 void ModeChannelBan::RemoveMode(Channel* channel, irc::modestacker* stack)
00053 {
00054         BanList copy;
00055 
00056         for (BanList::iterator i = channel->bans.begin(); i != channel->bans.end(); i++)
00057         {
00058                 copy.push_back(*i);
00059         }
00060 
00061         for (BanList::iterator i = copy.begin(); i != copy.end(); i++)
00062         {
00063                 if (stack)
00064                 {
00065                         stack->Push(this->GetModeChar(), i->data);
00066                 }
00067                 else
00068                 {
00069                         std::vector<std::string> parameters; parameters.push_back(channel->name); parameters.push_back("-b"); parameters.push_back(i->data);
00070                         ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
00071                 }
00072         }
00073 }
00074 
00075 void ModeChannelBan::RemoveMode(User*, irc::modestacker* stack)
00076 {
00077 }
00078 
00079 void ModeChannelBan::DisplayList(User* user, Channel* channel)
00080 {
00081         /* Display the channel banlist */
00082         for (BanList::reverse_iterator i = channel->bans.rbegin(); i != channel->bans.rend(); ++i)
00083         {
00084                 user->WriteServ("367 %s %s %s %s %lu",user->nick.c_str(), channel->name.c_str(), i->data.c_str(), i->set_by.c_str(), (unsigned long)i->set_time);
00085         }
00086         user->WriteServ("368 %s %s :End of channel ban list",user->nick.c_str(), channel->name.c_str());
00087         return;
00088 }
00089 
00090 void ModeChannelBan::DisplayEmptyList(User* user, Channel* channel)
00091 {
00092         user->WriteServ("368 %s %s :End of channel ban list",user->nick.c_str(), channel->name.c_str());
00093 }
00094 
00095 std::string& ModeChannelBan::AddBan(User *user, std::string &dest, Channel *chan, int, bool servermode)
00096 {
00097         if ((!user) || (!chan))
00098         {
00099                 ServerInstance->Logs->Log("MODE",DEFAULT,"*** BUG *** AddBan was given an invalid parameter");
00100                 dest = "";
00101                 return dest;
00102         }
00103 
00104         /* Attempt to tidy the mask */
00105         ModeParser::CleanMask(dest);
00106         /* If the mask was invalid, we exit */
00107         if (dest == "")
00108                 return dest;
00109 
00110         long maxbans = chan->GetMaxBans();
00111         if (!IS_LOCAL(user) && ((unsigned)chan->bans.size() > (unsigned)maxbans))
00112         {
00113                 user->WriteServ("478 %s %s :Channel ban list for %s is full (maximum entries for this channel is %ld)",user->nick.c_str(), chan->name.c_str(), chan->name.c_str(), maxbans);
00114                 dest = "";
00115                 return dest;
00116         }
00117 
00118         int MOD_RESULT = 0;
00119         FOREACH_RESULT(I_OnAddBan,OnAddBan(user,chan,dest));
00120         if (MOD_RESULT)
00121         {
00122                 dest = "";
00123                 return dest;
00124         }
00125 
00126         for (BanList::iterator i = chan->bans.begin(); i != chan->bans.end(); i++)
00127         {
00128                 if (!strcasecmp(i->data.c_str(), dest.c_str()))
00129                 {
00130                         /* dont allow a user to set the same ban twice */
00131                         dest = "";
00132                         return dest;
00133                 }
00134         }
00135 
00136         b.set_time = ServerInstance->Time();
00137         b.data.assign(dest, 0, MAXBUF);
00138         b.set_by.assign(servermode ? ServerInstance->Config->ServerName : user->nick, 0, 64);
00139         chan->bans.push_back(b);
00140         return dest;
00141 }
00142 
00143 ModePair ModeChannelBan::ModeSet(User*, User*, Channel* channel, const std::string &parameter)
00144 {
00145         for (BanList::iterator i = channel->bans.begin(); i != channel->bans.end(); i++)
00146         {
00147                 if (!strcasecmp(i->data.c_str(), parameter.c_str()))
00148                 {
00149                         return std::make_pair(true, i->data);
00150                 }
00151         }
00152         return std::make_pair(false, parameter);
00153 }
00154 
00155 std::string& ModeChannelBan::DelBan(User *user, std::string& dest, Channel *chan, int)
00156 {
00157         if ((!user) || (!chan))
00158         {
00159                 ServerInstance->Logs->Log("MODE",DEFAULT,"*** BUG *** TakeBan was given an invalid parameter");
00160                 dest = "";
00161                 return dest;
00162         }
00163 
00164         /* 'Clean' the mask, e.g. nick -> nick!*@* */
00165         ModeParser::CleanMask(dest);
00166 
00167         for (BanList::iterator i = chan->bans.begin(); i != chan->bans.end(); i++)
00168         {
00169                 if (!strcasecmp(i->data.c_str(), dest.c_str()))
00170                 {
00171                         int MOD_RESULT = 0;
00172                         FOREACH_RESULT(I_OnDelBan,OnDelBan(user, chan, dest));
00173                         if (MOD_RESULT)
00174                         {
00175                                 dest = "";
00176                                 return dest;
00177                         }
00178                         chan->bans.erase(i);
00179                         return dest;
00180                 }
00181         }
00182         dest = "";
00183         return dest;
00184 }
00185