]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules.cpp
Match USERINPUT/USEROUTPUT identifiers
[user/henk/code/inspircd.git] / src / modules.cpp
index f8989b415c5c3f87d56d1f470ebf3db51144d2ea..b3aabf284c10f6fb6f111987df5f1bade731378a 100644 (file)
@@ -24,9 +24,9 @@
 #endif
 
 
-// version is a simple class for holding a modules version number
+// Version is a simple class for holding a modules version number
 template<>
-VersionBase<API_VERSION>::VersionBase(const std::string &modv, int flags, int, const std::string& rev)
+VersionBase<API_VERSION>::VersionBase(const std::string &modv, int flags, const std::string& rev)
 : description(modv), version(rev), Flags(flags)
 {
 }
@@ -52,16 +52,18 @@ void Event::Send()
 // 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&) { }
@@ -87,8 +89,8 @@ void          Module::OnUnloadModule(Module*) { }
 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; }
@@ -99,8 +101,8 @@ ModResult    Module::OnCheckChannelBan(User*, Channel*) { 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&) { }
@@ -145,7 +147,8 @@ 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*, 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; }
 
@@ -321,6 +324,9 @@ std::string& ModuleManager::LastError()
 
 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.
@@ -457,7 +463,7 @@ void ModuleManager::DoSafeUnload(Module* mod)
 {
        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++)
@@ -473,6 +479,16 @@ void ModuleManager::DoSafeUnload(Module* mod)
                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);
@@ -571,11 +587,10 @@ void ModuleManager::LoadAll()
                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());
 
@@ -604,8 +619,7 @@ void ModuleManager::UnloadAll()
                        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();
@@ -768,54 +782,6 @@ void InspIRCd::SendMode(const std::vector<std::string>& parameters, User *user)
        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)
@@ -857,12 +823,23 @@ ConfigReader::~ConfigReader()
 {
 }
 
+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;
        }
@@ -877,7 +854,7 @@ std::string ConfigReader::ReadValue(const std::string &tag, const std::string &n
 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)
@@ -889,7 +866,7 @@ bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, int
 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))
        {
@@ -917,7 +894,7 @@ int ConfigReader::Enumerate(const std::string &tag)
        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;
 }