summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-10-18 02:57:46 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-10-18 02:57:46 +0000
commite50d016aa23083f81dcf181f68edb81c5b23c78d (patch)
tree2f627c4d456ec360a05c013832142df187e193d6
parent93a78a57ada6d5dab410c2bd3c4b02f4fa15684c (diff)
Cull channels, warn when Extensible objects are not culled as they must be
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11901 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/channels.h8
-rw-r--r--include/extensible.h1
-rw-r--r--src/base.cpp12
-rw-r--r--src/channels.cpp59
-rw-r--r--src/commands/cmd_kick.cpp4
-rw-r--r--src/commands/cmd_part.cpp4
-rw-r--r--src/modules/m_channames.cpp4
-rw-r--r--src/modules/m_cycle.cpp4
-rw-r--r--src/modules/m_messageflood.cpp5
-rw-r--r--src/modules/m_remove.cpp3
-rw-r--r--src/modules/m_sakick.cpp3
-rw-r--r--src/modules/m_sapart.cpp3
-rw-r--r--src/modules/m_spanningtree/svspart.cpp3
-rw-r--r--src/users.cpp30
14 files changed, 54 insertions, 89 deletions
diff --git a/include/channels.h b/include/channels.h
index 7728bb55b..2915ed390 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -204,7 +204,7 @@ class CoreExport Channel : public Extensible
* @param user The user to delete
* @return number of users left on the channel after deletion of the user
*/
- unsigned long DelUser(User* user);
+ void DelUser(User* user);
/** Obtain the internal reference list
* The internal reference list contains a list of User*.
@@ -232,7 +232,7 @@ class CoreExport Channel : public Extensible
* @return The number of users left on the channel. If this is zero
* when the method returns, you MUST delete the Channel immediately!
*/
- long KickUser(User *src, User *user, const char* reason);
+ void KickUser(User *src, User *user, const char* reason);
/** Make the server kick user from this channel with the given reason.
* @param user The user being kicked (must be on this channel)
@@ -241,7 +241,7 @@ class CoreExport Channel : public Extensible
* @return The number of users left on the channel. If this is zero
* when the method returns, you MUST delete the Channel immediately!
*/
- long ServerKickUser(User* user, const char* reason, const std::string& servername = "");
+ void ServerKickUser(User* user, const char* reason, const std::string& servername = "");
/** Part a user from this channel with the given reason.
* If the reason field is NULL, no reason will be sent.
@@ -250,7 +250,7 @@ class CoreExport Channel : public Extensible
* @return The number of users left on the channel. If this is zero
* when the method returns, you MUST delete the Channel immediately!
*/
- long PartUser(User *user, std::string &reason);
+ void PartUser(User *user, std::string &reason);
/* Join a user to a channel. May be a channel that doesnt exist yet.
* @param user The user to join to the channel.
diff --git a/include/extensible.h b/include/extensible.h
index 449c7b38a..62edb8896 100644
--- a/include/extensible.h
+++ b/include/extensible.h
@@ -72,6 +72,7 @@ class CoreExport Extensible : public classbase
*/
inline const ExtensibleStore& GetExtList() const { return extensions; }
+ Extensible();
virtual CullResult cull();
virtual ~Extensible();
void doUnhookExtensions(const std::vector<ExtensionItem*>& toRemove);
diff --git a/src/base.cpp b/src/base.cpp
index 15a642eb4..977227440 100644
--- a/src/base.cpp
+++ b/src/base.cpp
@@ -136,17 +136,27 @@ void Extensible::doUnhookExtensions(const std::vector<ExtensionItem*>& toRemove)
}
}
+Extensible::Extensible()
+{
+ extensions[NULL] = NULL;
+}
+
CullResult Extensible::cull()
{
for(ExtensibleStore::iterator i = extensions.begin(); i != extensions.end(); ++i)
{
- i->first->free(i->second);
+ if (i->first)
+ i->first->free(i->second);
}
+ extensions.clear();
return classbase::cull();
}
Extensible::~Extensible()
{
+ if (!extensions.empty() && ServerInstance && ServerInstance->Logs)
+ ServerInstance->Logs->Log("CULLLIST", DEBUG,
+ "Extensible destructor called without cull @%p", (void*)this);
}
LocalExtItem::LocalExtItem(const std::string& Key, Module* mod) : ExtensionItem(Key, mod)
diff --git a/src/channels.cpp b/src/channels.cpp
index 22ec6e4d9..0e45de33f 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -125,17 +125,16 @@ Membership* Channel::AddUser(User* user)
return memb;
}
-unsigned long Channel::DelUser(User* user)
+void Channel::DelUser(User* user)
{
UserMembIter a = userlist.find(user);
if (a != userlist.end())
{
+ a->second->cull();
delete a->second;
userlist.erase(a);
}
-
- return userlist.size();
}
bool Channel::HasUser(User* user)
@@ -448,10 +447,10 @@ ModResult Channel::GetExtBanStatus(User *user, char type)
* remove a channel from a users record, and return the number of users left.
* Therefore, if this function returns 0 the caller should delete the Channel.
*/
-long Channel::PartUser(User *user, std::string &reason)
+void Channel::PartUser(User *user, std::string &reason)
{
if (!user)
- return this->GetUserCounter();
+ return;
Membership* memb = GetUser(user);
@@ -466,39 +465,38 @@ long Channel::PartUser(User *user, std::string &reason)
this->RemoveAllPrefixes(user);
}
- if (!this->DelUser(user)) /* if there are no users left on the channel... */
+ this->DelUser(user);
+ if (userlist.empty())
{
+ ModResult res;
+ FIRST_MOD_RESULT(OnChannelPreDelete, res, (this));
+ if (res == MOD_RES_DENY)
+ return;
chan_hash::iterator iter = ServerInstance->chanlist->find(this->name);
/* kill the record */
if (iter != ServerInstance->chanlist->end())
{
- ModResult res;
- FIRST_MOD_RESULT(OnChannelPreDelete, res, (this));
- if (res == MOD_RES_DENY)
- return 1; // delete halted by module
FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this));
ServerInstance->chanlist->erase(iter);
}
- return 0;
+ ServerInstance->GlobalCulls.AddItem(this);
}
-
- return this->GetUserCounter();
}
-long Channel::ServerKickUser(User* user, const char* reason, const std::string& servername)
+void Channel::ServerKickUser(User* user, const char* reason, const std::string& servername)
{
if (servername.empty() || !ServerInstance->Config->HideWhoisServer.empty())
ServerInstance->FakeClient->server = ServerInstance->Config->ServerName;
else
ServerInstance->FakeClient->server = servername;
- return this->KickUser(ServerInstance->FakeClient, user, reason);
+ KickUser(ServerInstance->FakeClient, user, reason);
}
-long Channel::KickUser(User *src, User *user, const char* reason)
+void Channel::KickUser(User *src, User *user, const char* reason)
{
if (!src || !user || !reason)
- return this->GetUserCounter();
+ return;
Membership* memb = GetUser(user);
if (IS_LOCAL(src))
@@ -506,12 +504,12 @@ long Channel::KickUser(User *src, User *user, const char* reason)
if (!memb)
{
src->WriteNumeric(ERR_USERNOTINCHANNEL, "%s %s %s :They are not on that channel",src->nick.c_str(), user->nick.c_str(), this->name.c_str());
- return this->GetUserCounter();
+ return;
}
if ((ServerInstance->ULine(user->server)) && (!ServerInstance->ULine(src->server)))
{
src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only a u-line may kick a u-line from a channel.",src->nick.c_str(), this->name.c_str());
- return this->GetUserCounter();
+ return;
}
ModResult res;
@@ -521,7 +519,7 @@ long Channel::KickUser(User *src, User *user, const char* reason)
FIRST_MOD_RESULT(OnUserPreKick, res, (src,memb,reason));
if (res == MOD_RES_DENY)
- return this->GetUserCounter();
+ return;
if (res == MOD_RES_PASSTHRU)
{
@@ -530,7 +528,7 @@ long Channel::KickUser(User *src, User *user, const char* reason)
if ((them < HALFOP_VALUE) || (them < us))
{
src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator",src->nick.c_str(), this->name.c_str(), them >= HALFOP_VALUE ? "" : "half-");
- return this->GetUserCounter();
+ return;
}
}
}
@@ -546,25 +544,22 @@ long Channel::KickUser(User *src, User *user, const char* reason)
this->RemoveAllPrefixes(user);
}
- if (!this->DelUser(user))
- /* if there are no users left on the channel */
+ this->DelUser(user);
+ if (userlist.empty())
{
- chan_hash::iterator iter = ServerInstance->chanlist->find(this->name.c_str());
-
+ ModResult res;
+ FIRST_MOD_RESULT(OnChannelPreDelete, res, (this));
+ if (res == MOD_RES_DENY)
+ return;
+ chan_hash::iterator iter = ServerInstance->chanlist->find(this->name);
/* kill the record */
if (iter != ServerInstance->chanlist->end())
{
- ModResult res;
- FIRST_MOD_RESULT(OnChannelPreDelete, res, (this));
- if (res == MOD_RES_DENY)
- return 1; // delete halted by module
FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this));
ServerInstance->chanlist->erase(iter);
}
- return 0;
+ ServerInstance->GlobalCulls.AddItem(this);
}
-
- return this->GetUserCounter();
}
void Channel::WriteChannel(User* user, const char* text, ...)
diff --git a/src/commands/cmd_kick.cpp b/src/commands/cmd_kick.cpp
index d160b030b..65b22070c 100644
--- a/src/commands/cmd_kick.cpp
+++ b/src/commands/cmd_kick.cpp
@@ -66,9 +66,7 @@ CmdResult CommandKick::Handle (const std::vector<std::string>& parameters, User
reason.assign(user->nick, 0, ServerInstance->Config->Limits.MaxKick);
}
- if (!c->KickUser(user, u, reason.c_str()))
- /* Nobody left here, delete the Channel */
- delete c;
+ c->KickUser(user, u, reason.c_str());
return CMD_SUCCESS;
}
diff --git a/src/commands/cmd_part.cpp b/src/commands/cmd_part.cpp
index a7a407ac8..c234ed681 100644
--- a/src/commands/cmd_part.cpp
+++ b/src/commands/cmd_part.cpp
@@ -61,9 +61,7 @@ CmdResult CommandPart::Handle (const std::vector<std::string>& parameters, User
if (c)
{
- if (!c->PartUser(user, reason))
- /* Arse, who stole our channel! :/ */
- delete c;
+ c->PartUser(user, reason);
}
else
{
diff --git a/src/modules/m_channames.cpp b/src/modules/m_channames.cpp
index ba03f9af5..c137d0e71 100644
--- a/src/modules/m_channames.cpp
+++ b/src/modules/m_channames.cpp
@@ -81,8 +81,8 @@ class ModuleChannelNames : public Module
}
const UserMembList* users = c->GetUsers();
for(UserMembCIter j = users->begin(); j != users->end(); ++j)
- if (IS_LOCAL(j->first) && !c->ServerKickUser(j->first, "Channel name no longer valid", NULL))
- delete c;
+ if (IS_LOCAL(j->first))
+ c->ServerKickUser(j->first, "Channel name no longer valid", NULL);
}
badchan = false;
}
diff --git a/src/modules/m_cycle.cpp b/src/modules/m_cycle.cpp
index dec806b5b..fafdc336c 100644
--- a/src/modules/m_cycle.cpp
+++ b/src/modules/m_cycle.cpp
@@ -57,9 +57,7 @@ class CommandCycle : public Command
return CMD_FAILURE;
}
- /* XXX in the future, this may move to a static Channel method (the delete.) -- w00t */
- if (!channel->PartUser(user, reason))
- delete channel;
+ channel->PartUser(user, reason);
Channel::JoinUser(user, parameters[0].c_str(), true, "", false, ServerInstance->Time());
}
diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp
index bf124839a..9bc0f362f 100644
--- a/src/modules/m_messageflood.cpp
+++ b/src/modules/m_messageflood.cpp
@@ -234,10 +234,7 @@ class ModuleMsgFlood : public Module
char kickmessage[MAXBUF];
snprintf(kickmessage, MAXBUF, "Channel flood triggered (limit is %d lines in %d secs)", f->lines, f->secs);
- if (!dest->ServerKickUser(user, kickmessage))
- {
- delete dest;
- }
+ dest->ServerKickUser(user, kickmessage);
return MOD_RES_DENY;
}
diff --git a/src/modules/m_remove.cpp b/src/modules/m_remove.cpp
index 67f81fc65..1bbc0931f 100644
--- a/src/modules/m_remove.cpp
+++ b/src/modules/m_remove.cpp
@@ -106,8 +106,7 @@ class RemoveBase : public Command
channel->WriteChannelWithServ(ServerInstance->Config->ServerName.c_str(), "NOTICE %s :%s removed %s from the channel", channel->name.c_str(), user->nick.c_str(), target->nick.c_str());
target->WriteServ("NOTICE %s :*** %s removed you from %s with the message: %s", target->nick.c_str(), user->nick.c_str(), channel->name.c_str(), reasonparam.c_str());
- if (!channel->PartUser(target, reason))
- delete channel;
+ channel->PartUser(target, reason);
}
else
{
diff --git a/src/modules/m_sakick.cpp b/src/modules/m_sakick.cpp
index 57783be8f..b81df75c6 100644
--- a/src/modules/m_sakick.cpp
+++ b/src/modules/m_sakick.cpp
@@ -56,8 +56,7 @@ class CommandSakick : public Command
*/
if (IS_LOCAL(dest))
{
- if (!channel->ServerKickUser(dest, reason, servername))
- delete channel;
+ channel->ServerKickUser(dest, reason, servername);
Channel *n = ServerInstance->FindChan(parameters[1]);
if (n && n->HasUser(dest))
diff --git a/src/modules/m_sapart.cpp b/src/modules/m_sapart.cpp
index 32a2e16fc..8f0a9e551 100644
--- a/src/modules/m_sapart.cpp
+++ b/src/modules/m_sapart.cpp
@@ -49,8 +49,7 @@ class CommandSapart : public Command
*/
if (IS_LOCAL(dest))
{
- if (!channel->PartUser(dest, reason))
- delete channel;
+ channel->PartUser(dest, reason);
Channel* n = ServerInstance->FindChan(parameters[1]);
if (!n)
diff --git a/src/modules/m_spanningtree/svspart.cpp b/src/modules/m_spanningtree/svspart.cpp
index cc49aa72e..2a34d23c6 100644
--- a/src/modules/m_spanningtree/svspart.cpp
+++ b/src/modules/m_spanningtree/svspart.cpp
@@ -40,8 +40,7 @@ bool TreeSocket::ServicePart(const std::string &prefix, parameterlist &params)
{
/* only part if it's local, otherwise just pass it on! */
if (IS_LOCAL(u))
- if (!c->PartUser(u, reason))
- delete c;
+ c->PartUser(u, reason);
Utils->DoOneToAllButSender(prefix,"SVSPART",params,prefix);
}
diff --git a/src/users.cpp b/src/users.cpp
index 542a6e565..665f1d908 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -1708,35 +1708,7 @@ void User::PurgeEmptyChannels()
{
Channel* c = *f;
c->RemoveAllPrefixes(this);
- if (c->DelUser(this) == 0)
- {
- /* No users left in here, mark it for deletion */
- try
- {
- to_delete.push_back(c);
- }
- catch (...)
- {
- ServerInstance->Logs->Log("USERS", DEBUG,"Exception in User::PurgeEmptyChannels to_delete.push_back()");
- }
- }
- }
-
- for (std::vector<Channel*>::iterator n = to_delete.begin(); n != to_delete.end(); n++)
- {
- Channel* thischan = *n;
- chan_hash::iterator i2 = ServerInstance->chanlist->find(thischan->name);
- if (i2 != ServerInstance->chanlist->end())
- {
- ModResult MOD_RESULT;
- FIRST_MOD_RESULT(OnChannelPreDelete, MOD_RESULT, (i2->second));
- if (MOD_RESULT == MOD_RES_DENY)
- continue; // delete halted by module
- FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(i2->second));
- delete i2->second;
- ServerInstance->chanlist->erase(i2);
- this->chans.erase(*n);
- }
+ c->DelUser(this);
}
this->UnOper();