#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
*/
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);
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.
* @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()
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
}
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)
// 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);
}
}
+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;
{
}
- void Call()
+ void Call() CXX11_OVERRIDE
{
ReloadModule::DataKeeper datakeeper;
datakeeper.Save(mod);
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);
}
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;
}
}
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;
}
}