* Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
* Copyright (C) 2007 Oliver Lupton <om@inspircd.org>
* Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
- * Copyright (C) 2006-2010 Craig Edwards <brain@inspircd.org>
+ * Copyright (C) 2005-2010 Craig Edwards <brain@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
void Module::OnAddLine(User*, XLine*) { DetachEvent(I_OnAddLine); }
void Module::OnDelLine(User*, XLine*) { DetachEvent(I_OnDelLine); }
void Module::OnExpireLine(XLine*) { DetachEvent(I_OnExpireLine); }
-void Module::OnCleanup(ExtensionItem::ExtensibleType, Extensible*) { }
+void Module::OnCleanup(ExtensionItem::ExtensibleType, Extensible*) { }
ModResult Module::OnChannelPreDelete(Channel*) { DetachEvent(I_OnChannelPreDelete); return MOD_RES_PASSTHRU; }
void Module::OnChannelDelete(Channel*) { DetachEvent(I_OnChannelDelete); }
void Module::OnBuildNeighborList(User*, IncludeChanList&, std::map<User*,bool>&) { DetachEvent(I_OnBuildNeighborList); }
void Module::OnGarbageCollect() { DetachEvent(I_OnGarbageCollect); }
ModResult Module::OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { DetachEvent(I_OnSetConnectClass); return MOD_RES_PASSTHRU; }
-void Module::OnUserMessage(User*, const MessageTarget&, const MessageDetails&) { DetachEvent(I_OnUserMessage); }
+void Module::OnUserMessage(User*, const MessageTarget&, const MessageDetails&) { DetachEvent(I_OnUserMessage); }
ModResult Module::OnNumeric(User*, const Numeric::Numeric&) { DetachEvent(I_OnNumeric); return MOD_RES_PASSTHRU; }
ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { DetachEvent(I_OnAcceptConnection); return MOD_RES_PASSTHRU; }
void Module::OnSetUserIP(LocalUser*) { DetachEvent(I_OnSetUserIP); }
stdalgo::erase(*ServerInstance->Modules->NewServices, this);
}
+const char* ServiceProvider::GetTypeString() const
+{
+ switch (service)
+ {
+ case SERVICE_COMMAND:
+ return "command";
+ case SERVICE_MODE:
+ return "mode";
+ case SERVICE_METADATA:
+ return "metadata";
+ case SERVICE_IOHOOK:
+ return "iohook";
+ case SERVICE_DATA:
+ return "data service";
+ case SERVICE_CUSTOM:
+ return "module service";
+ }
+ return "unknown service";
+}
+
ModuleManager::ModuleManager()
{
}
user->doUnhookExtensions(items);
}
- for(std::multimap<std::string, ServiceProvider*>::iterator i = DataProviders.begin(); i != DataProviders.end(); )
+ for (DataProviderMap::iterator i = DataProviders.begin(); i != DataProviders.end(); )
{
- std::multimap<std::string, ServiceProvider*>::iterator curr = i++;
+ DataProviderMap::iterator curr = i++;
if (curr->second->creator == mod)
+ {
DataProviders.erase(curr);
+ FOREACH_MOD(OnServiceDel, (*curr->second));
+ }
}
dynamic_reference_base::reset_all();
Modules.erase(modfind);
ServerInstance->GlobalCulls.AddItem(mod);
- ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Module %s unloaded",mod->ModuleSourceFile.c_str());
+ ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "The %s module was unloaded", mod->ModuleSourceFile.c_str());
ServerInstance->ISupport.Build();
}
void ModuleManager::AddService(ServiceProvider& item)
{
+ ServerInstance->Logs->Log("SERVICE", LOG_DEBUG, "Adding %s %s provided by %s", item.name.c_str(),
+ item.GetTypeString(), item.creator ? item.creator->ModuleSourceFile.c_str() : "the core");
switch (item.service)
{
case SERVICE_DATA:
void ModuleManager::DelService(ServiceProvider& item)
{
+ ServerInstance->Logs->Log("SERVICE", LOG_DEBUG, "Deleting %s %s provided by %s", item.name.c_str(),
+ item.GetTypeString(), item.creator ? item.creator->ModuleSourceFile.c_str() : "the core");
switch (item.service)
{
case SERVICE_MODE:
case SERVICE_IOHOOK:
{
DelReferent(&item);
- return;
+ break;
}
default:
throw ModuleException("Cannot delete unknown service type");
case SERVICE_DATA:
case SERVICE_IOHOOK:
{
- std::multimap<std::string, ServiceProvider*>::iterator i = DataProviders.find(name);
+ DataProviderMap::iterator i = DataProviders.find(name);
if (i != DataProviders.end() && i->second->service == type)
return i->second;
return NULL;
{
// Because find() may return any element with a matching key in case count(key) > 1 use lower_bound()
// to ensure a dynref with the same name as another one resolves to the same object
- std::multimap<std::string, ServiceProvider*>::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name);
+ ModuleManager::DataProviderMap::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name);
if ((i != ServerInstance->Modules.DataProviders.end()) && (i->first == this->name))
{
ServiceProvider* newvalue = i->second;
void ModuleManager::DelReferent(ServiceProvider* service)
{
- for (std::multimap<std::string, ServiceProvider*>::iterator i = DataProviders.begin(); i != DataProviders.end(); )
+ for (DataProviderMap::iterator i = DataProviders.begin(); i != DataProviders.end(); )
{
ServiceProvider* curr = i->second;
if (curr == service)