]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_dccallow.cpp
Extbans can be VF_OPTCOMMON as they do not desync on module add/remove
[user/henk/code/inspircd.git] / src / modules / m_dccallow.cpp
index 22df5aa7ed2f05de80077a96c7e198af14889739..68090a8c3b602309c60ba652a21e34bf25cf6c81 100644 (file)
@@ -2,7 +2,7 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
  * See: http://wiki.inspircd.org/Credits
  *
  * This program is free but copyrighted software; see
 
 /* $ModDesc: Povides support for the /DCCALLOW command */
 
-static ConfigReader *Conf;
-
-class BannedFileList : public classbase
+class BannedFileList
 {
  public:
        std::string filemask;
        std::string action;
 };
 
-class DCCAllow : public classbase
+class DCCAllow
 {
  public:
        std::string nickname;
@@ -43,13 +41,13 @@ typedef std::vector<DCCAllow> dccallowlist;
 dccallowlist* dl;
 typedef std::vector<BannedFileList> bannedfilelist;
 bannedfilelist bfl;
+SimpleExtItem<dccallowlist>* ext;
 
 class CommandDccallow : public Command
 {
  public:
-       CommandDccallow(InspIRCd* Me) : Command(Me, "DCCALLOW", 0, 0)
+       CommandDccallow(Module* parent) : Command(parent, "DCCALLOW", 0)
        {
-               this->source = "m_dccallow.so";
                syntax = "{[+|-]<nick> <time>|HELP|LIST}";
                /* XXX we need to fix this so it can work with translation stuff (i.e. move +- into a seperate param */
        }
@@ -98,7 +96,8 @@ class CommandDccallow : public Command
                                if (action == '-')
                                {
                                        // check if it contains any entries
-                                       if (user->GetExt("dccallow_list", dl))
+                                       dl = ext->get(user);
+                                       if (dl)
                                        {
                                                for (dccallowlist::iterator i = dl->begin(); i != dl->end(); ++i)
                                                {
@@ -111,22 +110,6 @@ class CommandDccallow : public Command
                                                        }
                                                }
                                        }
-                                       else
-                                       {
-                                               delete  dl;
-                                               user->Shrink("dccallow_list");
-
-                                               // remove from userlist
-                                               for (userlist::iterator j = ul.begin(); j != ul.end(); ++j)
-                                               {
-                                                       User* u = (User*)(*j);
-                                                       if (u == user)
-                                                       {
-                                                               ul.erase(j);
-                                                               break;
-                                                       }
-                                               }
-                                       }
                                }
                                else if (action == '+')
                                {
@@ -136,10 +119,11 @@ class CommandDccallow : public Command
                                                return CMD_FAILURE;
                                        }
 
-                                       if (!user->GetExt("dccallow_list", dl))
+                                       dl = ext->get(user);
+                                       if (!dl)
                                        {
                                                dl = new dccallowlist;
-                                               user->Extend("dccallow_list", dl);
+                                               ext->set(user, dl);
                                                // add this user to the userlist
                                                ul.push_back(user);
                                        }
@@ -154,7 +138,8 @@ class CommandDccallow : public Command
                                        }
 
                                        std::string mask = std::string(target->nick)+"!"+std::string(target->ident)+"@"+std::string(target->dhost);
-                                       std::string default_length = Conf->ReadValue("dccallow", "length", 0);
+                                       ConfigReader Conf;
+                                       std::string default_length = Conf.ReadValue("dccallow", "length", 0);
 
                                        long length;
                                        if (parameters.size() < 2)
@@ -200,6 +185,11 @@ class CommandDccallow : public Command
                return CMD_FAILURE;
        }
 
+       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       {
+               return ROUTE_BROADCAST;
+       }
+
        void DisplayHelp(User* user)
        {
                user->WriteNumeric(998, "%s :DCCALLOW [<+|->nick [time]] [list] [help]", user->nick.c_str());
@@ -229,7 +219,8 @@ class CommandDccallow : public Command
                 // display current DCCALLOW list
                user->WriteNumeric(990, "%s :Users on your DCCALLOW list:", user->nick.c_str());
 
-               if (user->GetExt("dccallow_list", dl))
+               dl = ext->get(user);
+               if (dl)
                {
                        for (dccallowlist::const_iterator c = dl->begin(); c != dl->end(); ++c)
                        {
@@ -244,36 +235,33 @@ class CommandDccallow : public Command
 
 class ModuleDCCAllow : public Module
 {
-       CommandDccallow* mycommand;
+       CommandDccallow cmd;
  public:
 
-       ModuleDCCAllow(InspIRCd* Me)
-               : Module(Me)
+       ModuleDCCAllow()
+               : cmd(this)
        {
-               Conf = new ConfigReader(ServerInstance);
-               mycommand = new CommandDccallow(ServerInstance);
-               ServerInstance->AddCommand(mycommand);
+               ext = new SimpleExtItem<dccallowlist>("dccallow", this);
+               ServerInstance->Extensions.Register(ext);
+               ServerInstance->AddCommand(&cmd);
                ReadFileConf();
                Implementation eventlist[] = { I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserQuit, I_OnUserPreNick, I_OnRehash };
                ServerInstance->Modules->Attach(eventlist, this, 5);
        }
 
 
-       virtual void OnRehash(User* user, const std::string &parameter)
+       virtual void OnRehash(User* user)
        {
-               delete Conf;
-               Conf = new ConfigReader(ServerInstance);
+               ReadFileConf();
        }
 
        virtual void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message)
        {
-               dccallowlist* udl;
+               dccallowlist* udl = ext->get(user);
 
                // remove their DCCALLOW list if they have one
-               if (user->GetExt("dccallow_list", udl))
+               if (udl)
                {
-                       delete udl;
-                       user->Shrink("dccallow_list");
                        RemoveFromUserlist(user);
                }
 
@@ -282,22 +270,21 @@ class ModuleDCCAllow : public Module
                RemoveNick(user);
        }
 
-
-       virtual int OnUserPreNick(User* user, const std::string &newnick)
+       virtual ModResult OnUserPreNick(User* user, const std::string &newnick)
        {
                RemoveNick(user);
-               return 0;
+               return MOD_RES_PASSTHRU;
        }
 
-       virtual int OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list)
+       virtual ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list)
        {
                return OnUserPreNotice(user, dest, target_type, text, status, exempt_list);
        }
 
-       virtual int OnUserPreNotice(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list)
+       virtual ModResult OnUserPreNotice(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list)
        {
                if (!IS_LOCAL(user))
-                       return 0;
+                       return MOD_RES_PASSTHRU;
 
                if (target_type == TYPE_USER)
                {
@@ -305,7 +292,7 @@ class ModuleDCCAllow : public Module
 
                        /* Always allow a user to dcc themselves (although... why?) */
                        if (user == u)
-                               return 0;
+                               return MOD_RES_PASSTHRU;
 
                        if ((text.length()) && (text[0] == '\1'))
                        {
@@ -316,11 +303,12 @@ class ModuleDCCAllow : public Module
 
                                if (strncmp(text.c_str(), "\1DCC ", 5) == 0)
                                {
-                                       if (u->GetExt("dccallow_list", dl) && dl->size())
+                                       dl = ext->get(u);
+                                       if (dl && dl->size())
                                        {
                                                for (dccallowlist::const_iterator iter = dl->begin(); iter != dl->end(); ++iter)
                                                        if (InspIRCd::Match(user->GetFullHost(), iter->hostmask))
-                                                               return 0;
+                                                               return MOD_RES_PASSTHRU;
                                        }
 
                                        // tokenize
@@ -333,46 +321,50 @@ class ModuleDCCAllow : public Module
 
                                        irc::string type = tokens[1].c_str();
 
-                                       bool blockchat = Conf->ReadFlag("dccallow", "blockchat", 0);
+                                       ConfigReader Conf;
+                                       bool blockchat = Conf.ReadFlag("dccallow", "blockchat", 0);
 
                                        if (type == "SEND")
                                        {
-                                               std::string defaultaction = Conf->ReadValue("dccallow", "action", 0);
+                                               std::string defaultaction = Conf.ReadValue("dccallow", "action", 0);
                                                std::string filename = tokens[2];
 
-                                               if (defaultaction == "allow")
-                                                       return 0;
-
+                                               bool found = false;
                                                for (unsigned int i = 0; i < bfl.size(); i++)
                                                {
                                                        if (InspIRCd::Match(filename, bfl[i].filemask, ascii_case_insensitive_map))
                                                        {
+                                                               /* We have a matching badfile entry, override whatever the default action is */
                                                                if (bfl[i].action == "allow")
-                                                                       return 0;
-                                                       }
-                                                       else
-                                                       {
-                                                               if (defaultaction == "allow")
-                                                                       return 0;
+                                                                       return MOD_RES_PASSTHRU;
+                                                               else
+                                                               {
+                                                                       found = true;
+                                                                       break;
+                                                               }
                                                        }
                                                }
 
+                                               /* only follow the default action if no badfile matches were found above */
+                                               if ((!found) && (defaultaction == "allow"))
+                                                       return MOD_RES_PASSTHRU;
+
                                                user->WriteServ("NOTICE %s :The user %s is not accepting DCC SENDs from you. Your file %s was not sent.", user->nick.c_str(), u->nick.c_str(), filename.c_str());
                                                u->WriteServ("NOTICE %s :%s (%s@%s) attempted to send you a file named %s, which was blocked.", u->nick.c_str(), user->nick.c_str(), user->ident.c_str(), user->dhost.c_str(), filename.c_str());
                                                u->WriteServ("NOTICE %s :If you trust %s and were expecting this, you can type /DCCALLOW HELP for information on the DCCALLOW system.", u->nick.c_str(), user->nick.c_str());
-                                               return 1;
+                                               return MOD_RES_DENY;
                                        }
                                        else if ((type == "CHAT") && (blockchat))
                                        {
                                                user->WriteServ("NOTICE %s :The user %s is not accepting DCC CHAT requests from you.", user->nick.c_str(), u->nick.c_str());
                                                u->WriteServ("NOTICE %s :%s (%s@%s) attempted to initiate a DCC CHAT session, which was blocked.", u->nick.c_str(), user->nick.c_str(), user->ident.c_str(), user->dhost.c_str());
                                                u->WriteServ("NOTICE %s :If you trust %s and were expecting this, you can type /DCCALLOW HELP for information on the DCCALLOW system.", u->nick.c_str(), user->nick.c_str());
-                                               return 1;
+                                               return MOD_RES_DENY;
                                        }
                                }
                        }
                }
-               return 0;
+               return MOD_RES_PASSTHRU;
        }
 
        void Expire()
@@ -380,7 +372,8 @@ class ModuleDCCAllow : public Module
                for (userlist::iterator iter = ul.begin(); iter != ul.end(); ++iter)
                {
                        User* u = (User*)(*iter);
-                       if (u->GetExt("dccallow_list", dl))
+                       dl = ext->get(u);
+                       if (dl)
                        {
                                if (dl->size())
                                {
@@ -412,7 +405,8 @@ class ModuleDCCAllow : public Module
                for (userlist::iterator iter = ul.begin(); iter != ul.end(); ++iter)
                {
                        User *u = (User*)(*iter);
-                       if (u->GetExt("dccallow_list", dl))
+                       dl = ext->get(u);
+                       if (dl)
                        {
                                if (dl->size())
                                {
@@ -452,12 +446,13 @@ class ModuleDCCAllow : public Module
 
        void ReadFileConf()
        {
+               ConfigReader Conf;
                bfl.clear();
-               for (int i = 0; i < Conf->Enumerate("banfile"); i++)
+               for (int i = 0; i < Conf.Enumerate("banfile"); i++)
                {
                        BannedFileList bf;
-                       std::string fileglob = Conf->ReadValue("banfile", "pattern", i);
-                       std::string action = Conf->ReadValue("banfile", "action", i);
+                       std::string fileglob = Conf.ReadValue("banfile", "pattern", i);
+                       std::string action = Conf.ReadValue("banfile", "action", i);
                        bf.filemask = fileglob;
                        bf.action = action;
                        bfl.push_back(bf);
@@ -467,11 +462,12 @@ class ModuleDCCAllow : public Module
 
        virtual ~ModuleDCCAllow()
        {
+               delete ext;
        }
 
        virtual Version GetVersion()
        {
-               return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
+               return Version("Povides support for the /DCCALLOW command", VF_COMMON | VF_VENDOR);
        }
 };