]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/coremods/core_reloadmodule.cpp
Use an oper priv instead of a config flag for overriding nonicks.
[user/henk/code/inspircd.git] / src / coremods / core_reloadmodule.cpp
index fd99a5f7e78515881b5ac680ac34c2d15ddd811c..9101442216465c477df8dbfe5911ff47729e1215 100644 (file)
 
 #include "inspircd.h"
 #include "listmode.h"
+#include "modules/reload.h"
+
+static Events::ModuleEventProvider* reloadevprov;
 
 class CommandReloadmodule : public Command
 {
+       Events::ModuleEventProvider evprov;
  public:
        /** Constructor for reloadmodule.
         */
-       CommandReloadmodule ( Module* parent) : Command( parent, "RELOADMODULE",1) { flags_needed = 'o'; syntax = "<modulename>"; }
+       CommandReloadmodule(Module* parent)
+               : Command(parent, "RELOADMODULE", 1)
+               , evprov(parent, "event/reloadmodule")
+       {
+               reloadevprov = &evprov;
+               flags_needed = 'o';
+               syntax = "<modulename>";
+       }
+
        /** Handle command.
         * @param parameters The parameters to the command
         * @param user The user issuing the command
         * @return A value from CmdResult to indicate command success or failure.
         */
-       CmdResult Handle(const std::vector<std::string>& parameters, User *user);
+       CmdResult Handle(const std::vector<std::string>& parameters, User* user) CXX11_OVERRIDE;
 };
 
 namespace ReloadModule
@@ -153,6 +165,10 @@ class DataKeeper
         */
        std::vector<ChanData> chandatalist;
 
+       /** Data attached by modules
+        */
+       ReloadModule::CustomData moddata;
+
        void SaveExtensions(Extensible* extensible, std::vector<InstanceData>& extdatalist);
        void SaveMemberData(Channel* chan, std::vector<ChanData::MemberData>& memberdatalist);
        static void SaveListModes(Channel* chan, ListModeBase* lm, size_t index, ModesExts& currdata);
@@ -172,6 +188,7 @@ class DataKeeper
 
        void DoRestoreUsers();
        void DoRestoreChans();
+       void DoRestoreModules();
 
        /** Restore previously saved modes and extensions on an Extensible.
         * The extensions are set directly on the extensible, the modes are added into the provided mode change list.
@@ -219,6 +236,10 @@ class DataKeeper
         * @param newmod Newly loaded instance of the module which had its data saved
         */
        void Restore(Module* newmod);
+
+       /** Handle reload failure
+        */
+       void Fail();
 };
 
 void DataKeeper::DoSaveUsers()
@@ -332,7 +353,8 @@ void DataKeeper::SaveMemberData(Channel* chan, std::vector<OwnedModesExts>& memb
                for (size_t j = 0; j < handledmodes[MODETYPE_CHANNEL].size(); j++)
                {
                        ModeHandler* mh = handledmodes[MODETYPE_CHANNEL][j].mh;
-                       if ((mh->IsPrefixMode()) && (memb->hasMode(mh->GetModeChar())))
+                       const PrefixMode* const pm = mh->IsPrefixMode();
+                       if ((pm) && (memb->HasMode(pm)))
                                currdata.modelist.push_back(InstanceData(j, memb->user->uuid)); // Need to pass the user's uuid to the mode parser to set the mode later
                }
 
@@ -399,7 +421,9 @@ void DataKeeper::Save(Module* currmod)
        CreateModeList(MODETYPE_CHANNEL);
        DoSaveChans();
 
-       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Saved data about %lu users %lu chans", (unsigned long)userdatalist.size(), (unsigned long)chandatalist.size());
+       FOREACH_MOD_CUSTOM(*reloadevprov, ReloadModule::EventListener, OnReloadModuleSave, (mod, this->moddata));
+
+       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Saved data about %lu users %lu chans %lu modules", (unsigned long)userdatalist.size(), (unsigned long)chandatalist.size(), (unsigned long)moddata.list.size());
 }
 
 void DataKeeper::VerifyServiceProvider(const ProviderInfo& service, const char* type)
@@ -444,10 +468,19 @@ void DataKeeper::Restore(Module* newmod)
        // Restore
        DoRestoreUsers();
        DoRestoreChans();
+       DoRestoreModules();
 
        ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Restore finished");
 }
 
+void DataKeeper::Fail()
+{
+       this->mod = NULL;
+
+       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Restore failed, notifying modules");
+       DoRestoreModules();
+}
+
 void DataKeeper::RestoreObj(const OwnedModesExts& data, Extensible* extensible, ModeType modetype, Modes::ChangeList& modechange)
 {
        RestoreExtensions(data.extlist, extensible);
@@ -520,9 +553,19 @@ void DataKeeper::DoRestoreChans()
        }
 }
 
+void DataKeeper::DoRestoreModules()
+{
+       for (ReloadModule::CustomData::List::iterator i = moddata.list.begin(); i != moddata.list.end(); ++i)
+       {
+               ReloadModule::CustomData::Data& data = *i;
+               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Calling module data handler %p", (void*)data.handler);
+               data.handler->OnReloadModuleRestore(mod, data.data);
+       }
+}
+
 } // namespace ReloadModule
 
-class ReloadAction : public HandlerBase0<void>
+class ReloadAction : public ActionBase
 {
        Module* const mod;
        const std::string uuid;
@@ -536,7 +579,7 @@ class ReloadAction : public HandlerBase0<void>
        {
        }
 
-       void Call()
+       void Call() CXX11_OVERRIDE
        {
                ReloadModule::DataKeeper datakeeper;
                datakeeper.Save(mod);
@@ -553,11 +596,13 @@ class ReloadAction : public HandlerBase0<void>
                        Module* newmod = ServerInstance->Modules->Find(name);
                        datakeeper.Restore(newmod);
                }
+               else
+                       datakeeper.Fail();
 
                ServerInstance->SNO->WriteGlobalSno('a', "RELOAD MODULE: %s %ssuccessfully reloaded", passedname.c_str(), result ? "" : "un");
                User* user = ServerInstance->FindUUID(uuid);
                if (user)
-                       user->WriteNumeric(RPL_LOADEDMODULE, "%s :Module %ssuccessfully reloaded.", passedname.c_str(), result ? "" : "un");
+                       user->WriteNumeric(RPL_LOADEDMODULE, passedname, InspIRCd::Format("Module %ssuccessfully reloaded.", (result ? "" : "un")));
 
                ServerInstance->GlobalCulls.AddItem(this);
        }
@@ -568,8 +613,7 @@ CmdResult CommandReloadmodule::Handle (const std::vector<std::string>& parameter
        Module* m = ServerInstance->Modules->Find(parameters[0]);
        if (m == creator)
        {
-               user->WriteNumeric(RPL_LOADEDMODULE, "%s :You cannot reload core_reloadmodule.so (unload and load it)",
-                       parameters[0].c_str());
+               user->WriteNumeric(RPL_LOADEDMODULE, parameters[0], "You cannot reload core_reloadmodule (unload and load it)");
                return CMD_FAILURE;
        }
 
@@ -583,7 +627,7 @@ CmdResult CommandReloadmodule::Handle (const std::vector<std::string>& parameter
        }
        else
        {
-               user->WriteNumeric(RPL_LOADEDMODULE, "%s :Could not find module by that name", parameters[0].c_str());
+               user->WriteNumeric(RPL_LOADEDMODULE, parameters[0], "Could not find module by that name");
                return CMD_FAILURE;
        }
 }