]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules.cpp
m_spanningtree Remove unneeded #includes
[user/henk/code/inspircd.git] / src / modules.cpp
index b09639b2eaabd7ddd3e38b6d76066502bf61ac0b..7ac4d2062aa3657d278a726bd6eb1777c69fc928 100644 (file)
@@ -109,7 +109,7 @@ ModResult   Module::OnUserPreNotice(User*, void*, int, std::string&, char, CUList&
 ModResult      Module::OnUserPreNick(User*, const std::string&) { return MOD_RES_PASSTHRU; }
 void           Module::OnUserPostNick(User*, const std::string&) { }
 ModResult      Module::OnPreMode(User*, User*, Channel*, const std::vector<std::string>&) { return MOD_RES_PASSTHRU; }
-void           Module::On005Numeric(std::string&) { }
+void           Module::On005Numeric(std::map<std::string, std::string>&) { }
 ModResult      Module::OnKill(User*, User*, const std::string&) { return MOD_RES_PASSTHRU; }
 void           Module::OnLoadModule(Module*) { }
 void           Module::OnUnloadModule(Module*) { }
@@ -331,13 +331,13 @@ bool ModuleManager::CanUnload(Module* mod)
        if (modfind == Modules.end() || modfind->second != mod)
        {
                LastModuleError = "Module " + mod->ModuleSourceFile + " is not loaded, cannot unload it!";
-               ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
+               ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, LastModuleError);
                return false;
        }
        if (mod->GetVersion().Flags & VF_STATIC)
        {
                LastModuleError = "Module " + mod->ModuleSourceFile + " not unloadable (marked static)";
-               ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
+               ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, LastModuleError);
                return false;
        }
        return true;
@@ -345,6 +345,11 @@ bool ModuleManager::CanUnload(Module* mod)
 
 void ModuleManager::DoSafeUnload(Module* mod)
 {
+       // First, notify all modules that a module is about to be unloaded, so in case
+       // they pass execution to the soon to be unloaded module, it will happen now,
+       // i.e. before we unregister the services of the module being unloaded
+       FOREACH_MOD(I_OnUnloadModule,OnUnloadModule(mod));
+
        std::map<std::string, Module*>::iterator modfind = Modules.find(mod->ModuleSourceFile);
 
        std::vector<reference<ExtensionItem> > items;
@@ -368,10 +373,10 @@ void ModuleManager::DoSafeUnload(Module* mod)
                ModeHandler* mh;
                mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER);
                if (mh && mh->creator == mod)
-                       ServerInstance->Modes->DelMode(mh);
+                       this->DelService(*mh);
                mh = ServerInstance->Modes->FindMode(m, MODETYPE_CHANNEL);
                if (mh && mh->creator == mod)
-                       ServerInstance->Modes->DelMode(mh);
+                       this->DelService(*mh);
        }
        for(std::multimap<std::string, ServiceProvider*>::iterator i = DataProviders.begin(); i != DataProviders.end(); )
        {
@@ -385,16 +390,14 @@ void ModuleManager::DoSafeUnload(Module* mod)
        /* Tidy up any dangling resolvers */
        ServerInstance->Res->CleanResolvers(mod);
 
-       FOREACH_MOD(I_OnUnloadModule,OnUnloadModule(mod));
-
        DetachAll(mod);
 
        Modules.erase(modfind);
        ServerInstance->GlobalCulls.AddItem(mod);
 
-       ServerInstance->Logs->Log("MODULE", DEFAULT,"Module %s unloaded",mod->ModuleSourceFile.c_str());
+       ServerInstance->Logs->Log("MODULE", LOG_DEFAULT,"Module %s unloaded",mod->ModuleSourceFile.c_str());
        this->ModCount--;
-       ServerInstance->BuildISupport();
+       ServerInstance->ISupport.Build();
 }
 
 void ModuleManager::UnloadAll()
@@ -436,6 +439,8 @@ void ModuleManager::AddService(ServiceProvider& item)
                case SERVICE_MODE:
                        if (!ServerInstance->Modes->AddMode(static_cast<ModeHandler*>(&item)))
                                throw ModuleException("Mode "+std::string(item.name)+" already exists.");
+                       DataProviders.insert(std::make_pair("mode/" + item.name, &item));
+                       dynamic_reference_base::reset_all();
                        return;
                case SERVICE_METADATA:
                        if (!ServerInstance->Extensions.Register(static_cast<ExtensionItem*>(&item)))
@@ -444,6 +449,9 @@ void ModuleManager::AddService(ServiceProvider& item)
                case SERVICE_DATA:
                case SERVICE_IOHOOK:
                {
+                       if (item.name.substr(0, 5) == "mode/")
+                               throw ModuleException("The \"mode/\" service name prefix is reserved.");
+
                        DataProviders.insert(std::make_pair(item.name, &item));
                        std::string::size_type slash = item.name.find('/');
                        if (slash != std::string::npos)
@@ -466,7 +474,7 @@ void ModuleManager::DelService(ServiceProvider& item)
                case SERVICE_MODE:
                        if (!ServerInstance->Modes->DelMode(static_cast<ModeHandler*>(&item)))
                                throw ModuleException("Mode "+std::string(item.name)+" does not exist.");
-                       return;
+                       // Fall through
                case SERVICE_DATA:
                case SERVICE_IOHOOK:
                {