X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Flistmode.cpp;h=f3b2d5fc57937e93c339c3a077b6fb2aec7219cf;hb=e2b0f3dc9ef4d56c71d7abda13e6139ca092e387;hp=35964dfb3396d9f893f78e63aa2d682d0c39e53d;hpb=8c71a2a6304f0d77aa7738e04a44f366a158cadd;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/listmode.cpp b/src/listmode.cpp index 35964dfb3..f3b2d5fc5 100644 --- a/src/listmode.cpp +++ b/src/listmode.cpp @@ -1,7 +1,10 @@ /* * InspIRCd -- Internet Relay Chat Daemon * - * Copyright (C) 2009 Daniel De Graaf + * Copyright (C) 2018 linuxdaemon + * Copyright (C) 2018 B00mX0r + * Copyright (C) 2017-2019 Sadie Powell + * Copyright (C) 2013-2014, 2016 Attila Molnar * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public @@ -19,11 +22,13 @@ #include "inspircd.h" #include "listmode.h" -ListModeBase::ListModeBase(Module* Creator, const std::string& Name, char modechar, const std::string &eolstr, unsigned int lnum, unsigned int eolnum, bool autotidy, const std::string &ctag) - : ModeHandler(Creator, Name, modechar, PARAM_ALWAYS, MODETYPE_CHANNEL, MC_LIST), - listnumeric(lnum), endoflistnumeric(eolnum), endofliststring(eolstr), tidy(autotidy), - configtag(ctag) - , extItem("listbase_mode_" + name + "_list", ExtensionItem::EXT_CHANNEL, Creator) +ListModeBase::ListModeBase(Module* Creator, const std::string& Name, char modechar, const std::string& eolstr, unsigned int lnum, unsigned int eolnum, bool autotidy) + : ModeHandler(Creator, Name, modechar, PARAM_ALWAYS, MODETYPE_CHANNEL, MC_LIST) + , listnumeric(lnum) + , endoflistnumeric(eolnum) + , endofliststring(eolstr) + , tidy(autotidy) + , extItem(name + "_mode_list", ExtensionItem::EXT_CHANNEL, Creator) { list = true; } @@ -35,15 +40,15 @@ void ListModeBase::DisplayList(User* user, Channel* channel) { for (ModeList::const_iterator it = cd->list.begin(); it != cd->list.end(); ++it) { - user->WriteNumeric(listnumeric, "%s %s %s %lu", channel->name.c_str(), it->mask.c_str(), it->setter.c_str(), (unsigned long) it->time); + user->WriteNumeric(listnumeric, channel->name, it->mask, it->setter, (unsigned long) it->time); } } - user->WriteNumeric(endoflistnumeric, "%s :%s", channel->name.c_str(), endofliststring.c_str()); + user->WriteNumeric(endoflistnumeric, channel->name, endofliststring); } void ListModeBase::DisplayEmptyList(User* user, Channel* channel) { - user->WriteNumeric(endoflistnumeric, "%s :%s", channel->name.c_str(), endofliststring.c_str()); + user->WriteNumeric(endoflistnumeric, channel->name, endofliststring); } void ListModeBase::RemoveMode(Channel* channel, Modes::ChangeList& changelist) @@ -60,29 +65,42 @@ void ListModeBase::RemoveMode(Channel* channel, Modes::ChangeList& changelist) void ListModeBase::DoRehash() { - ConfigTagList tags = ServerInstance->Config->ConfTags(configtag); - - limitlist oldlimits = chanlimits; - chanlimits.clear(); - + ConfigTagList tags = ServerInstance->Config->ConfTags("maxlist"); + limitlist newlimits; + bool seen_default = false; for (ConfigIter i = tags.first; i != tags.second; i++) { - // For each tag ConfigTag* c = i->second; - ListLimit limit(c->getString("chan"), c->getInt("limit")); - if (limit.mask.size() && limit.limit > 0) - chanlimits.push_back(limit); + const std::string mname = c->getString("mode"); + if (!mname.empty() && !stdalgo::string::equalsci(mname, name) && !(mname.length() == 1 && GetModeChar() == mname[0])) + continue; + + ListLimit limit(c->getString("chan", "*", 1), c->getUInt("limit", DEFAULT_LIST_SIZE)); + + if (limit.mask.empty()) + throw ModuleException(InspIRCd::Format(" is empty, at %s", c->getTagLocation().c_str())); + + if (limit.mask == "*" || limit.mask == "#*") + seen_default = true; + + newlimits.push_back(limit); } - // Add the default entry. This is inserted last so if the user specifies a - // wildcard record in the config it will take precedence over this entry. - chanlimits.push_back(ListLimit("*", 64)); + // If no default limit has been specified then insert one. + if (!seen_default) + { + ServerInstance->Logs->Log("MODE", LOG_DEBUG, "No default entry was found for the %s mode; defaulting to %u", + name.c_str(), DEFAULT_LIST_SIZE); + newlimits.push_back(ListLimit("*", DEFAULT_LIST_SIZE)); + } // Most of the time our settings are unchanged, so we can avoid iterating the chanlist - if (oldlimits == chanlimits) + if (chanlimits == newlimits) return; + chanlimits.swap(newlimits); + const chan_hash& chans = ServerInstance->GetChans(); for (chan_hash::const_iterator i = chans.begin(); i != chans.end(); ++i) { @@ -102,7 +120,7 @@ unsigned int ListModeBase::FindLimit(const std::string& channame) return it->limit; } } - return 64; + return 0; } unsigned int ListModeBase::GetLimitInternal(const std::string& channame, ChanData* cd) @@ -121,6 +139,20 @@ unsigned int ListModeBase::GetLimit(Channel* channel) return GetLimitInternal(channel->name, cd); } +unsigned int ListModeBase::GetLowerLimit() +{ + if (chanlimits.empty()) + return DEFAULT_LIST_SIZE; + + unsigned int limit = UINT_MAX; + for (limitlist::iterator iter = chanlimits.begin(); iter != chanlimits.end(); ++iter) + { + if (iter->limit < limit) + limit = iter->limit; + } + return limit; +} + ModeAction ListModeBase::OnModeChange(User* source, User*, Channel* channel, std::string ¶meter, bool adding) { // Try and grab the list @@ -131,9 +163,6 @@ ModeAction ListModeBase::OnModeChange(User* source, User*, Channel* channel, std if (tidy) ModeParser::CleanMask(parameter); - if (parameter.length() > 250) - return MODEACTION_DENY; - // If there was no list if (!cd) { @@ -210,15 +239,22 @@ bool ListModeBase::ValidateParam(User*, Channel*, std::string&) return true; } +void ListModeBase::OnParameterMissing(User*, User*, Channel*) +{ + // Intentionally left blank. +} + void ListModeBase::TellListTooLong(User* source, Channel* channel, std::string& parameter) { - source->WriteNumeric(ERR_BANLISTFULL, "%s %s :Channel ban list is full", channel->name.c_str(), parameter.c_str()); + source->WriteNumeric(ERR_BANLISTFULL, channel->name, parameter, mode, InspIRCd::Format("Channel %s list is full", name.c_str())); } -void ListModeBase::TellAlreadyOnList(User*, Channel*, std::string&) +void ListModeBase::TellAlreadyOnList(User* source, Channel* channel, std::string& parameter) { + source->WriteNumeric(ERR_LISTMODEALREADYSET, channel->name, parameter, mode, InspIRCd::Format("Channel %s list already contains %s", name.c_str(), parameter.c_str())); } -void ListModeBase::TellNotSet(User*, Channel*, std::string&) +void ListModeBase::TellNotSet(User* source, Channel* channel, std::string& parameter) { + source->WriteNumeric(ERR_LISTMODENOTSET, channel->name, parameter, mode, InspIRCd::Format("Channel %s list does not contain %s", name.c_str(), parameter.c_str())); }