// These declarations define the behavours of the base class Module (which does nothing at all)
Module::Module() { }
-bool Module::cull()
+CullResult Module::cull()
+{
+ return classbase::cull();
+}
+Module::~Module()
{
- return true;
}
-Module::~Module() { }
ModResult Module::OnSendSnotice(char &snomask, std::string &type, const std::string &message) { return MOD_RES_PASSTHRU; }
-void Module::OnUserConnect(User*) { }
+void Module::OnUserConnect(LocalUser*) { }
void Module::OnUserQuit(User*, const std::string&, const std::string&) { }
-void Module::OnUserDisconnect(User*) { }
+void Module::OnUserDisconnect(LocalUser*) { }
void Module::OnUserJoin(Membership*, bool, bool, CUList&) { }
void Module::OnPostJoin(Membership*) { }
void Module::OnUserPart(Membership*, std::string&, CUList&) { }
void Module::OnBackgroundTimer(time_t) { }
ModResult Module::OnPreCommand(std::string&, std::vector<std::string>&, User *, bool, const std::string&) { return MOD_RES_PASSTHRU; }
void Module::OnPostCommand(const std::string&, const std::vector<std::string>&, User *, CmdResult, const std::string&) { }
-ModResult Module::OnCheckReady(User*) { return MOD_RES_PASSTHRU; }
-ModResult Module::OnUserRegister(User*) { return MOD_RES_PASSTHRU; }
+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; }
void Module::OnUserKick(User*, Membership*, const std::string&, CUList&) { }
ModResult Module::OnRawMode(User*, Channel*, const char, const std::string &, bool, int) { return MOD_RES_PASSTHRU; }
ModResult Module::OnCheckBan(User*, Channel*, const std::string&) { return MOD_RES_PASSTHRU; }
ModResult Module::OnExtBanCheck(User*, Channel*, char) { return MOD_RES_PASSTHRU; }
ModResult Module::OnStats(char, User*, string_list&) { return MOD_RES_PASSTHRU; }
-ModResult Module::OnChangeLocalUserHost(User*, const std::string&) { return MOD_RES_PASSTHRU; }
-ModResult Module::OnChangeLocalUserGECOS(User*, const std::string&) { return MOD_RES_PASSTHRU; }
+ModResult Module::OnChangeLocalUserHost(LocalUser*, const std::string&) { return MOD_RES_PASSTHRU; }
+ModResult Module::OnChangeLocalUserGECOS(LocalUser*, const std::string&) { return MOD_RES_PASSTHRU; }
ModResult Module::OnPreTopicChange(User*, Channel*, const std::string&) { return MOD_RES_PASSTHRU; }
void Module::OnEvent(Event&) { }
void Module::OnRequest(Request&) { }
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*, ListenSocketBase*) { }
+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&) { }
ModResult Module::OnChannelRestrictionApply(User*, Channel*, const char*) { return MOD_RES_PASSTHRU; }
bool ModuleManager::Load(const char* filename)
{
+ /* Don't allow people to specify paths for modules, it doesn't work as expected */
+ if (strchr(filename, '/'))
+ return false;
/* Do we have a glob pattern in the filename?
* The user wants to load multiple modules which
* match the pattern.
{
std::map<std::string, Module*>::iterator modfind = Modules.find(mod->ModuleSourceFile);
- std::vector<ExtensionItem*> items;
+ std::vector<reference<ExtensionItem> > 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_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);
+ }
/* Tidy up any dangling resolvers */
ServerInstance->Res->CleanResolvers(mod);
printf("\n");
}
- for(int count = 0;; count++)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("module");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("module", count);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string name = tag->getString("name");
printf_c("[\033[1;32m*\033[0m] Loading module:\t\033[1;32m%s\033[0m\n",name.c_str());
std::map<std::string, Module*>::iterator me = i++;
if (CanUnload(me->second))
{
- ServerInstance->GlobalCulls.AddItem(me->second);
- Modules.erase(me);
+ DoSafeUnload(me->second);
}
}
ServerInstance->GlobalCulls.Apply();
this->Modes->Process(parameters, user);
}
-void InspIRCd::DumpText(User* user, const std::string &text)
-{
- if (IS_LOCAL(user))
- {
- user->Write(text);
- }
- else
- {
- PI->PushToClient(user, text);
- }
-}
-
-void InspIRCd::DumpText(User* user, const char *text, ...)
-{
- va_list argsPtr;
- char line[MAXBUF];
-
- va_start(argsPtr, text);
- vsnprintf(line, MAXBUF, text, argsPtr);
- va_end(argsPtr);
-
- DumpText(user, std::string(line));
-}
-
-void InspIRCd::DumpText(User* user, const std::string &LinePrefix, std::stringstream &TextStream)
-{
- char line[MAXBUF];
- int start_pos = LinePrefix.length();
- int pos = start_pos;
- memcpy(line, LinePrefix.data(), pos);
- std::string Word;
- while (TextStream >> Word)
- {
- int len = Word.length();
- if (pos + len + 12 > MAXBUF)
- {
- line[pos] = '\0';
- DumpText(user, std::string(line));
- pos = start_pos;
- }
- line[pos] = ' ';
- memcpy(line + pos + 1, Word.data(), len);
- pos += len + 1;
- }
- line[pos] = '\0';
- DumpText(user, std::string(line));
-}
-
bool InspIRCd::AddResolver(Resolver* r, bool cached)
{
if (!cached)
{
}
+static ConfigTag* SlowGetTag(const std::string &tag, int index)
+{
+ ConfigTagList tags = ServerInstance->Config->ConfTags(tag);
+ while (tags.first != tags.second)
+ {
+ if (!index)
+ return tags.first->second;
+ tags.first++;
+ index--;
+ }
+ return NULL;
+}
std::string ConfigReader::ReadValue(const std::string &tag, const std::string &name, const std::string &default_value, int index, bool allow_linefeeds)
{
- /* Don't need to strlcpy() tag and name anymore, ReadConf() takes const char* */
std::string result = default_value;
- if (!ServerInstance->Config->ConfValue(tag, index)->readString(name, result, allow_linefeeds))
+ if (!SlowGetTag(tag, index)->readString(name, result, allow_linefeeds))
{
this->error = CONF_VALUE_NOT_FOUND;
}
bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, const std::string &default_value, int index)
{
bool def = (default_value == "yes");
- return ServerInstance->Config->ConfValue(tag, index)->getBool(name, def);
+ return SlowGetTag(tag, index)->getBool(name, def);
}
bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, int index)
int ConfigReader::ReadInteger(const std::string &tag, const std::string &name, const std::string &default_value, int index, bool need_positive)
{
int v = atoi(default_value.c_str());
- int result = ServerInstance->Config->ConfValue(tag, index)->getInt(name, v);
+ int result = SlowGetTag(tag, index)->getInt(name, v);
if ((need_positive) && (result < 0))
{
ServerInstance->Logs->Log("MODULE", DEBUG, "Module is using ConfigReader::Enumerate on %s; this is slow!",
tag.c_str());
int i=0;
- while (ServerInstance->Config->ConfValue(tag, i)) i++;
+ while (SlowGetTag(tag, i)) i++;
return i;
}