summaryrefslogtreecommitdiff
path: root/src/modules.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules.cpp')
-rw-r--r--src/modules.cpp324
1 files changed, 161 insertions, 163 deletions
diff --git a/src/modules.cpp b/src/modules.cpp
index cf2724b7a..0ddd6bdab 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -210,6 +210,167 @@ const char* ModuleManager::LastError()
return MODERR;
}
+bool ModuleManager::Load(const char* filename)
+{
+ /* Do we have a glob pattern in the filename?
+ * The user wants to load multiple modules which
+ * match the pattern.
+ */
+ if (strchr(filename,'*') || (strchr(filename,'?')))
+ {
+ int n_match = 0;
+ DIR* library = opendir(Instance->Config->ModPath);
+ if (library)
+ {
+ /* Try and locate and load all modules matching the pattern */
+ dirent* entry = NULL;
+ while ((entry = readdir(library)))
+ {
+ if (Instance->MatchText(entry->d_name, filename))
+ {
+ if (!this->Load(entry->d_name))
+ n_match++;
+ }
+ }
+ closedir(library);
+ }
+ /* Loadmodule will now return false if any one of the modules failed
+ * to load (but wont abort when it encounters a bad one) and when 1 or
+ * more modules were actually loaded.
+ */
+ return (n_match > 0);
+ }
+
+ char modfile[MAXBUF];
+ snprintf(modfile,MAXBUF,"%s/%s",Instance->Config->ModPath,filename);
+ std::string filename_str = filename;
+
+ if (!ServerConfig::DirValid(modfile))
+ {
+ snprintf(MODERR, MAXBUF,"Module %s is not within the modules directory.", modfile);
+ Instance->Log(DEFAULT, MODERR);
+ return false;
+ }
+
+ if (!ServerConfig::FileExists(modfile))
+ {
+ snprintf(MODERR,MAXBUF,"Module file could not be found: %s", modfile);
+ Instance->Log(DEFAULT, MODERR);
+ return false;
+ }
+
+ if(find(Instance->Config->module_names.begin(), Instance->Config->module_names.end(), filename_str) != Instance->Config->module_names.end())
+ {
+ Instance->Log(DEFAULT,"Module %s is already loaded, cannot load a module twice!",modfile);
+ snprintf(MODERR, MAXBUF, "Module already loaded");
+ return false;
+ }
+
+ Module* newmod;
+ ircd_module* newhandle;
+
+ newmod = NULL;
+ newhandle = NULL;
+
+ try
+ {
+ /* This will throw a CoreException if there's a problem loading
+ * the module file or getting a pointer to the init_module symbol.
+ */
+ newhandle = new ircd_module(Instance, modfile, "init_module");
+
+ handles[this->ModCount+1] = newhandle;
+
+ newmod = handles[this->ModCount+1]->CallInit();
+
+ if(newmod)
+ {
+ Version v = newmod->GetVersion();
+
+ if (v.API != API_VERSION)
+ {
+ delete newmod;
+ Instance->Log(DEFAULT,"Unable to load %s: Incorrect module API version: %d (our version: %d)",modfile,v.API,API_VERSION);
+ snprintf(MODERR,MAXBUF,"Loader/Linker error: Incorrect module API version: %d (our version: %d)",v.API,API_VERSION);
+ return false;
+ }
+ else
+ {
+ Instance->Log(DEFAULT,"New module introduced: %s (API version %d, Module version %d.%d.%d.%d)%s", filename, v.API, v.Major, v.Minor, v.Revision, v.Build, (!(v.Flags & VF_VENDOR) ? " [3rd Party]" : " [Vendor]"));
+ }
+
+ modules[this->ModCount+1] = newmod;
+
+ /* save the module and the module's classfactory, if
+ * this isnt done, random crashes can occur :/ */
+ Instance->Config->module_names.push_back(filename);
+
+ char* x = &Instance->Config->implement_lists[this->ModCount+1][0];
+ for(int t = 0; t < 255; t++)
+ x[t] = 0;
+
+ modules[this->ModCount+1]->Implements(x);
+
+ for(int t = 0; t < 255; t++)
+ Instance->Config->global_implementation[t] += Instance->Config->implement_lists[this->ModCount+1][t];
+ }
+ else
+ {
+ Instance->Log(DEFAULT, "Unable to load %s",modfile);
+ snprintf(MODERR,MAXBUF, "Probably missing init_module() entrypoint, but dlsym() didn't notice a problem");
+ return false;
+ }
+ }
+ catch (LoadModuleException& modexcept)
+ {
+ Instance->Log(DEFAULT,"Unable to load %s: %s", modfile, modexcept.GetReason());
+ snprintf(MODERR,MAXBUF,"Loader/Linker error: %s", modexcept.GetReason());
+ return false;
+ }
+ catch (FindSymbolException& modexcept)
+ {
+ Instance->Log(DEFAULT,"Unable to load %s: %s", modfile, modexcept.GetReason());
+ snprintf(MODERR,MAXBUF,"Loader/Linker error: %s", modexcept.GetReason());
+ return false;
+ }
+ catch (CoreException& modexcept)
+ {
+ Instance->Log(DEFAULT,"Unable to load %s: %s",modfile,modexcept.GetReason());
+ snprintf(MODERR,MAXBUF,"Factory function of %s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
+ return false;
+ }
+
+ this->ModCount++;
+ FOREACH_MOD_I(Instance,I_OnLoadModule,OnLoadModule(modules[this->ModCount],filename_str));
+ // now work out which modules, if any, want to move to the back of the queue,
+ // and if they do, move them there.
+ std::vector<std::string> put_to_back;
+ std::vector<std::string> put_to_front;
+ std::map<std::string,std::string> put_before;
+ std::map<std::string,std::string> put_after;
+ for (unsigned int j = 0; j < Instance->Config->module_names.size(); j++)
+ {
+ if (modules[j]->Prioritize() == PRIORITY_LAST)
+ put_to_back.push_back(Instance->Config->module_names[j]);
+ else if (modules[j]->Prioritize() == PRIORITY_FIRST)
+ put_to_front.push_back(Instance->Config->module_names[j]);
+ else if ((modules[j]->Prioritize() & 0xFF) == PRIORITY_BEFORE)
+ put_before[Instance->Config->module_names[j]] = Instance->Config->module_names[modules[j]->Prioritize() >> 8];
+ else if ((modules[j]->Prioritize() & 0xFF) == PRIORITY_AFTER)
+ put_after[Instance->Config->module_names[j]] = Instance->Config->module_names[modules[j]->Prioritize() >> 8];
+ }
+ for (unsigned int j = 0; j < put_to_back.size(); j++)
+ MoveToLast(put_to_back[j]);
+ for (unsigned int j = 0; j < put_to_front.size(); j++)
+ MoveToFirst(put_to_front[j]);
+ for (std::map<std::string,std::string>::iterator j = put_before.begin(); j != put_before.end(); j++)
+ MoveBefore(j->first,j->second);
+ for (std::map<std::string,std::string>::iterator j = put_after.begin(); j != put_after.end(); j++)
+ MoveAfter(j->first,j->second);
+ Instance->BuildISupport();
+ return true;
+}
+
bool ModuleManager::EraseHandle(unsigned int j)
{
ModuleHandleList::iterator iter;
@@ -441,169 +602,6 @@ void ModuleManager::LoadAll()
Instance->Log(DEFAULT,"Total loaded modules: %d", this->GetCount());
}
-bool ModuleManager::Load(const char* filename)
-{
- /* Do we have a glob pattern in the filename?
- * The user wants to load multiple modules which
- * match the pattern.
- */
- if (strchr(filename,'*') || (strchr(filename,'?')))
- {
- int n_match = 0;
- DIR* library = opendir(Instance->Config->ModPath);
- if (library)
- {
- /* Try and locate and load all modules matching the pattern */
- dirent* entry = NULL;
- while ((entry = readdir(library)))
- {
- if (Instance->MatchText(entry->d_name, filename))
- {
- if (!this->Load(entry->d_name))
- n_match++;
- }
- }
- closedir(library);
- }
- /* Loadmodule will now return false if any one of the modules failed
- * to load (but wont abort when it encounters a bad one) and when 1 or
- * more modules were actually loaded.
- */
- return (n_match > 0);
- }
-
- char modfile[MAXBUF];
- snprintf(modfile,MAXBUF,"%s/%s",Instance->Config->ModPath,filename);
- std::string filename_str = filename;
-
- if (!ServerConfig::DirValid(modfile))
- {
- snprintf(MODERR, MAXBUF,"Module %s is not within the modules directory.", modfile);
- Instance->Log(DEFAULT, MODERR);
- return false;
- }
-
- if (ServerConfig::FileExists(modfile))
- {
- for (unsigned int j = 0; j < Instance->Config->module_names.size(); j++)
- {
- if (Instance->Config->module_names[j] == filename_str)
- {
- Instance->Log(DEFAULT,"Module %s is already loaded, cannot load a module twice!",modfile);
- snprintf(MODERR, MAXBUF, "Module already loaded");
- return false;
- }
- }
-
- Module* m = NULL;
- ircd_module* a = NULL;
-
- try
- {
- /* This will throw a CoreException if there's a problem loading
- * the module file or getting a pointer to the init_module symbol.
- */
- a = new ircd_module(Instance, modfile, "init_module");
-
- handles[this->ModCount+1] = a;
-
- m = handles[this->ModCount+1]->CallInit();
-
- if(m)
- {
- Version v = m->GetVersion();
-
- if (v.API != API_VERSION)
- {
- delete m;
- Instance->Log(DEFAULT,"Unable to load %s: Incorrect module API version: %d (our version: %d)",modfile,v.API,API_VERSION);
- snprintf(MODERR,MAXBUF,"Loader/Linker error: Incorrect module API version: %d (our version: %d)",v.API,API_VERSION);
- return false;
- }
- else
- {
- Instance->Log(DEFAULT,"New module introduced: %s (API version %d, Module version %d.%d.%d.%d)%s", filename, v.API, v.Major, v.Minor, v.Revision, v.Build, (!(v.Flags & VF_VENDOR) ? " [3rd Party]" : " [Vendor]"));
- }
-
- modules[this->ModCount+1] = m;
-
- /* save the module and the module's classfactory, if
- * this isnt done, random crashes can occur :/ */
- Instance->Config->module_names.push_back(filename);
-
- char* x = &Instance->Config->implement_lists[this->ModCount+1][0];
- for(int t = 0; t < 255; t++)
- x[t] = 0;
-
- modules[this->ModCount+1]->Implements(x);
-
- for(int t = 0; t < 255; t++)
- Instance->Config->global_implementation[t] += Instance->Config->implement_lists[this->ModCount+1][t];
- }
- else
- {
- Instance->Log(DEFAULT, "Unable to load %s",modfile);
- snprintf(MODERR,MAXBUF, "Probably missing init_module() entrypoint, but dlsym() didn't notice a problem");
- return false;
- }
- }
- catch (LoadModuleException& modexcept)
- {
- Instance->Log(DEFAULT,"Unable to load %s: %s", modfile, modexcept.GetReason());
- snprintf(MODERR,MAXBUF,"Loader/Linker error: %s", modexcept.GetReason());
- return false;
- }
- catch (FindSymbolException& modexcept)
- {
- Instance->Log(DEFAULT,"Unable to load %s: %s", modfile, modexcept.GetReason());
- snprintf(MODERR,MAXBUF,"Loader/Linker error: %s", modexcept.GetReason());
- return false;
- }
- catch (CoreException& modexcept)
- {
- Instance->Log(DEFAULT,"Unable to load %s: %s",modfile,modexcept.GetReason());
- snprintf(MODERR,MAXBUF,"Factory function of %s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
- return false;
- }
- }
- else
- {
- Instance->Log(DEFAULT,"InspIRCd: startup: Module Not Found %s",modfile);
- snprintf(MODERR,MAXBUF,"Module file could not be found");
- return false;
- }
-
- this->ModCount++;
- FOREACH_MOD_I(Instance,I_OnLoadModule,OnLoadModule(modules[this->ModCount],filename_str));
- // now work out which modules, if any, want to move to the back of the queue,
- // and if they do, move them there.
- std::vector<std::string> put_to_back;
- std::vector<std::string> put_to_front;
- std::map<std::string,std::string> put_before;
- std::map<std::string,std::string> put_after;
- for (unsigned int j = 0; j < Instance->Config->module_names.size(); j++)
- {
- if (modules[j]->Prioritize() == PRIORITY_LAST)
- put_to_back.push_back(Instance->Config->module_names[j]);
- else if (modules[j]->Prioritize() == PRIORITY_FIRST)
- put_to_front.push_back(Instance->Config->module_names[j]);
- else if ((modules[j]->Prioritize() & 0xFF) == PRIORITY_BEFORE)
- put_before[Instance->Config->module_names[j]] = Instance->Config->module_names[modules[j]->Prioritize() >> 8];
- else if ((modules[j]->Prioritize() & 0xFF) == PRIORITY_AFTER)
- put_after[Instance->Config->module_names[j]] = Instance->Config->module_names[modules[j]->Prioritize() >> 8];
- }
- for (unsigned int j = 0; j < put_to_back.size(); j++)
- MoveToLast(put_to_back[j]);
- for (unsigned int j = 0; j < put_to_front.size(); j++)
- MoveToFirst(put_to_front[j]);
- for (std::map<std::string,std::string>::iterator j = put_before.begin(); j != put_before.end(); j++)
- MoveBefore(j->first,j->second);
- for (std::map<std::string,std::string>::iterator j = put_after.begin(); j != put_after.end(); j++)
- MoveAfter(j->first,j->second);
- Instance->BuildISupport();
- return true;
-}
-
long ModuleManager::PriorityAfter(const std::string &modulename)
{
for (unsigned int j = 0; j < Instance->Config->module_names.size(); j++)