]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_dccallow.cpp
Some more text fixes and improvements (#1618).
[user/henk/code/inspircd.git] / src / modules / m_dccallow.cpp
index edf9d012f72277171a5803713d0341c5dd666279..e0ea4c7aeed89e7d20ab38cdc05bb0320e4e8ff5 100644 (file)
 
 #include "inspircd.h"
 
+enum
+{
+       // From ircd-ratbox.
+       RPL_HELPSTART = 704,
+       RPL_HELPTXT = 705,
+       RPL_ENDOFHELP = 706,
+
+       // InspIRCd-specific?
+       RPL_DCCALLOWSTART = 990,
+       RPL_DCCALLOWLIST = 991,
+       RPL_DCCALLOWEND = 992,
+       RPL_DCCALLOWTIMED = 993,
+       RPL_DCCALLOWPERMANENT = 994,
+       RPL_DCCALLOWREMOVED = 995,
+       ERR_DCCALLOWINVALID = 996,
+       RPL_DCCALLOWEXPIRED = 997,
+       ERR_UNKNOWNDCCALLOWCMD = 998
+};
+
 static const char* const helptext[] =
 {
-       "DCCALLOW [(+|-)<nick> [<time>]]|[LIST|HELP]",
        "You may allow DCCs from specific users by specifying a",
        "DCC allow for the user you want to receive DCCs from.",
        "For example, to allow the user Brain to send you inspircd.exe",
@@ -36,7 +54,7 @@ static const char* const helptext[] =
        "Brain would then be able to send you files. They would have to",
        "resend the file again if the server gave them an error message",
        "before you added them to your DCCALLOW list.",
-       "DCCALLOW entries will be temporary by default, if you want to add",
+       "DCCALLOW entries will be temporary. If you want to add",
        "them to your DCCALLOW list until you leave IRC, type:",
        "/DCCALLOW +Brain 0",
        "To remove the user from your DCCALLOW list, type:",
@@ -45,7 +63,7 @@ static const char* const helptext[] =
        "/DCCALLOW LIST",
        "NOTE: If the user leaves IRC or changes their nickname",
        "  they will be removed from your DCCALLOW list.",
-       "  your DCCALLOW list will be deleted when you leave IRC."
+       "  Your DCCALLOW list will be deleted when you leave IRC."
 };
 
 class BannedFileList
@@ -61,11 +79,17 @@ class DCCAllow
        std::string nickname;
        std::string hostmask;
        time_t set_on;
-       long length;
+       unsigned long length;
 
        DCCAllow() { }
 
-       DCCAllow(const std::string &nick, const std::string &hm, const time_t so, const long ln) : nickname(nick), hostmask(hm), set_on(so), length(ln) { }
+       DCCAllow(const std::string& nick, const std::string& hm, time_t so, unsigned long ln)
+               : nickname(nick)
+               , hostmask(hm)
+               , set_on(so)
+               , length(ln)
+       {
+       }
 };
 
 typedef std::vector<User *> userlist;
@@ -82,6 +106,7 @@ class CommandDccallow : public Command
 
  public:
        unsigned int maxentries;
+       unsigned long defaultlength;
        CommandDccallow(Module* parent, DCCAllowExt& Ext)
                : Command(parent, "DCCALLOW", 0)
                , ext(Ext)
@@ -90,9 +115,9 @@ class CommandDccallow : public Command
                /* XXX we need to fix this so it can work with translation stuff (i.e. move +- into a seperate param */
        }
 
-       CmdResult Handle(const std::vector<std::string> &parameters, User *user)
+       CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
        {
-               /* syntax: DCCALLOW [+|-]<nick> (<time>) */
+               /* syntax: DCCALLOW [(+|-)<nick> [<time>]]|[LIST|HELP] */
                if (!parameters.size())
                {
                        // display current DCCALLOW list
@@ -120,7 +145,7 @@ class CommandDccallow : public Command
                                }
                                else
                                {
-                                       user->WriteNumeric(998, "DCCALLOW command not understood. For help on DCCALLOW, type /DCCALLOW HELP");
+                                       user->WriteNumeric(ERR_UNKNOWNDCCALLOWCMD, "DCCALLOW command not understood. For help on DCCALLOW, type /DCCALLOW HELP");
                                        return CMD_FAILURE;
                                }
                        }
@@ -143,7 +168,7 @@ class CommandDccallow : public Command
                                                        if (i->nickname == target->nick)
                                                        {
                                                                dl->erase(i);
-                                                               user->WriteNumeric(995, user->nick, InspIRCd::Format("Removed %s from your DCCALLOW list", target->nick.c_str()));
+                                                               user->WriteNumeric(RPL_DCCALLOWREMOVED, user->nick, InspIRCd::Format("Removed %s from your DCCALLOW list", target->nick.c_str()));
                                                                break;
                                                        }
                                                }
@@ -153,7 +178,7 @@ class CommandDccallow : public Command
                                {
                                        if (target == user)
                                        {
-                                               user->WriteNumeric(996, user->nick, "You cannot add yourself to your own DCCALLOW list!");
+                                               user->WriteNumeric(ERR_DCCALLOWINVALID, user->nick, "You cannot add yourself to your own DCCALLOW list!");
                                                return CMD_FAILURE;
                                        }
 
@@ -168,7 +193,7 @@ class CommandDccallow : public Command
 
                                        if (dl->size() >= maxentries)
                                        {
-                                               user->WriteNumeric(996, user->nick, "Too many nicks on DCCALLOW list");
+                                               user->WriteNumeric(ERR_DCCALLOWINVALID, user->nick, "Too many nicks on DCCALLOW list");
                                                return CMD_FAILURE;
                                        }
 
@@ -176,26 +201,29 @@ class CommandDccallow : public Command
                                        {
                                                if (k->nickname == target->nick)
                                                {
-                                                       user->WriteNumeric(996, user->nick, InspIRCd::Format("%s is already on your DCCALLOW list", target->nick.c_str()));
+                                                       user->WriteNumeric(ERR_DCCALLOWINVALID, user->nick, InspIRCd::Format("%s is already on your DCCALLOW list", target->nick.c_str()));
                                                        return CMD_FAILURE;
                                                }
                                        }
 
-                                       std::string mask = target->nick+"!"+target->ident+"@"+target->dhost;
-                                       std::string default_length = ServerInstance->Config->ConfValue("dccallow")->getString("length");
-
+                                       std::string mask = target->nick+"!"+target->ident+"@"+target->GetDisplayedHost();
                                        unsigned long length;
                                        if (parameters.size() < 2)
                                        {
-                                               length = InspIRCd::Duration(default_length);
+                                               length = defaultlength;
                                        }
-                                       else if (!atoi(parameters[1].c_str()))
+                                       else if (!InspIRCd::IsValidDuration(parameters[1]))
                                        {
-                                               length = 0;
+                                               user->WriteNumeric(ERR_DCCALLOWINVALID, user->nick, InspIRCd::Format("%s is not a valid DCCALLOW duration", parameters[1].c_str()));
+                                               return CMD_FAILURE;
                                        }
                                        else
                                        {
-                                               length = InspIRCd::Duration(parameters[1]);
+                                               if (!InspIRCd::Duration(parameters[1], length))
+                                               {
+                                                       user->WriteNotice("*** Invalid duration for DCC allow");
+                                                       return CMD_FAILURE;
+                                               }
                                        }
 
                                        if (!InspIRCd::IsValidMask(mask))
@@ -207,11 +235,11 @@ class CommandDccallow : public Command
 
                                        if (length > 0)
                                        {
-                                               user->WriteNumeric(993, user->nick, InspIRCd::Format("Added %s to DCCALLOW list for %ld seconds", target->nick.c_str(), length));
+                                               user->WriteNumeric(RPL_DCCALLOWTIMED, user->nick, InspIRCd::Format("Added %s to DCCALLOW list for %s", target->nick.c_str(), InspIRCd::DurationString(length).c_str()));
                                        }
                                        else
                                        {
-                                               user->WriteNumeric(994, user->nick, InspIRCd::Format("Added %s to DCCALLOW list for this session", target->nick.c_str()));
+                                               user->WriteNumeric(RPL_DCCALLOWPERMANENT, user->nick, InspIRCd::Format("Added %s to DCCALLOW list for this session", target->nick.c_str()));
                                        }
 
                                        /* route it. */
@@ -228,16 +256,17 @@ class CommandDccallow : public Command
                return CMD_FAILURE;
        }
 
-       RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+       RouteDescriptor GetRouting(User* user, const Params& parameters) CXX11_OVERRIDE
        {
                return ROUTE_BROADCAST;
        }
 
        void DisplayHelp(User* user)
        {
+               user->WriteNumeric(RPL_HELPSTART, "*", "DCCALLOW [(+|-)<nick> [<time>]]|[LIST|HELP]");
                for (size_t i = 0; i < sizeof(helptext)/sizeof(helptext[0]); i++)
-                       user->WriteNumeric(998, helptext[i]);
-               user->WriteNumeric(999, "End of DCCALLOW HELP");
+                       user->WriteNumeric(RPL_HELPTXT, "*", helptext[i]);
+               user->WriteNumeric(RPL_ENDOFHELP, "*", "End of DCCALLOW HELP");
 
                LocalUser* localuser = IS_LOCAL(user);
                if (localuser)
@@ -247,18 +276,18 @@ class CommandDccallow : public Command
        void DisplayDCCAllowList(User* user)
        {
                 // display current DCCALLOW list
-               user->WriteNumeric(990, "Users on your DCCALLOW list:");
+               user->WriteNumeric(RPL_DCCALLOWSTART, "Users on your DCCALLOW list:");
 
                dl = ext.get(user);
                if (dl)
                {
                        for (dccallowlist::const_iterator c = dl->begin(); c != dl->end(); ++c)
                        {
-                               user->WriteNumeric(991, user->nick, InspIRCd::Format("%s (%s)", c->nickname.c_str(), c->hostmask.c_str()));
+                               user->WriteNumeric(RPL_DCCALLOWLIST, user->nick, InspIRCd::Format("%s (%s)", c->nickname.c_str(), c->hostmask.c_str()));
                        }
                }
 
-               user->WriteNumeric(992, "End of DCCALLOW list");
+               user->WriteNumeric(RPL_DCCALLOWEND, "End of DCCALLOW list");
        }
 
 };
@@ -267,11 +296,14 @@ class ModuleDCCAllow : public Module
 {
        DCCAllowExt ext;
        CommandDccallow cmd;
+       bool blockchat;
+       std::string defaultaction;
 
  public:
        ModuleDCCAllow()
                : ext("dccallow", ExtensionItem::EXT_USER, this)
                , cmd(this, ext)
+               , blockchat(false)
        {
        }
 
@@ -293,27 +325,27 @@ class ModuleDCCAllow : public Module
                RemoveNick(user);
        }
 
-       ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list, MessageType msgtype) CXX11_OVERRIDE
+       ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE
        {
                if (!IS_LOCAL(user))
                        return MOD_RES_PASSTHRU;
 
-               if (target_type == TYPE_USER)
+               if (target.type == MessageTarget::TYPE_USER)
                {
-                       User* u = (User*)dest;
+                       User* u = target.Get<User>();
 
                        /* Always allow a user to dcc themselves (although... why?) */
                        if (user == u)
                                return MOD_RES_PASSTHRU;
 
-                       if ((text.length()) && (text[0] == '\1'))
+                       if ((details.text.length()) && (details.text[0] == '\1'))
                        {
                                Expire();
 
                                // :jamie!jamie@test-D4457903BA652E0F.silverdream.org PRIVMSG eimaj :DCC SEND m_dnsbl.cpp 3232235786 52650 9676
                                // :jamie!jamie@test-D4457903BA652E0F.silverdream.org PRIVMSG eimaj :VERSION
 
-                               if (strncmp(text.c_str(), "\1DCC ", 5) == 0)
+                               if (strncmp(details.text.c_str(), "\1DCC ", 5) == 0)
                                {
                                        dl = ext.get(u);
                                        if (dl && dl->size())
@@ -323,16 +355,13 @@ class ModuleDCCAllow : public Module
                                                                return MOD_RES_PASSTHRU;
                                        }
 
-                                       std::string buf = text.substr(5);
+                                       std::string buf = details.text.substr(5);
                                        size_t s = buf.find(' ');
                                        if (s == std::string::npos)
                                                return MOD_RES_PASSTHRU;
 
                                        const std::string type = buf.substr(0, s);
 
-                                       ConfigTag* conftag = ServerInstance->Config->ConfValue("dccallow");
-                                       bool blockchat = conftag->getBool("blockchat");
-
                                        if (stdalgo::string::equalsci(type, "SEND"))
                                        {
                                                size_t first;
@@ -358,7 +387,6 @@ class ModuleDCCAllow : public Module
                                                if (s == std::string::npos)
                                                        return MOD_RES_PASSTHRU;
 
-                                               std::string defaultaction = conftag->getString("action");
                                                std::string filename = buf.substr(first, s);
 
                                                bool found = false;
@@ -367,7 +395,7 @@ class ModuleDCCAllow : public Module
                                                        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")
+                                                               if (stdalgo::string::equalsci(bfl[i].action, "allow"))
                                                                        return MOD_RES_PASSTHRU;
                                                                else
                                                                {
@@ -382,14 +410,14 @@ class ModuleDCCAllow : public Module
                                                        return MOD_RES_PASSTHRU;
 
                                                user->WriteNotice("The user " + u->nick + " is not accepting DCC SENDs from you. Your file " + filename + " was not sent.");
-                                               u->WriteNotice(user->nick + " (" + user->ident + "@" + user->dhost + ") attempted to send you a file named " + filename + ", which was blocked.");
+                                               u->WriteNotice(user->nick + " (" + user->ident + "@" + user->GetDisplayedHost() + ") attempted to send you a file named " + filename + ", which was blocked.");
                                                u->WriteNotice("If you trust " + user->nick + " and were expecting this, you can type /DCCALLOW HELP for information on the DCCALLOW system.");
                                                return MOD_RES_DENY;
                                        }
                                        else if ((blockchat) && (stdalgo::string::equalsci(type, "CHAT")))
                                        {
                                                user->WriteNotice("The user " + u->nick + " is not accepting DCC CHAT requests from you.");
-                                               u->WriteNotice(user->nick + " (" + user->ident + "@" + user->dhost + ") attempted to initiate a DCC CHAT session, which was blocked.");
+                                               u->WriteNotice(user->nick + " (" + user->ident + "@" + user->GetDisplayedHost() + ") attempted to initiate a DCC CHAT session, which was blocked.");
                                                u->WriteNotice("If you trust " + user->nick + " and were expecting this, you can type /DCCALLOW HELP for information on the DCCALLOW system.");
                                                return MOD_RES_DENY;
                                        }
@@ -412,9 +440,10 @@ class ModuleDCCAllow : public Module
                                        dccallowlist::iterator iter2 = dl->begin();
                                        while (iter2 != dl->end())
                                        {
-                                               if (iter2->length != 0 && (iter2->set_on + iter2->length) <= ServerInstance->Time())
+                                               time_t expires = iter2->set_on + iter2->length;
+                                               if (iter2->length != 0 && expires <= ServerInstance->Time())
                                                {
-                                                       u->WriteNumeric(997, u->nick, InspIRCd::Format("DCCALLOW entry for %s has expired", iter2->nickname.c_str()));
+                                                       u->WriteNumeric(RPL_DCCALLOWEXPIRED, u->nick, InspIRCd::Format("DCCALLOW entry for %s has expired", iter2->nickname.c_str()));
                                                        iter2 = dl->erase(iter2);
                                                }
                                                else
@@ -449,7 +478,7 @@ class ModuleDCCAllow : public Module
                                                {
 
                                                        u->WriteNotice(i->nickname + " left the network or changed their nickname and has been removed from your DCCALLOW list");
-                                                       u->WriteNumeric(995, u->nick, InspIRCd::Format("Removed %s from your DCCALLOW list", i->nickname.c_str()));
+                                                       u->WriteNumeric(RPL_DCCALLOWREMOVED, u->nick, InspIRCd::Format("Removed %s from your DCCALLOW list", i->nickname.c_str()));
                                                        dl->erase(i);
                                                        break;
                                                }
@@ -480,23 +509,27 @@ class ModuleDCCAllow : public Module
 
        void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
        {
-               ConfigTag* tag = ServerInstance->Config->ConfValue("dccallow");
-               cmd.maxentries = tag->getInt("maxentries", 20);
-
-               bfl.clear();
+               bannedfilelist newbfl;
                ConfigTagList tags = ServerInstance->Config->ConfTags("banfile");
                for (ConfigIter i = tags.first; i != tags.second; ++i)
                {
                        BannedFileList bf;
                        bf.filemask = i->second->getString("pattern");
                        bf.action = i->second->getString("action");
-                       bfl.push_back(bf);
+                       newbfl.push_back(bf);
                }
+               bfl.swap(newbfl);
+
+               ConfigTag* tag = ServerInstance->Config->ConfValue("dccallow");
+               cmd.maxentries = tag->getUInt("maxentries", 20);
+               cmd.defaultlength = tag->getDuration("length", 0);
+               blockchat = tag->getBool("blockchat");
+               defaultaction = tag->getString("action");
        }
 
        Version GetVersion() CXX11_OVERRIDE
        {
-               return Version("Provides support for the /DCCALLOW command", VF_COMMON | VF_VENDOR);
+               return Version("Provides the DCCALLOW command", VF_COMMON | VF_VENDOR);
        }
 };