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

m_cban.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 "xline.h"
00016 
00017 /* $ModDesc: Gives /cban, aka C:lines. Think Q:lines, for channels. */
00018 
00021 class CBan : public XLine
00022 {
00023 public:
00024         irc::string matchtext;
00025 
00026         CBan(InspIRCd* Instance, time_t s_time, long d, const char* src, const char* re, const char *ch) : XLine(Instance, s_time, d, src, re, "CBAN")
00027         {
00028                 this->matchtext = ch;
00029         }
00030 
00031         ~CBan()
00032         {
00033         }
00034 
00035         // XXX I shouldn't have to define this
00036         bool Matches(User *u)
00037         {
00038                 return false;
00039         }
00040 
00041         bool Matches(const std::string &s)
00042         {
00043                 if (matchtext == s)
00044                         return true;
00045                 return false;
00046         }
00047 
00048         void DisplayExpiry()
00049         {
00050                 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed CBan %s (set by %s %ld seconds ago)", this->matchtext.c_str(), this->source, this->duration);
00051         }
00052 
00053         const char* Displayable()
00054         {
00055                 return matchtext.c_str();
00056         }
00057 };
00058 
00061 class CBanFactory : public XLineFactory
00062 {
00063  public:
00064         CBanFactory(InspIRCd* Instance) : XLineFactory(Instance, "CBAN") { }
00065 
00068         XLine* Generate(time_t set_time, long duration, const char* source, const char* reason, const char* xline_specific_mask)
00069         {
00070                 return new CBan(ServerInstance, set_time, duration, source, reason, xline_specific_mask);
00071         }
00072 
00073         bool AutoApplyToUserList(XLine *x)
00074         {
00075                 return false; // No, we apply to channels.
00076         }
00077 };
00078 
00081 class CommandCBan : public Command
00082 {
00083  public:
00084         CommandCBan(InspIRCd* Me) : Command(Me, "CBAN", "o", 1, 3)
00085         {
00086                 this->source = "m_cban.so";
00087                 this->syntax = "<channel> [<duration> :<reason>]";
00088                 TRANSLATE4(TR_TEXT,TR_TEXT,TR_TEXT,TR_END);
00089         }
00090 
00091         CmdResult Handle(const std::vector<std::string> &parameters, User *user)
00092         {
00093                 /* syntax: CBAN #channel time :reason goes here */
00094                 /* 'time' is a human-readable timestring, like 2d3h2s. */
00095 
00096                 if (parameters.size() == 1)
00097                 {
00098                         if (ServerInstance->XLines->DelLine(parameters[0].c_str(), "CBAN", user))
00099                         {
00100                                 ServerInstance->SNO->WriteToSnoMask('x',"%s Removed CBan on %s.",user->nick.c_str(),parameters[0].c_str());
00101                         }
00102                         else
00103                         {
00104                                 user->WriteServ("NOTICE %s :*** CBan %s not found in list, try /stats C.",user->nick.c_str(),parameters[0].c_str());
00105                         }
00106 
00107                         return CMD_SUCCESS;
00108                 }
00109                 else if (parameters.size() >= 2)
00110                 {
00111                         // Adding - XXX todo make this respect <insane> tag perhaps..
00112                         long duration = ServerInstance->Duration(parameters[1]);
00113                         CBan *r = NULL;
00114 
00115                         try
00116                         {
00117                                 r = new CBan(ServerInstance, ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str());
00118                         }
00119                         catch (...)
00120                         {
00121                                 ; // Do nothing. If we get here, the regex was fucked up, and they already got told it fucked up.
00122                         }
00123 
00124                         if (r)
00125                         {
00126                                 if (ServerInstance->XLines->AddLine(r, user))
00127                                 {
00128                                         if (!duration)
00129                                         {
00130                                                 ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent CBan for %s: %s", user->nick.c_str(), parameters[0].c_str(), parameters[2].c_str());
00131                                         }
00132                                         else
00133                                         {
00134                                                 time_t c_requires_crap = duration + ServerInstance->Time();
00135                                                 ServerInstance->SNO->WriteToSnoMask('x', "%s added timed CBan for %s, expires on %s: %s", user->nick.c_str(), parameters[0].c_str(), ServerInstance->TimeString(c_requires_crap).c_str(), parameters[2].c_str());
00136                                         }
00137 
00138                                         ServerInstance->XLines->ApplyLines();
00139                                 }
00140                                 else
00141                                 {
00142                                         delete r;
00143                                         user->WriteServ("NOTICE %s :*** CBan for %s already exists", user->nick.c_str(), parameters[0].c_str());
00144                                 }
00145                         }
00146                 }
00147 
00148                 return CMD_FAILURE;
00149         }
00150 };
00151 
00152 class ModuleCBan : public Module
00153 {
00154         CommandCBan* mycommand;
00155         CBanFactory *f;
00156 
00157  public:
00158         ModuleCBan(InspIRCd* Me) : Module(Me)
00159         {
00160                 f = new CBanFactory(ServerInstance);
00161                 ServerInstance->XLines->RegisterFactory(f);
00162 
00163                 mycommand = new CommandCBan(Me);
00164                 ServerInstance->AddCommand(mycommand);
00165                 Implementation eventlist[] = { I_OnUserPreJoin, I_OnSyncOtherMetaData, I_OnDecodeMetaData, I_OnStats };
00166                 ServerInstance->Modules->Attach(eventlist, this, 4);
00167         }
00168 
00169         virtual ~ModuleCBan()
00170         {
00171                 ServerInstance->XLines->DelAll("CBAN");
00172                 ServerInstance->XLines->UnregisterFactory(f);
00173         }
00174 
00175         virtual int OnStats(char symbol, User* user, string_list &out)
00176         {
00177                 if (symbol != 'C')
00178                         return 0;
00179 
00180                 ServerInstance->XLines->InvokeStats("CBAN", 210, user, out);
00181                 return 1;
00182         }
00183 
00184         virtual int OnUserPreJoin(User *user, Channel *chan, const char *cname, std::string &privs, const std::string &keygiven)
00185         {
00186                 XLine *rl = ServerInstance->XLines->MatchesLine("CBAN", cname);
00187 
00188                 if (rl)
00189                 {
00190                         // Channel is banned.
00191                         user->WriteServ( "384 %s %s :Cannot join channel, CBANed (%s)", user->nick.c_str(), cname, rl->reason);
00192                         ServerInstance->SNO->WriteToSnoMask('A', "%s tried to join %s which is CBANed (%s)", user->nick.c_str(), cname, rl->reason);
00193                         return 1;
00194                 }
00195 
00196                 return 0;
00197         }
00198 
00199         virtual Version GetVersion()
00200         {
00201                 return Version("$Id: m_cban.cpp 10741 2008-10-28 16:11:20Z w00t $", VF_COMMON | VF_VENDOR, API_VERSION);
00202         }
00203 };
00204 
00205 MODULE_INIT(ModuleCBan)
00206