X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules.cpp;h=52a25d37cc8e0a43001776e402675eaf450364a1;hb=9d4004e8d477232c143830508a7a6e41fd2d31b7;hp=f460a6a28401b9df0baaa7c8e06cdbc0559c19ce;hpb=601d67fd5f5a9e430a59a1930382eae67eb39fb4;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules.cpp b/src/modules.cpp index f460a6a28..52a25d37c 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -26,8 +26,14 @@ // Version is a simple class for holding a modules version number template<> -VersionBase::VersionBase(const std::string &modv, int flags) -: description(modv), Flags(flags) +VersionBase::VersionBase(const std::string &desc, int flags) +: description(desc), Flags(flags) +{ +} + +template<> +VersionBase::VersionBase(const std::string &desc, int flags, const std::string& linkdata) +: description(desc), Flags(flags), link_data(linkdata) { } @@ -93,8 +99,8 @@ ModResult Module::OnKill(User*, User*, const std::string&) { return MOD_RES_PASS void Module::OnLoadModule(Module*) { } void Module::OnUnloadModule(Module*) { } void Module::OnBackgroundTimer(time_t) { } -ModResult Module::OnPreCommand(std::string&, std::vector&, User *, bool, const std::string&) { return MOD_RES_PASSTHRU; } -void Module::OnPostCommand(const std::string&, const std::vector&, User *, CmdResult, const std::string&) { } +ModResult Module::OnPreCommand(std::string&, std::vector&, LocalUser*, bool, const std::string&) { return MOD_RES_PASSTHRU; } +void Module::OnPostCommand(const std::string&, const std::vector&, LocalUser*, CmdResult, const std::string&) { } ModResult Module::OnCheckReady(LocalUser*) { return MOD_RES_PASSTHRU; } ModResult Module::OnUserRegister(LocalUser*) { return MOD_RES_PASSTHRU; } ModResult Module::OnUserPreKick(User*, Membership*, const std::string&) { return MOD_RES_PASSTHRU; } @@ -149,13 +155,14 @@ ModResult Module::OnUserList(User*, Channel*) { return MOD_RES_PASSTHRU; } ModResult Module::OnWhoisLine(User*, User*, int&, std::string&) { return MOD_RES_PASSTHRU; } void Module::OnBuildNeighborList(User*, UserChanList&, std::map&) { } void Module::OnGarbageCollect() { } +ModResult Module::OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { return MOD_RES_PASSTHRU; } void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { } void Module::OnRunTestSuite() { } void Module::OnNamesListItem(User*, Membership*, std::string&, std::string&) { } ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MOD_RES_PASSTHRU; } void Module::OnHookIO(StreamSocket*, ListenSocket*) { } ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { return MOD_RES_PASSTHRU; } -void Module::OnSendWhoLine(User*, User*, Channel*, std::string&) { } +void Module::OnSendWhoLine(User*, const std::vector&, User*, Channel*, std::string&) { } ModResult Module::OnChannelRestrictionApply(User*, Channel*, const char*) { return MOD_RES_PASSTHRU; } ModuleManager::ModuleManager() : ModCount(0) @@ -168,6 +175,9 @@ ModuleManager::~ModuleManager() bool ModuleManager::Attach(Implementation i, Module* mod) { + if (Modules.find(mod->ModuleSourceFile) == Modules.end()) + ServerInstance->Logs->Log("MODULE", DEFAULT, "Module is attaching to hook %d in constructor; this does not handle exceptions correctly!", i); + if (std::find(EventHandlers[i].begin(), EventHandlers[i].end(), mod) != EventHandlers[i].end()) return false; @@ -323,6 +333,79 @@ bool ModuleManager::SetPriority(Module* mod, Implementation i, Priority s, Modul return true; } +bool ModuleManager::CanUnload(Module* mod) +{ + std::map::iterator modfind = Modules.find(mod->ModuleSourceFile); + + if (modfind == Modules.end() || modfind->second != mod) + { + LastModuleError = "Module " + mod->ModuleSourceFile + " is not loaded, cannot unload it!"; + ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError); + return false; + } + if (mod->GetVersion().Flags & VF_STATIC) + { + LastModuleError = "Module " + mod->ModuleSourceFile + " not unloadable (marked static)"; + ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError); + return false; + } + return true; +} + +void ModuleManager::DoSafeUnload(Module* mod) +{ + std::map::iterator modfind = Modules.find(mod->ModuleSourceFile); + + std::vector > items; + ServerInstance->Extensions.BeginUnregister(modfind->second, items); + /* Give the module a chance to tidy out all its metadata */ + for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++) + { + mod->OnCleanup(TYPE_CHANNEL,c->second); + c->second->doUnhookExtensions(items); + const UserMembList* users = c->second->GetUsers(); + for(UserMembCIter mi = users->begin(); mi != users->end(); mi++) + mi->second->doUnhookExtensions(items); + } + for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++) + { + mod->OnCleanup(TYPE_USER,u->second); + u->second->doUnhookExtensions(items); + } + for(char m='A'; m <= 'z'; m++) + { + ModeHandler* mh; + mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER); + if (mh && mh->creator == mod) + ServerInstance->Modes->DelMode(mh); + mh = ServerInstance->Modes->FindMode(m, MODETYPE_CHANNEL); + if (mh && mh->creator == mod) + ServerInstance->Modes->DelMode(mh); + } + for(std::multimap::iterator i = DataProviders.begin(); i != DataProviders.end(); ) + { + std::multimap::iterator curr = i++; + if (curr->second->creator == mod) + DataProviders.erase(curr); + } + for(unsigned int i = 0; i < ServerInstance->Modules->ActiveDynrefs.size(); i++) + ServerInstance->Modules->ActiveDynrefs[i]->ClearCache(); + + /* 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()); + this->ModCount--; + ServerInstance->BuildISupport(); +} + std::string& ModuleManager::LastError() { return LastModuleError; @@ -338,16 +421,12 @@ bool InspIRCd::IsValidModuleCommand(const std::string &commandname, int pcnt, Us return this->Parser->IsValidCommand(commandname, pcnt, user); } -void InspIRCd::AddCommand(Command *f) -{ - if (!this->Parser->AddCommand(f)) - { - throw ModuleException("Command "+std::string(f->name)+" already exists."); - } -} - void ModuleManager::AddService(ServiceProvider& item) { + Module* owner = item.creator; + if (Modules.find(owner->ModuleSourceFile) == Modules.end()) + ServerInstance->Logs->Log("MODULE", DEFAULT, "Module is registering item %s in constructor; this does not handle exceptions correctly!", item.name.c_str()); + switch (item.service) { case SERVICE_COMMAND: @@ -446,6 +525,14 @@ void InspIRCd::SendMode(const std::vector& parameters, User *user) this->Modes->Process(parameters, user); } + +void InspIRCd::SendGlobalMode(const std::vector& parameters, User *user) +{ + Modes->Process(parameters, user); + if (!Modes->GetLastParse().empty()) + this->PI->SendMode(parameters[0], Modes->GetLastParseParams(), Modes->GetLastParseTranslate()); +} + bool InspIRCd::AddResolver(Resolver* r, bool cached) { if (!cached) @@ -480,6 +567,8 @@ const std::vector ModuleManager::GetAllModuleNames(int filter) ConfigReader::ConfigReader() { this->error = 0; + ServerInstance->Logs->Log("MODULE", DEBUG, "ConfigReader is deprecated in 2.0; " + "use ServerInstance->Config->ConfValue(\"key\") or ->ConfTags(\"key\") instead"); } @@ -597,13 +686,27 @@ void FileReader::CalcSize() void FileReader::LoadFile(const std::string &filename) { - file_cache c; - c.clear(); - if (ServerInstance->Config->ReadFile(c,filename.c_str())) + std::map::iterator file = ServerInstance->Config->Files.find(filename); + if (file != ServerInstance->Config->Files.end()) { - this->fc = c; - this->CalcSize(); + this->fc = file->second; + } + else + { + fc.clear(); + FILE* f = fopen(filename.c_str(), "r"); + if (!f) + return; + char linebuf[MAXBUF*10]; + while (fgets(linebuf, sizeof(linebuf), f)) + { + int len = strlen(linebuf); + if (len) + fc.push_back(std::string(linebuf, len - 1)); + } + fclose(f); } + CalcSize(); }