diff options
| author | 2019-09-23 00:37:33 +0100 | |
|---|---|---|
| committer | 2019-09-23 00:37:33 +0100 | |
| commit | 8848169e8b42b5ed85837efd3b3f9e36ffbada1b (patch) | |
| tree | 04babb46ea381f254589b12288f121d53338cb67 /src/modules | |
| parent | Install libc++abi-dev on Travis. (diff) | |
| parent | Lower the acceptable drift for clocks on link. (diff) | |
Merge branch 'insp3' into master.
Diffstat (limited to 'src/modules')
| -rw-r--r-- | src/modules/extra/m_mysql.cpp | 58 | ||||
| -rw-r--r-- | src/modules/extra/m_pgsql.cpp | 2 | ||||
| -rw-r--r-- | src/modules/m_alias.cpp | 10 | ||||
| -rw-r--r-- | src/modules/m_chanfilter.cpp | 89 | ||||
| -rw-r--r-- | src/modules/m_cloaking.cpp | 24 | ||||
| -rw-r--r-- | src/modules/m_dccallow.cpp | 83 | ||||
| -rw-r--r-- | src/modules/m_delaymsg.cpp | 2 | ||||
| -rw-r--r-- | src/modules/m_haproxy.cpp | 27 | ||||
| -rw-r--r-- | src/modules/m_ircv3_servertime.cpp | 2 | ||||
| -rw-r--r-- | src/modules/m_noctcp.cpp | 8 | ||||
| -rw-r--r-- | src/modules/m_silence.cpp | 91 | ||||
| -rw-r--r-- | src/modules/m_spanningtree/treesocket2.cpp | 10 | ||||
| -rw-r--r-- | src/modules/m_xline_db.cpp | 4 |
13 files changed, 321 insertions, 89 deletions
diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp index 90ed1a82c..d3df58833 100644 --- a/src/modules/extra/m_mysql.cpp +++ b/src/modules/extra/m_mysql.cpp @@ -246,6 +246,31 @@ class MySQLresult : public SQL::Result */ class SQLConnection : public SQL::Provider { + private: + bool EscapeString(SQL::Query* query, const std::string& in, std::string& out) + { + // In the worst case each character may need to be encoded as using two bytes and one + // byte is the NUL terminator. + std::vector<char> buffer(in.length() * 2 + 1); + + // The return value of mysql_escape_string() is either an error or the length of the + // encoded string not including the NUL terminator. + // + // Unfortunately, someone genius decided that mysql_escape_string should return an + // unsigned type even though -1 is returned on error so checking whether an error + // happened is a bit cursed. + unsigned long escapedsize = mysql_escape_string(&buffer[0], in.c_str(), in.length()); + if (escapedsize == static_cast<unsigned long>(-1)) + { + SQL::Error err(SQL::QSEND_FAIL, InspIRCd::Format("%u: %s", mysql_errno(connection), mysql_error(connection))); + query->OnError(err); + return false; + } + + out.append(&buffer[0], escapedsize); + return true; + } + public: reference<ConfigTag> config; MYSQL *connection; @@ -349,21 +374,8 @@ class SQLConnection : public SQL::Provider { if (q[i] != '?') res.push_back(q[i]); - else - { - if (param < p.size()) - { - std::string parm = p[param++]; - // In the worst case, each character may need to be encoded as using two bytes, - // and one byte is the terminating null - std::vector<char> buffer(parm.length() * 2 + 1); - - // The return value of mysql_real_escape_string() is the length of the encoded string, - // not including the terminating null - unsigned long escapedsize = mysql_real_escape_string(connection, &buffer[0], parm.c_str(), parm.length()); - res.append(&buffer[0], escapedsize); - } - } + else if (param < p.size() && !EscapeString(call, p[param++], res)) + return; } Submit(call, res); } @@ -384,14 +396,8 @@ class SQLConnection : public SQL::Provider i--; SQL::ParamMap::const_iterator it = p.find(field); - if (it != p.end()) - { - std::string parm = it->second; - // NOTE: See above - std::vector<char> buffer(parm.length() * 2 + 1); - unsigned long escapedsize = mysql_escape_string(&buffer[0], parm.c_str(), parm.length()); - res.append(&buffer[0], escapedsize); - } + if (it != p.end() && !EscapeString(call, it->second, res)) + return; } } Submit(call, res); @@ -405,6 +411,9 @@ ModuleSQL::ModuleSQL() void ModuleSQL::init() { + if (mysql_library_init(0, NULL, NULL)) + throw ModuleException("Unable to initialise the MySQL library!"); + Dispatcher = new DispatcherThread(this); Dispatcher->Start(); } @@ -417,10 +426,13 @@ ModuleSQL::~ModuleSQL() Dispatcher->OnNotify(); delete Dispatcher; } + for(ConnMap::iterator i = connections.begin(); i != connections.end(); i++) { delete i->second; } + + mysql_library_end(); } void ModuleSQL::ReadConfig(ConfigStatus& status) diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp index 10ad2b968..ac285a8aa 100644 --- a/src/modules/extra/m_pgsql.cpp +++ b/src/modules/extra/m_pgsql.cpp @@ -103,7 +103,7 @@ class PgSQLresult : public SQL::Result { rows = PQntuples(res); if (!rows) - rows = atoi(PQcmdTuples(res)); + rows = ConvToNum<int>(PQcmdTuples(res)); } ~PgSQLresult() diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp index 1904af549..e3308b027 100644 --- a/src/modules/m_alias.cpp +++ b/src/modules/m_alias.cpp @@ -50,6 +50,9 @@ class Alias /** Format that must be matched for use */ std::string format; + + /** Strip color codes before match? */ + bool StripColor; }; class ModuleAlias : public Module @@ -94,6 +97,7 @@ class ModuleAlias : public Module a.UserCommand = tag->getBool("usercommand", true); a.OperOnly = tag->getBool("operonly"); a.format = tag->getString("format"); + a.StripColor = tag->getBool("stripcolor"); std::transform(a.AliasedCommand.begin(), a.AliasedCommand.end(), a.AliasedCommand.begin(), ::toupper); newAliases.insert(std::make_pair(a.AliasedCommand, a)); @@ -261,10 +265,14 @@ class ModuleAlias : public Module int DoAlias(User *user, Channel *c, Alias *a, const std::string& compare, const std::string& safe) { + std::string stripped(compare); + if (a->StripColor) + InspIRCd::StripColor(stripped); + /* Does it match the pattern? */ if (!a->format.empty()) { - if (!InspIRCd::Match(compare, a->format)) + if (!InspIRCd::Match(stripped, a->format)) return 0; } diff --git a/src/modules/m_chanfilter.cpp b/src/modules/m_chanfilter.cpp index 4b3721b12..da36c58cc 100644 --- a/src/modules/m_chanfilter.cpp +++ b/src/modules/m_chanfilter.cpp @@ -59,6 +59,25 @@ class ModuleChanFilter : public Module bool hidemask; bool notifyuser; + ChanFilter::ListItem* Match(User* user, Channel* chan, const std::string& text) + { + ModResult res = CheckExemption::Call(exemptionprov, user, chan, "filter"); + if (!IS_LOCAL(user) || res == MOD_RES_ALLOW) + return NULL; + + ListModeBase::ModeList* list = cf.GetList(chan); + if (!list) + return NULL; + + for (ListModeBase::ModeList::iterator i = list->begin(); i != list->end(); i++) + { + if (InspIRCd::Match(text, i->mask)) + return &*i; + } + + return NULL; + } + public: ModuleChanFilter() @@ -76,40 +95,62 @@ class ModuleChanFilter : public Module cf.DoRehash(); } + void OnUserPart(Membership* memb, std::string& partmessage, CUList& except_list) override + { + if (!memb) + return; + + User* user = memb->user; + Channel* chan = memb->chan; + ChanFilter::ListItem* match = Match(user, chan, partmessage); + if (!match) + return; + + // Match() checks the user is local, we can assume from here + LocalUser* luser = IS_LOCAL(user); + + std::string oldreason(partmessage); + partmessage = "Reason filtered"; + if (!notifyuser) + { + // Send fake part + ClientProtocol::Messages::Part partmsg(memb, oldreason); + ClientProtocol::Event ev(ServerInstance->GetRFCEvents().part, partmsg); + luser->Send(ev); + + // Don't send the user the changed message + except_list.insert(user); + return; + } + + if (hidemask) + user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your part message contained a censored word)"); + else + user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your part message contained a censored word: " + match->mask + ")"); + } + ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) override { if (target.type != MessageTarget::TYPE_CHANNEL) return MOD_RES_PASSTHRU; Channel* chan = target.Get<Channel>(); - ModResult res = CheckExemption::Call(exemptionprov, user, chan, "filter"); - - if (!IS_LOCAL(user) || res == MOD_RES_ALLOW) - return MOD_RES_PASSTHRU; - - ListModeBase::ModeList* list = cf.GetList(chan); - - if (list) + ChanFilter::ListItem* match = Match(user, chan, details.text); + if (match) { - for (ListModeBase::ModeList::iterator i = list->begin(); i != list->end(); i++) + if (!notifyuser) { - if (InspIRCd::Match(details.text, i->mask)) - { - if (!notifyuser) - { - details.echo_original = true; - return MOD_RES_DENY; - } - - if (hidemask) - user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your message contained a censored word)"); - else - user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your message contained a censored word: " + i->mask + ")"); - return MOD_RES_DENY; - } + details.echo_original = true; + return MOD_RES_DENY; } - } + if (hidemask) + user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your message contained a censored word)"); + else + user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your message contained a censored word: " + match->mask + ")"); + + return MOD_RES_DENY; + } return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index 7c8260174..64b3936b2 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -49,6 +49,9 @@ struct CloakInfo // The number of parts of the hostname shown when using half cloaking. unsigned int domainparts; + // Whether to ignore the case of a hostname when cloaking it. + bool ignorecase; + // The secret used for generating cloaks. std::string key; @@ -58,9 +61,10 @@ struct CloakInfo // The suffix for IP cloaks (e.g. .IP). std::string suffix; - CloakInfo(CloakMode Mode, const std::string& Key, const std::string& Prefix, const std::string& Suffix, unsigned int DomainParts = 0) + CloakInfo(CloakMode Mode, const std::string& Key, const std::string& Prefix, const std::string& Suffix, bool IgnoreCase, unsigned int DomainParts = 0) : mode(Mode) , domainparts(DomainParts) + , ignorecase(IgnoreCase) , key(Key) , prefix(Prefix) , suffix(Suffix) @@ -248,7 +252,10 @@ class ModuleCloaking : public Module input.append(1, id); input.append(info.key); input.append(1, '\0'); // null does not terminate a C++ string - input.append(item); + if (info.ignorecase) + std::transform(item.begin(), item.end(), std::back_inserter(input), ::tolower); + else + input.append(item); std::string rv = Hash->GenerateRaw(input).substr(0,len); for(size_t i = 0; i < len; i++) @@ -388,17 +395,17 @@ class ModuleCloaking : public Module { case MODE_HALF_CLOAK: // Use old cloaking verification to stay compatible with 2.0 - // But verify domainparts when use 3.0-only features - if (info.domainparts == 3) + // But verify domainparts and ignorecase when use 3.0-only features + if (info.domainparts == 3 && !info.ignorecase) testcloak = info.prefix + SegmentCloak(info, "*", 3, 8) + info.suffix; else { irc::sockets::sockaddrs sa; - testcloak = GenCloak(info, sa, "", testcloak + ConvToStr(info.domainparts)); + testcloak = GenCloak(info, sa, "", testcloak + ConvToStr(info.domainparts)) + (info.ignorecase ? "-ci" : ""); } break; case MODE_OPAQUE: - testcloak = info.prefix + SegmentCloak(info, "*", 4, 8) + info.suffix; + testcloak = info.prefix + SegmentCloak(info, "*", 4, 8) + info.suffix + (info.ignorecase ? "-ci" : ""); } } return Version("Provides masking of user hostnames", VF_COMMON|VF_VENDOR, testcloak); @@ -424,16 +431,17 @@ class ModuleCloaking : public Module if (i == tags.first && key.length() < minkeylen) throw ModuleException("Your cloaking key is not secure. It should be at least " + ConvToStr(minkeylen) + " characters long, at " + tag->getTagLocation()); + const bool ignorecase = tag->getBool("ignorecase"); const std::string mode = tag->getString("mode"); const std::string prefix = tag->getString("prefix"); const std::string suffix = tag->getString("suffix", ".IP"); if (stdalgo::string::equalsci(mode, "half")) { unsigned int domainparts = tag->getUInt("domainparts", 3, 1, 10); - newcloaks.push_back(CloakInfo(MODE_HALF_CLOAK, key, prefix, suffix, domainparts)); + newcloaks.push_back(CloakInfo(MODE_HALF_CLOAK, key, prefix, suffix, ignorecase, domainparts)); } else if (stdalgo::string::equalsci(mode, "full")) - newcloaks.push_back(CloakInfo(MODE_OPAQUE, key, prefix, suffix)); + newcloaks.push_back(CloakInfo(MODE_OPAQUE, key, prefix, suffix, ignorecase)); else throw ModuleException(mode + " is an invalid value for <cloak:mode>; acceptable values are 'half' and 'full', at " + tag->getTagLocation()); } diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index 13963fc0b..60d880cb6 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -98,14 +98,83 @@ typedef std::vector<DCCAllow> dccallowlist; dccallowlist* dl; typedef std::vector<BannedFileList> bannedfilelist; bannedfilelist bfl; -typedef SimpleExtItem<dccallowlist> DCCAllowExt; -class CommandDccallow : public Command +class DCCAllowExt : public SimpleExtItem<dccallowlist> { - DCCAllowExt& ext; - public: unsigned int maxentries; + + DCCAllowExt(Module* Creator) + : SimpleExtItem<dccallowlist>(Creator, "dccallow", ExtensionItem::EXT_USER) + { + } + + void FromInternal(Extensible* container, const std::string& value) override + { + LocalUser* user = IS_LOCAL(static_cast<User*>(container)); + if (!user) + return; + + // Remove the old list and create a new one. + unset(user); + dccallowlist* list = new dccallowlist(); + + irc::spacesepstream ts(value); + while (!ts.StreamEnd()) + { + // Check we have space for another entry. + if (list->size() >= maxentries) + { + ServerInstance->Logs.Log(MODNAME, LOG_DEBUG, "Oversized DCC allow list received for %s: %s", + user->uuid.c_str(), value.c_str()); + delete list; + return; + } + + // Extract the fields. + DCCAllow dccallow; + if (!ts.GetToken(dccallow.nickname) || + !ts.GetToken(dccallow.hostmask) || + !ts.GetNumericToken(dccallow.set_on) || + !ts.GetNumericToken(dccallow.length)) + { + ServerInstance->Logs.Log(MODNAME, LOG_DEBUG, "Malformed DCC allow list received for %s: %s", + user->uuid.c_str(), value.c_str()); + delete list; + return; + } + + // Store the DCC allow entry. + list->push_back(dccallow); + } + + } + + std::string ToInternal(const Extensible* container, void* item) const override + { + dccallowlist* list = static_cast<dccallowlist*>(item); + std::string buf; + for (dccallowlist::const_iterator iter = list->begin(); iter != list->end(); ++iter) + { + if (iter != list->begin()) + buf.push_back(' '); + + buf.append(iter->nickname); + buf.push_back(' '); + buf.append(iter->hostmask); + buf.push_back(' '); + buf.append(ConvToStr(iter->set_on)); + buf.push_back(' '); + buf.append(ConvToStr(iter->length)); + } + return buf; + } +}; + +class CommandDccallow : public Command +{ + public: + DCCAllowExt& ext; unsigned long defaultlength; CommandDccallow(Module* parent, DCCAllowExt& Ext) : Command(parent, "DCCALLOW", 0) @@ -191,7 +260,7 @@ class CommandDccallow : public Command ul.push_back(user); } - if (dl->size() >= maxentries) + if (dl->size() >= ext.maxentries) { user->WriteNumeric(ERR_DCCALLOWINVALID, user->nick, "Too many nicks on DCCALLOW list"); return CMD_FAILURE; @@ -301,7 +370,7 @@ class ModuleDCCAllow : public Module public: ModuleDCCAllow() - : ext(this, "dccallow", ExtensionItem::EXT_USER) + : ext(this) , cmd(this, ext) , blockchat(false) { @@ -521,7 +590,7 @@ class ModuleDCCAllow : public Module bfl.swap(newbfl); ConfigTag* tag = ServerInstance->Config->ConfValue("dccallow"); - cmd.maxentries = tag->getUInt("maxentries", 20); + cmd.ext.maxentries = tag->getUInt("maxentries", 20); cmd.defaultlength = tag->getDuration("length", 0); blockchat = tag->getBool("blockchat"); defaultaction = tag->getString("action"); diff --git a/src/modules/m_delaymsg.cpp b/src/modules/m_delaymsg.cpp index 3206d9b08..b99c3f6de 100644 --- a/src/modules/m_delaymsg.cpp +++ b/src/modules/m_delaymsg.cpp @@ -34,7 +34,7 @@ class DelayMsgMode : public ParamMode<DelayMsgMode, IntExtItem> bool ResolveModeConflict(std::string& their_param, const std::string& our_param, Channel*) override { - return (atoi(their_param.c_str()) < atoi(our_param.c_str())); + return ConvToNum<intptr_t>(their_param) < ConvToNum<intptr_t>(our_param); } ModeAction OnSet(User* source, Channel* chan, std::string& parameter) override; diff --git a/src/modules/m_haproxy.cpp b/src/modules/m_haproxy.cpp index 4f2d6cdbf..fcdb3ce9f 100644 --- a/src/modules/m_haproxy.cpp +++ b/src/modules/m_haproxy.cpp @@ -219,7 +219,16 @@ class HAProxyHook : public IOHookMiddle return true; } - int ReadProxyAddress(StreamSocket* sock) + int ReadData(std::string& destrecvq) + { + // Once connected we handle no special data. + std::string& recvq = GetRecvQ(); + destrecvq.append(recvq); + recvq.clear(); + return 1; + } + + int ReadProxyAddress(StreamSocket* sock, std::string& destrecvq) { // Block until we have the entire address. std::string& recvq = GetRecvQ(); @@ -276,14 +285,15 @@ class HAProxyHook : public IOHookMiddle // Erase the processed proxy information from the receive queue. recvq.erase(0, address_length); + break; } // We're done! state = HPS_CONNECTED; - return 1; + return ReadData(destrecvq); } - int ReadProxyHeader(StreamSocket* sock) + int ReadProxyHeader(StreamSocket* sock, std::string& destrecvq) { // Block until we have a header. std::string& recvq = GetRecvQ(); @@ -359,7 +369,7 @@ class HAProxyHook : public IOHookMiddle } state = HPS_WAITING_FOR_ADDRESS; - return ReadProxyAddress(sock); + return ReadProxyAddress(sock, destrecvq); } public: @@ -384,16 +394,13 @@ class HAProxyHook : public IOHookMiddle switch (state) { case HPS_WAITING_FOR_HEADER: - return ReadProxyHeader(sock); + return ReadProxyHeader(sock, destrecvq); case HPS_WAITING_FOR_ADDRESS: - return ReadProxyAddress(sock); + return ReadProxyAddress(sock, destrecvq); case HPS_CONNECTED: - std::string& recvq = GetRecvQ(); - destrecvq.append(recvq); - recvq.clear(); - return 1; + return ReadData(destrecvq); } // We should never reach this point. diff --git a/src/modules/m_ircv3_servertime.cpp b/src/modules/m_ircv3_servertime.cpp index 5fa099ece..943afb278 100644 --- a/src/modules/m_ircv3_servertime.cpp +++ b/src/modules/m_ircv3_servertime.cpp @@ -46,6 +46,8 @@ class ServerTimeTag } public: + using ServerProtocol::MessageEventListener::OnBuildMessage; + ServerTimeTag(Module* mod) : IRCv3::ServerTime::Manager(mod) , IRCv3::CapTag<ServerTimeTag>(mod, "server-time", "time") diff --git a/src/modules/m_noctcp.cpp b/src/modules/m_noctcp.cpp index 500c31dbc..ca1bffb10 100644 --- a/src/modules/m_noctcp.cpp +++ b/src/modules/m_noctcp.cpp @@ -67,6 +67,14 @@ class ModuleNoCTCP : public Module user->WriteNumeric(ERR_CANNOTSENDTOCHAN, c->name, "Can't send CTCP to channel (+C is set)"); return MOD_RES_DENY; } + + const Channel::MemberMap& members = c->GetUsers(); + for (Channel::MemberMap::const_iterator member = members.begin(); member != members.end(); ++member) + { + User* u = member->first; + if (u->IsModeSet(ncu)) + details.exemptions.insert(u); + } break; } case MessageTarget::TYPE_USER: diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp index b7c24b5e9..90212ef2b 100644 --- a/src/modules/m_silence.cpp +++ b/src/modules/m_silence.cpp @@ -180,6 +180,84 @@ class SilenceEntry typedef insp::flat_set<SilenceEntry> SilenceList; +class SilenceExtItem : public SimpleExtItem<SilenceList> +{ + public: + unsigned int maxsilence; + + SilenceExtItem(Module* Creator) + : SimpleExtItem<SilenceList>(Creator, "silence_list", ExtensionItem::EXT_USER) + { + } + + void FromInternal(Extensible* container, const std::string& value) override + { + LocalUser* user = IS_LOCAL(static_cast<User*>(container)); + if (!user) + return; + + // Remove the old list and create a new one. + unset(user); + SilenceList* list = new SilenceList(); + + irc::spacesepstream ts(value); + while (!ts.StreamEnd()) + { + // Check we have space for another entry. + if (list->size() >= maxsilence) + { + ServerInstance->Logs.Log(MODNAME, LOG_DEBUG, "Oversized silence list received for %s: %s", + user->uuid.c_str(), value.c_str()); + delete list; + return; + } + + // Extract the mask and the flags. + std::string mask; + std::string flagstr; + if (!ts.GetToken(mask) || !ts.GetToken(flagstr)) + { + ServerInstance->Logs.Log(MODNAME, LOG_DEBUG, "Malformed silence list received for %s: %s", + user->uuid.c_str(), value.c_str()); + delete list; + return; + } + + // Try to parse the flags. + uint32_t flags; + if (!SilenceEntry::FlagsToBits(flagstr, flags)) + { + ServerInstance->Logs.Log(MODNAME, LOG_DEBUG, "Malformed silence flags received for %s: %s", + user->uuid.c_str(), flagstr.c_str()); + delete list; + return; + } + + // Store the silence entry. + list->insert(SilenceEntry(flags, mask)); + } + + // The value was well formed. + set(user, list); + } + + std::string ToInternal(const Extensible* container, void* item) const override + { + SilenceList* list = static_cast<SilenceList*>(item); + std::string buf; + for (SilenceList::const_iterator iter = list->begin(); iter != list->end(); ++iter) + { + if (iter != list->begin()) + buf.push_back(' '); + + buf.append(iter->mask); + buf.push_back(' '); + buf.append(SilenceEntry::BitsToFlags(iter->flags)); + } + return buf; + } +}; + class SilenceMessage : public ClientProtocol::Message { public: @@ -199,7 +277,7 @@ class CommandSilence : public SplitCommand CmdResult AddSilence(LocalUser* user, const std::string& mask, uint32_t flags) { SilenceList* list = ext.get(user); - if (list && list->size() > maxsilence) + if (list && list->size() > ext.maxsilence) { user->WriteNumeric(ERR_SILELISTFULL, mask, SilenceEntry::BitsToFlags(flags), "Your SILENCE list is full"); return CMD_FAILURE; @@ -258,13 +336,12 @@ class CommandSilence : public SplitCommand } public: - SimpleExtItem<SilenceList> ext; - unsigned int maxsilence; + SilenceExtItem ext; CommandSilence(Module* Creator) : SplitCommand(Creator, "SILENCE") , msgprov(Creator, "SILENCE") - , ext(Creator, "silence_list", ExtensionItem::EXT_USER) + , ext(Creator) { allow_empty_last_param = false; syntax = "[(+|-)<mask> [CcdiNnPpTtx]]"; @@ -282,7 +359,7 @@ class CommandSilence : public SplitCommand std::string mask = parameters[0]; if (mask[0] == '-' || mask[0] == '+') { - mask.erase(0); + mask.erase(0, 1); if (mask.empty()) mask.assign("*"); ModeParser::CleanMask(mask); @@ -364,13 +441,13 @@ class ModuleSilence { ConfigTag* tag = ServerInstance->Config->ConfValue("silence"); exemptuline = tag->getBool("exemptuline", true); - cmd.maxsilence = tag->getUInt("maxentries", 32, 1); + cmd.ext.maxsilence = tag->getUInt("maxentries", 32, 1); } void On005Numeric(std::map<std::string, std::string>& tokens) override { tokens["ESILENCE"] = "CcdiNnPpTtx"; - tokens["SILENCE"] = ConvToStr(cmd.maxsilence); + tokens["SILENCE"] = ConvToStr(cmd.ext.maxsilence); } ModResult OnUserPreInvite(User* source, User* dest, Channel* channel, time_t timeout) override diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index db16ad121..faa4af2c0 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -155,17 +155,17 @@ void TreeSocket::ProcessLine(std::string &line) } else if (command == "BURST") { - if (params.size()) + if (!params.empty()) { time_t them = ConvToNum<time_t>(params[0]); time_t delta = them - ServerInstance->Time(); - if ((delta < -600) || (delta > 600)) + if ((delta < -60) || (delta > 60)) { - ServerInstance->SNO.WriteGlobalSno('l', "\002ERROR\002: Your clocks are off by %ld seconds (this is more than five minutes). Link aborted, \002PLEASE SYNC YOUR CLOCKS!\002", labs((long)delta)); - SendError("Your clocks are out by "+ConvToStr(labs((long)delta))+" seconds (this is more than five minutes). Link aborted, PLEASE SYNC YOUR CLOCKS!"); + ServerInstance->SNO.WriteGlobalSno('l', "\002ERROR\002: Your clocks are off by %ld seconds (this is more than one minute). Link aborted, \002PLEASE SYNC YOUR CLOCKS!\002", labs((long)delta)); + SendError("Your clocks are out by "+ConvToStr(labs((long)delta))+" seconds (this is more than one minute). Link aborted, PLEASE SYNC YOUR CLOCKS!"); return; } - else if ((delta < -30) || (delta > 30)) + else if ((delta < -15) || (delta > 15)) { ServerInstance->SNO.WriteGlobalSno('l', "\002WARNING\002: Your clocks are off by %ld seconds. Please consider syncing your clocks.", labs((long)delta)); } diff --git a/src/modules/m_xline_db.cpp b/src/modules/m_xline_db.cpp index b72eebb07..8e20e8f42 100644 --- a/src/modules/m_xline_db.cpp +++ b/src/modules/m_xline_db.cpp @@ -211,8 +211,8 @@ class ModuleXLineDB continue; } - XLine* xl = xlf->Generate(ServerInstance->Time(), atoi(command_p[5].c_str()), command_p[3], command_p[6], command_p[2]); - xl->SetCreateTime(atoi(command_p[4].c_str())); + XLine* xl = xlf->Generate(ServerInstance->Time(), ConvToNum<unsigned long>(command_p[5]), command_p[3], command_p[6], command_p[2]); + xl->SetCreateTime(ConvToNum<time_t>(command_p[4])); if (ServerInstance->XLines->AddLine(xl, NULL)) { |
