X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules.cpp;h=b2d2f23c68af1acf45b429bd3de819298f0393de;hb=4c751dbbe8945e5efc230a59b0ed51c2ba10cf92;hp=8af5b95e33e1153d9b298ae212de4f19fc78b1d6;hpb=cd6b7a8cda83f54679634624e84e92b91cf80683;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules.cpp b/src/modules.cpp index 8af5b95e3..b2d2f23c6 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -1,16 +1,29 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ +/* + * InspIRCd -- Internet Relay Chat Daemon * - * InspIRCd: (C) 2002-2010 InspIRCd Development Team - * See: http://wiki.inspircd.org/Credits + * Copyright (C) 2009-2010 Daniel De Graaf + * Copyright (C) 2007, 2009 Dennis Friis + * Copyright (C) 2003-2008 Craig Edwards + * Copyright (C) 2008 Thomas Stagner + * Copyright (C) 2006-2007 Robin Burchell + * Copyright (C) 2006-2007 Oliver Lupton + * Copyright (C) 2007 Pippijn van Steenhoven + * Copyright (C) 2003 randomdan * - * This program is free but copyrighted software; see - * the file COPYING for details. + * 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 . */ + #include "inspircd.h" #include "xline.h" #include "socket.h" @@ -19,7 +32,7 @@ #include "dns.h" #include "exitcodes.h" -#ifndef WIN32 +#ifndef _WIN32 #include #endif @@ -163,6 +176,7 @@ ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MO void Module::OnHookIO(StreamSocket*, ListenSocket*) { } ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { return MOD_RES_PASSTHRU; } void Module::OnSendWhoLine(User*, const std::vector&, User*, std::string&) { } +void Module::OnSetUserIP(LocalUser*) { } ModuleManager::ModuleManager() : ModCount(0) { @@ -174,9 +188,6 @@ 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; @@ -303,7 +314,7 @@ swap_now: for (unsigned int j = my_pos; j != swap_pos; j += incrmnt) { - if (( j + incrmnt > EventHandlers[i].size() - 1) || (j + incrmnt < 0)) + if ((j + incrmnt > EventHandlers[i].size() - 1) || ((incrmnt == -1) && (j == 0))) continue; std::swap(EventHandlers[i][j], EventHandlers[i][j+incrmnt]); @@ -317,7 +328,7 @@ bool ModuleManager::CanUnload(Module* mod) { std::map::iterator modfind = Modules.find(mod->ModuleSourceFile); - if (modfind == Modules.end() || modfind->second != mod) + if ((modfind == Modules.end()) || (modfind->second != mod) || (mod->dying)) { LastModuleError = "Module " + mod->ModuleSourceFile + " is not loaded, cannot unload it!"; ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError); @@ -329,6 +340,8 @@ bool ModuleManager::CanUnload(Module* mod) ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError); return false; } + + mod->dying = true; return true; } @@ -339,18 +352,23 @@ void ModuleManager::DoSafeUnload(Module* mod) 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++) + for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); ) { - mod->OnCleanup(TYPE_CHANNEL,c->second); - c->second->doUnhookExtensions(items); - const UserMembList* users = c->second->GetUsers(); + Channel* chan = c->second; + ++c; + mod->OnCleanup(TYPE_CHANNEL, chan); + chan->doUnhookExtensions(items); + const UserMembList* users = chan->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++) + for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); ) { - mod->OnCleanup(TYPE_USER,u->second); - u->second->doUnhookExtensions(items); + User* user = u->second; + // The module may quit the user (e.g. SSL mod unloading) and that will remove it from the container + ++u; + mod->OnCleanup(TYPE_USER, user); + user->doUnhookExtensions(items); } for(char m='A'; m <= 'z'; m++) { @@ -426,10 +444,6 @@ bool InspIRCd::IsValidModuleCommand(const std::string &commandname, int pcnt, Us 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: @@ -441,7 +455,8 @@ void ModuleManager::AddService(ServiceProvider& item) throw ModuleException("Mode "+std::string(item.name)+" already exists."); return; case SERVICE_METADATA: - ServerInstance->Extensions.Register(static_cast(&item)); + if (!ServerInstance->Extensions.Register(static_cast(&item))) + throw ModuleException("Extension " + std::string(item.name) + " already exists."); return; case SERVICE_DATA: case SERVICE_IOHOOK: @@ -551,7 +566,7 @@ dynamic_reference_base::operator bool() if (i != ServerInstance->Modules->DataProviders.end()) value = static_cast(i->second); } - return value; + return (value != NULL); } void InspIRCd::SendMode(const std::vector& parameters, User *user) @@ -755,7 +770,7 @@ bool FileReader::Exists() std::string FileReader::GetLine(int x) { - if ((x<0) || ((unsigned)x>fc.size())) + if ((x<0) || ((unsigned)x>=fc.size())) return ""; return fc[x]; }