summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/configreader.cpp4
-rw-r--r--src/modules/m_hostcycle.cpp114
-rw-r--r--src/users.cpp77
3 files changed, 116 insertions, 79 deletions
diff --git a/src/configreader.cpp b/src/configreader.cpp
index d2291556c..047a2b5cd 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -32,7 +32,7 @@
ServerConfig::ServerConfig()
{
RawLog = HideBans = HideSplits = UndernetMsgPrefix = false;
- WildcardIPv6 = CycleHosts = InvBypassModes = true;
+ WildcardIPv6 = InvBypassModes = true;
dns_timeout = 5;
MaxTargets = 20;
NetBufferSize = 10240;
@@ -349,6 +349,7 @@ static const DeprecatedConfig ChangedConfig[] = {
{ "link", "transport", "", "has been moved to <link:ssl> as of 2.0" },
{ "module", "name", "m_chanprotect.so", "has been replaced with m_customprefix as of 2.2" },
{ "module", "name", "m_halfop.so", "has been replaced with m_customprefix as of 2.2" },
+ { "options", "cyclehosts", "", "has been replaced with m_hostcycle as of 2.2" },
{ "performance", "nouserdns", "", "has been moved to <connect:nouserdns> as of 2.2" }
};
@@ -405,7 +406,6 @@ void ServerConfig::Fill()
RestrictBannedUsers = security->getBool("restrictbannedusers", true);
GenericOper = security->getBool("genericoper");
SyntaxHints = options->getBool("syntaxhints");
- CycleHosts = options->getBool("cyclehosts");
CycleHostsFromUser = options->getBool("cyclehostsfromuser");
UndernetMsgPrefix = options->getBool("ircumsgprefix");
FullHostInTopic = options->getBool("hostintopic");
diff --git a/src/modules/m_hostcycle.cpp b/src/modules/m_hostcycle.cpp
new file mode 100644
index 000000000..79b4169ec
--- /dev/null
+++ b/src/modules/m_hostcycle.cpp
@@ -0,0 +1,114 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2013 Attila Molnar <attilamolnar@hush.com>
+ * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *
+ * 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
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+class ModuleHostCycle : public Module
+{
+ /** Send fake quit/join/mode messages for host or ident cycle.
+ */
+ static void DoHostCycle(User* user, const std::string& newident, const std::string& newhost, const char* quitmsg)
+ {
+ // GetFullHost() returns the original data at the time this function is called
+ const std::string quitline = ":" + user->GetFullHost() + " QUIT :" + quitmsg;
+
+ already_sent_t silent_id = ++LocalUser::already_sent_id;
+ already_sent_t seen_id = ++LocalUser::already_sent_id;
+
+ UserChanList include_chans(user->chans);
+ std::map<User*,bool> exceptions;
+
+ FOREACH_MOD(OnBuildNeighborList, (user, include_chans, exceptions));
+
+ for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
+ {
+ LocalUser* u = IS_LOCAL(i->first);
+ if (u && !u->quitting)
+ {
+ if (i->second)
+ {
+ u->already_sent = seen_id;
+ u->Write(quitline);
+ }
+ else
+ {
+ u->already_sent = silent_id;
+ }
+ }
+ }
+
+ std::string newfullhost = user->nick + "!" + newident + "@" + newhost;
+
+ for (UCListIter i = include_chans.begin(); i != include_chans.end(); ++i)
+ {
+ Channel* c = *i;
+ Membership* memb = c->GetUser(user);
+ const std::string joinline = ":" + newfullhost + " JOIN " + c->name;
+ std::string modeline;
+
+ if (!memb->modes.empty())
+ {
+ modeline = ":" + (ServerInstance->Config->CycleHostsFromUser ? newfullhost : ServerInstance->Config->ServerName)
+ + " MODE " + c->name + " +" + memb->modes;
+
+ for (size_t j = 0; j < memb->modes.length(); j++)
+ modeline.append(" ").append(user->nick);
+ }
+
+ const UserMembList* ulist = c->GetUsers();
+ for (UserMembList::const_iterator j = ulist->begin(); j != ulist->end(); ++j)
+ {
+ LocalUser* u = IS_LOCAL(j->first);
+ if (u == NULL || u == user)
+ continue;
+ if (u->already_sent == silent_id)
+ continue;
+
+ if (u->already_sent != seen_id)
+ {
+ u->Write(quitline);
+ u->already_sent = seen_id;
+ }
+
+ u->Write(joinline);
+ if (!memb->modes.empty())
+ u->Write(modeline);
+ }
+ }
+ }
+
+ public:
+ void OnChangeIdent(User* user, const std::string& newident) CXX11_OVERRIDE
+ {
+ DoHostCycle(user, newident, user->dhost, "Changing ident");
+ }
+
+ void OnChangeHost(User* user, const std::string& newhost) CXX11_OVERRIDE
+ {
+ DoHostCycle(user, user->ident, newhost, "Changing host");
+ }
+
+ Version GetVersion() CXX11_OVERRIDE
+ {
+ return Version("Cycles users in all their channels when their host or ident changes", VF_VENDOR);
+ }
+};
+
+MODULE_INIT(ModuleHostCycle)
diff --git a/src/users.cpp b/src/users.cpp
index 371fa3bb6..bb7588fb2 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -1124,72 +1124,6 @@ bool User::ChangeName(const char* gecos)
return true;
}
-void User::DoHostCycle(const std::string &quitline)
-{
- if (!ServerInstance->Config->CycleHosts)
- return;
-
- already_sent_t silent_id = ++LocalUser::already_sent_id;
- already_sent_t seen_id = ++LocalUser::already_sent_id;
-
- UserChanList include_c(chans);
- std::map<User*,bool> exceptions;
-
- FOREACH_MOD(OnBuildNeighborList, (this, include_c, exceptions));
-
- for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
- {
- LocalUser* u = IS_LOCAL(i->first);
- if (u && !u->quitting)
- {
- if (i->second)
- {
- u->already_sent = seen_id;
- u->Write(quitline);
- }
- else
- {
- u->already_sent = silent_id;
- }
- }
- }
- for (UCListIter v = include_c.begin(); v != include_c.end(); ++v)
- {
- Channel* c = *v;
- Membership* memb = c->GetUser(this);
- const std::string joinline = ":" + GetFullHost() + " JOIN " + c->name;
- std::string modeline;
-
- if (!memb->modes.empty())
- {
- modeline = ":" + (ServerInstance->Config->CycleHostsFromUser ? GetFullHost() : ServerInstance->Config->ServerName)
- + " MODE " + c->name + " +" + memb->modes;
-
- for (size_t i = 0; i < memb->modes.length(); i++)
- modeline.append(" ").append(nick);
- }
-
- const UserMembList *ulist = c->GetUsers();
- for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
- {
- LocalUser* u = IS_LOCAL(i->first);
- if (u == NULL || u == this)
- continue;
- if (u->already_sent == silent_id)
- continue;
-
- if (u->already_sent != seen_id)
- {
- u->Write(quitline);
- u->already_sent = seen_id;
- }
- u->Write(joinline);
- if (!memb->modes.empty())
- u->Write(modeline);
- }
- }
-}
-
bool User::ChangeDisplayedHost(const char* shost)
{
if (dhost == shost)
@@ -1205,15 +1139,9 @@ bool User::ChangeDisplayedHost(const char* shost)
FOREACH_MOD(OnChangeHost, (this,shost));
- std::string quitstr = ":" + GetFullHost() + " QUIT :Changing host";
-
- /* Fix by Om: User::dhost is 65 long, this was truncating some long hosts */
this->dhost.assign(shost, 0, 64);
-
this->InvalidateCache();
- this->DoHostCycle(quitstr);
-
if (IS_LOCAL(this))
this->WriteNumeric(RPL_YOURDISPLAYEDHOST, "%s %s :is now your displayed host",this->nick.c_str(),this->dhost.c_str());
@@ -1227,14 +1155,9 @@ bool User::ChangeIdent(const char* newident)
FOREACH_MOD(OnChangeIdent, (this,newident));
- std::string quitstr = ":" + GetFullHost() + " QUIT :Changing ident";
-
this->ident.assign(newident, 0, ServerInstance->Config->Limits.IdentMax);
-
this->InvalidateCache();
- this->DoHostCycle(quitstr);
-
return true;
}