]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_dccallow.cpp
Fix dccallow to work with files with spaces in their names
[user/henk/code/inspircd.git] / src / modules / m_dccallow.cpp
index 68fee4a19f2c271fbc7a728563b6393552cdf3c8..05fff89377f5c09f6d2faf1a097eaf70c0c2040c 100644 (file)
@@ -58,9 +58,10 @@ SimpleExtItem<dccallowlist>* ext;
 class CommandDccallow : public Command
 {
  public:
+       unsigned int maxentries;
        CommandDccallow(Module* parent) : Command(parent, "DCCALLOW", 0)
        {
-               syntax = "{[+|-]<nick> <time>|HELP|LIST}";
+               syntax = "[(+|-)<nick> [<time>]]|[LIST|HELP]";
                /* XXX we need to fix this so it can work with translation stuff (i.e. move +- into a seperate param */
        }
 
@@ -140,6 +141,12 @@ class CommandDccallow : public Command
                                                ul.push_back(user);
                                        }
 
+                                       if (dl->size() >= maxentries)
+                                       {
+                                               user->WriteNumeric(996, "%s %s :Too many nicks on DCCALLOW list", user->nick.c_str(), user->nick.c_str());
+                                               return CMD_FAILURE;
+                                       }
+
                                        for (dccallowlist::const_iterator k = dl->begin(); k != dl->end(); ++k)
                                        {
                                                if (k->nickname == target->nick)
@@ -166,7 +173,7 @@ class CommandDccallow : public Command
                                                length = ServerInstance->Duration(parameters[1]);
                                        }
 
-                                       if (!ServerInstance->IsValidMask(mask.c_str()))
+                                       if (!ServerInstance->IsValidMask(mask))
                                        {
                                                return CMD_FAILURE;
                                        }
@@ -203,7 +210,7 @@ class CommandDccallow : public Command
 
        void DisplayHelp(User* user)
        {
-               user->WriteNumeric(998, "%s :DCCALLOW [<+|->nick [time]] [list] [help]", user->nick.c_str());
+               user->WriteNumeric(998, "%s :DCCALLOW [(+|-)<nick> [<time>]]|[LIST|HELP]", user->nick.c_str());
                user->WriteNumeric(998, "%s :You may allow DCCs from specific users by specifying a", user->nick.c_str());
                user->WriteNumeric(998, "%s :DCC allow for the user you want to receive DCCs from.", user->nick.c_str());
                user->WriteNumeric(998, "%s :For example, to allow the user Brain to send you inspircd.exe", user->nick.c_str());
@@ -223,6 +230,10 @@ class CommandDccallow : public Command
                user->WriteNumeric(998, "%s :  they will be removed from your DCCALLOW list.", user->nick.c_str());
                user->WriteNumeric(998, "%s :  your DCCALLOW list will be deleted when you leave IRC.", user->nick.c_str());
                user->WriteNumeric(999, "%s :End of DCCALLOW HELP", user->nick.c_str());
+
+               LocalUser* localuser = IS_LOCAL(user);
+               if (localuser)
+                       localuser->CommandFloodPenalty += 4000;
        }
 
        void DisplayDCCAllowList(User* user)
@@ -258,16 +269,18 @@ class ModuleDCCAllow : public Module
        void init()
        {
                ext = new SimpleExtItem<dccallowlist>("dccallow", this);
-               ServerInstance->Extensions.Register(ext);
-               ServerInstance->AddCommand(&cmd);
-               ReadFileConf();
+               ServerInstance->Modules->AddService(*ext);
+               ServerInstance->Modules->AddService(cmd);
+               OnRehash(NULL);
                Implementation eventlist[] = { I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserQuit, I_OnUserPostNick, I_OnRehash };
-               ServerInstance->Modules->Attach(eventlist, this, 5);
+               ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
        }
 
        virtual void OnRehash(User* user)
        {
                ReadFileConf();
+               ConfigTag* tag = ServerInstance->Config->ConfValue("dccallow");
+               cmd.maxentries = tag->getInt("maxentries", 20);
        }
 
        virtual void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message)
@@ -327,23 +340,43 @@ class ModuleDCCAllow : public Module
                                                                return MOD_RES_PASSTHRU;
                                        }
 
-                                       // tokenize
-                                       std::stringstream ss(text);
-                                       std::string buf;
-                                       std::vector<std::string> tokens;
-
-                                       while (ss >> buf)
-                                               tokens.push_back(buf);
+                                       std::string buf = text.substr(5);
+                                       size_t s = buf.find(' ');
+                                       if (s == std::string::npos)
+                                               return MOD_RES_PASSTHRU;
 
-                                       irc::string type = tokens[1].c_str();
+                                       irc::string type = assign(buf.substr(0, s));
 
                                        ConfigTag* conftag = ServerInstance->Config->ConfValue("dccallow");
                                        bool blockchat = conftag->getBool("blockchat");
 
                                        if (type == "SEND")
                                        {
+                                               size_t first;
+
+                                               buf = buf.substr(s + 1);
+
+                                               if (!buf.empty() && buf[0] == '"')
+                                               {
+                                                       s = buf.find('"', 1);
+
+                                                       if (s == std::string::npos || s <= 1)
+                                                               return MOD_RES_PASSTHRU;
+
+                                                       --s;
+                                                       first = 1;
+                                               }
+                                               else
+                                               {
+                                                       s = buf.find(' ');
+                                                       first = 0;
+                                               }
+
+                                               if (s == std::string::npos)
+                                                       return MOD_RES_PASSTHRU;
+
                                                std::string defaultaction = conftag->getString("action");
-                                               std::string filename = tokens[2];
+                                               std::string filename = buf.substr(first, s);
 
                                                bool found = false;
                                                for (unsigned int i = 0; i < bfl.size(); i++)