summaryrefslogtreecommitdiff
path: root/src/modules.c
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2010-06-19 11:54:08 -0400
committerAdam <Adam@anope.org>2010-06-19 11:54:08 -0400
commit52058fe87b4b0475b1775198c725af14e540d355 (patch)
treec3597d6411a006ffbb670d2ce761101b9640e9b6 /src/modules.c
parent43e951aed54f838ba55a4c1552214773aee2fb2f (diff)
parentdf9d291bcba9788e51d11424ebaf6f05c26cc80f (diff)
Merge remote branch 'origin/1.9.3' into 1.9
Diffstat (limited to 'src/modules.c')
-rw-r--r--src/modules.c784
1 files changed, 0 insertions, 784 deletions
diff --git a/src/modules.c b/src/modules.c
deleted file mode 100644
index 40c10144f..000000000
--- a/src/modules.c
+++ /dev/null
@@ -1,784 +0,0 @@
-/* Modular support
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-#include "modules.h"
-#include "language.h"
-#include "version.h"
-
-/**
- * Declare all the list's we want to use here
- **/
-CommandHash *HOSTSERV[MAX_CMD_HASH];
-CommandHash *BOTSERV[MAX_CMD_HASH];
-CommandHash *MEMOSERV[MAX_CMD_HASH];
-CommandHash *NICKSERV[MAX_CMD_HASH];
-CommandHash *CHANSERV[MAX_CMD_HASH];
-CommandHash *OPERSERV[MAX_CMD_HASH];
-MessageHash *IRCD[MAX_CMD_HASH];
-ModuleHash *MODULE_HASH[MAX_CMD_HASH];
-
-char *mod_current_buffer = NULL;
-
-char *ModuleGetErrStr(int status)
-{
- const char *module_err_str[] = {
- "Module, Okay - No Error", /* MOD_ERR_OK */
- "Module Error, Allocating memory", /* MOD_ERR_MEMORY */
- "Module Error, Not enough parameters", /* MOD_ERR_PARAMS */
- "Module Error, Already loaded", /* MOD_ERR_EXISTS */
- "Module Error, File does not exist", /* MOD_ERR_NOEXIST */
- "Module Error, No User", /* MOD_ERR_NOUSER */
- "Module Error, Error during load time or module returned MOD_STOP", /* MOD_ERR_NOLOAD */
- "Module Error, Unable to unload", /* MOD_ERR_NOUNLOAD */
- "Module Error, Incorrect syntax", /* MOD_ERR_SYNTAX */
- "Module Error, Unable to delete", /* MOD_ERR_NODELETE */
- "Module Error, Unknown Error occuried", /* MOD_ERR_UNKOWN */
- "Module Error, File I/O Error", /* MOD_ERR_FILE_IO */
- "Module Error, No Service found for request", /* MOD_ERR_NOSERVICE */
- "Module Error, No module name for request" /* MOD_ERR_NO_MOD_NAME */
- };
- return const_cast<char *>(module_err_str[status]);
-}
-
-
-/************************************************/
-
-/**
- * Load the ircd protocol module up
- **/
-int protocol_module_init()
-{
- int ret = 0;
-
- Alog() << "Loading IRCD Protocol Module: [" << Config.IRCDModule << "]";
- ret = ModuleManager::LoadModule(Config.IRCDModule, NULL);
-
- if (ret == MOD_ERR_OK)
- {
- findModule(Config.IRCDModule)->SetType(PROTOCOL);
- /* This is really NOT the correct place to do config checks, but
- * as we only have the ircd struct filled here, we have to over
- * here. -GD
- */
- if (ircd->ts6)
- {
- if (!Config.Numeric)
- {
- Alog() << "This IRCd protocol requires a server id to be set in Anope's configuration.";
- ret = -1;
- }
- else
- {
- ts6_uid_init();
- }
- }
- }
-
- return ret;
-}
-
-/**
- * Unload ALL loaded modules, no matter what kind of module it is.
- * Do NEVER EVER, and i mean NEVER (and if that isn't clear enough
- * yet, i mean: NEVER AT ALL) call this unless we're shutting down,
- * or we'll fuck up Anope badly (protocol handling won't work for
- * example). If anyone calls this function without a justified need
- * for it, i reserve the right to break their legs in a painful way.
- * And if that isn't enough discouragement, you'll wake up with your
- * both legs broken tomorrow ;) -GD
- */
-void modules_unload_all(bool unload_proto)
-{
- int idx;
- ModuleHash *mh, *next;
-
- for (idx = 0; idx < MAX_CMD_HASH; idx++) {
- mh = MODULE_HASH[idx];
- while (mh) {
- next = mh->next;
- if (unload_proto || (mh->m->type != PROTOCOL))
- ModuleManager::UnloadModule(mh->m, NULL);
- mh = next;
- }
- }
-}
-
-void Module::InsertLanguage(int langNumber, int ac, const char **av)
-{
- int i;
-
- Alog(LOG_DEBUG) << this->name << "Adding " << ac << " texts for language " << langNumber;
-
- if (this->lang[langNumber].argc > 0) {
- this->DeleteLanguage(langNumber);
- }
-
- this->lang[langNumber].argc = ac;
- this->lang[langNumber].argv = new char *[ac];
- for (i = 0; i < ac; i++) {
- this->lang[langNumber].argv[i] = sstrdup(av[i]);
- }
-}
-
-/**
- * Search the list of loaded modules for the given name.
- * @param name the name of the module to find
- * @return a pointer to the module found, or NULL
- */
-Module *findModule(const char *name)
-{
- int idx;
- ModuleHash *current = NULL;
- if (!name) {
- return NULL;
- }
- idx = CMD_HASH(name);
-
- for (current = MODULE_HASH[idx]; current; current = current->next) {
- if (stricmp(name, current->name) == 0) {
- return current->m;
- }
- }
- return NULL;
-
-}
-
-/*******************************************************************************
- * Command Functions
- *******************************************************************************/
-
-/** Add a command to a command table. Only for internal use.
- * only add if were unique, pos = 0;
- * if we want it at the "head" of that command, pos = 1
- * at the tail, pos = 2
- * @param cmdTable the table to add the command to
- * @param c the command to add
- * @return MOD_ERR_OK will be returned on success.
- */
-static int internal_addCommand(Module *m, CommandHash * cmdTable[], Command * c)
-{
- /* We can assume both param's have been checked by this point.. */
- int index = 0;
- CommandHash *current = NULL;
- CommandHash *newHash = NULL;
- CommandHash *lastHash = NULL;
-
- if (!cmdTable || !c) {
- return MOD_ERR_PARAMS;
- }
-
- index = CMD_HASH(c->name.c_str());
-
- for (current = cmdTable[index]; current; current = current->next) {
- if ((c->service) && (current->c) && (current->c->service)
- && (!strcmp(c->service, current->c->service) == 0)) {
- continue;
- }
- if ((stricmp(c->name.c_str(), current->name) == 0))
- {
- /* the cmd exists, throw an error */
- return MOD_ERR_EXISTS;
- }
- lastHash = current;
- }
-
- newHash = new CommandHash;
- newHash->next = NULL;
- newHash->name = sstrdup(c->name.c_str());
- newHash->c = c;
-
- if (lastHash == NULL)
- cmdTable[index] = newHash;
- else
- lastHash->next = newHash;
-
- return MOD_ERR_OK;
-}
-
-int Module::AddCommand(CommandHash * cmdTable[], Command * c)
-{
- int status;
-
- if (!cmdTable || !c) {
- return MOD_ERR_PARAMS;
- }
- c->core = 0;
- if (!c->mod_name) {
- c->mod_name = sstrdup(this->name.c_str());
- }
-
-
- if (cmdTable == HOSTSERV) {
- if (Config.s_HostServ) {
- c->service = sstrdup(Config.s_HostServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == BOTSERV) {
- if (Config.s_BotServ) {
- c->service = sstrdup(Config.s_BotServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == MEMOSERV) {
- if (Config.s_MemoServ) {
- c->service = sstrdup(Config.s_MemoServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == CHANSERV) {
- if (Config.s_ChanServ) {
- c->service = sstrdup(Config.s_ChanServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == NICKSERV) {
- if (Config.s_NickServ) {
- c->service = sstrdup(Config.s_NickServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == OPERSERV) {
- if (Config.s_OperServ) {
- c->service = sstrdup(Config.s_OperServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else
- c->service = sstrdup("Unknown");
-
- status = internal_addCommand(this, cmdTable, c);
- if (status != MOD_ERR_OK)
- {
- Alog() << "ERROR! [ "<< status << "]";
- }
- return status;
-}
-
-
-/** Remove a command from the command hash. Only for internal use.
- * @param cmdTable the command table to remove the command from
- * @param c the command to remove
- * @param mod_name the name of the module who owns the command
- * @return MOD_ERR_OK will be returned on success
- */
-static int internal_delCommand(CommandHash * cmdTable[], Command * c, const char *mod_name)
-{
- int index = 0;
- CommandHash *current = NULL;
- CommandHash *lastHash = NULL;
- Command *tail = NULL, *last = NULL;
-
- if (!c || !cmdTable) {
- return MOD_ERR_PARAMS;
- }
-
- index = CMD_HASH(c->name.c_str());
- for (current = cmdTable[index]; current; current = current->next) {
- if (stricmp(c->name.c_str(), current->name) == 0) {
- if (!lastHash) {
- tail = current->c;
- if (tail->next) {
- while (tail) {
- if (mod_name && tail->mod_name
- && (stricmp(mod_name, tail->mod_name) == 0)) {
- if (last) {
- last->next = tail->next;
- } else {
- current->c = tail->next;
- }
- return MOD_ERR_OK;
- }
- last = tail;
- tail = tail->next;
- }
- } else {
- cmdTable[index] = current->next;
- delete [] current->name;
- return MOD_ERR_OK;
- }
- } else {
- tail = current->c;
- if (tail->next) {
- while (tail) {
- if (mod_name && tail->mod_name
- && (stricmp(mod_name, tail->mod_name) == 0)) {
- if (last) {
- last->next = tail->next;
- } else {
- current->c = tail->next;
- }
- return MOD_ERR_OK;
- }
- last = tail;
- tail = tail->next;
- }
- } else {
- lastHash->next = current->next;
- delete [] current->name;
- return MOD_ERR_OK;
- }
- }
- }
- lastHash = current;
- }
- return MOD_ERR_NOEXIST;
-}
-
-/**
- * Delete a command from the service given.
- * @param cmdTable the cmdTable for the services to remove the command from
- * @param name the name of the command to delete from the service
- * @return returns MOD_ERR_OK on success
- */
-int Module::DelCommand(CommandHash * cmdTable[], const char *dname)
-{
- Command *c = NULL;
- Command *cmd = NULL;
- int status = 0;
-
- c = findCommand(cmdTable, dname);
- if (!c) {
- return MOD_ERR_NOEXIST;
- }
-
-
- for (cmd = c; cmd; cmd = cmd->next)
- {
- if (cmd->mod_name && cmd->mod_name == this->name)
- {
- status = internal_delCommand(cmdTable, cmd, this->name.c_str());
- }
- }
- return status;
-}
-
-/**
- * Search the command table gieven for a command.
- * @param cmdTable the name of the command table to search
- * @param name the name of the command to look for
- * @return returns a pointer to the found command struct, or NULL
- */
-Command *findCommand(CommandHash * cmdTable[], const char *name)
-{
- int idx;
- CommandHash *current = NULL;
- if (!cmdTable || !name) {
- return NULL;
- }
-
- idx = CMD_HASH(name);
-
- for (current = cmdTable[idx]; current; current = current->next) {
- if (stricmp(name, current->name) == 0) {
- return current->c;
- }
- }
- return NULL;
-}
-
-/*******************************************************************************
- * Message Functions
- *******************************************************************************/
-
- /**
- * Create a new Message struct.
- * @param name the name of the message
- * @param func a pointer to the function to call when we recive this message
- * @return a new Message object
- **/
-Message *createMessage(const char *name,
- int (*func) (const char *source, int ac, const char **av))
-{
- Message *m = NULL;
- if (!name || !func) {
- return NULL;
- }
- if (!(m = new Message)) {
- fatal("Out of memory!");
- }
- m->name = sstrdup(name);
- m->func = func;
- m->core = 0;
- m->next = NULL;
- return m;
-}
-
-/**
- * find a message in the given table.
- * Looks up the message <name> in the MessageHash given
- * @param MessageHash the message table to search for this command, will almost always be IRCD
- * @param name the name of the command were looking for
- * @return NULL if we cant find it, or a pointer to the Message if we can
- **/
-Message *findMessage(MessageHash * msgTable[], const char *name)
-{
- int idx;
- MessageHash *current = NULL;
- if (!msgTable || !name) {
- return NULL;
- }
- idx = CMD_HASH(name);
-
- for (current = msgTable[idx]; current; current = current->next) {
- if (stricmp(name, current->name) == 0) {
- return current->m;
- }
- }
- return NULL;
-}
-
-/**
- * Add a message to the MessageHash.
- * @param msgTable the MessageHash we want to add a message to
- * @param m the Message we want to add
- * @param pos the position we want to add the message to, E.G. MOD_HEAD, MOD_TAIL, MOD_UNIQUE
- * @return MOD_ERR_OK on a successful add.
- **/
-
-int addMessage(MessageHash * msgTable[], Message * m, int pos)
-{
- /* We can assume both param's have been checked by this point.. */
- int index = 0;
- MessageHash *current = NULL;
- MessageHash *newHash = NULL;
- MessageHash *lastHash = NULL;
- Message *tail = NULL;
- int match = 0;
-
- if (!msgTable || !m || (pos < 0 || pos > 2)) {
- return MOD_ERR_PARAMS;
- }
-
- index = CMD_HASH(m->name);
-
- for (current = msgTable[index]; current; current = current->next) {
- match = stricmp(m->name, current->name);
- if (match == 0) { /* the msg exist's we are a addHead */
- if (pos == 1) {
- m->next = current->m;
- current->m = m;
- Alog(LOG_DEBUG) << "existing msg: ("<< static_cast<void *>(m->next)
- << "), new msg (" << static_cast<void *>(m) << ")";
- return MOD_ERR_OK;
- } else if (pos == 2) {
- tail = current->m;
- while (tail->next)
- tail = tail->next;
- Alog(LOG_DEBUG) << "existing msg: ("<< static_cast<void *>(tail)
- << "), new msg (" << static_cast<void *>(m) << ")";
- m->next = NULL;
- return MOD_ERR_OK;
- } else
- return MOD_ERR_EXISTS;
- }
- lastHash = current;
- }
-
- if (!(newHash = new MessageHash)) {
- fatal("Out of memory");
- }
- newHash->next = NULL;
- newHash->name = sstrdup(m->name);
- newHash->m = m;
-
- if (lastHash == NULL)
- msgTable[index] = newHash;
- else
- lastHash->next = newHash;
- return MOD_ERR_OK;
-}
-
-/**
- * Add the given message (m) to the MessageHash marking it as a core command
- * @param msgTable the MessageHash we want to add to
- * @param m the Message we are adding
- * @return MOD_ERR_OK on a successful add.
- **/
-int addCoreMessage(MessageHash * msgTable[], Message * m)
-{
- if (!msgTable || !m) {
- return MOD_ERR_PARAMS;
- }
- m->core = 1;
- return addMessage(msgTable, m, 0);
-}
-
-/**
- * remove the given message from the given message hash, for the given module
- * @param msgTable which MessageHash we are removing from
- * @param m the Message we want to remove
- * @return MOD_ERR_OK on success, althing else on fail.
- **/
-int delMessage(MessageHash * msgTable[], Message * m)
-{
- int index = 0;
- MessageHash *current = NULL;
- MessageHash *lastHash = NULL;
- Message *tail = NULL, *last = NULL;
-
- if (!m || !msgTable) {
- return MOD_ERR_PARAMS;
- }
-
- index = CMD_HASH(m->name);
-
- for (current = msgTable[index]; current; current = current->next) {
- if (stricmp(m->name, current->name) == 0) {
- if (!lastHash) {
- tail = current->m;
- if (tail->next) {
- while (tail) {
- if (last) {
- last->next = tail->next;
- } else {
- current->m = tail->next;
- }
- return MOD_ERR_OK;
- }
- } else {
- msgTable[index] = current->next;
- delete [] current->name;
- return MOD_ERR_OK;
- }
- } else {
- tail = current->m;
- if (tail->next) {
- while (tail) {
- if (last) {
- last->next = tail->next;
- } else {
- current->m = tail->next;
- }
- return MOD_ERR_OK;
- }
- } else {
- lastHash->next = current->next;
- delete [] current->name;
- return MOD_ERR_OK;
- }
- }
- }
- lastHash = current;
- }
- return MOD_ERR_NOEXIST;
-}
-
-/**
- * Destory a message, freeing its memory.
- * @param m the message to be destroyed
- * @return MOD_ERR_SUCCESS on success
- **/
-int destroyMessage(Message * m)
-{
- if (!m) {
- return MOD_ERR_PARAMS;
- }
- if (m->name) {
- delete [] m->name;
- }
- m->func = NULL;
- m->next = NULL;
- return MOD_ERR_OK;
-}
-
-/*******************************************************************************
- * Module Callback Functions
- *******************************************************************************/
-
- /* Check the current version of anope against a given version number
- * Specifiying -1 for minor,patch or build
- * @param major The major version of anope, the first part of the verison number
- * @param minor The minor version of anope, the second part of the version number
- * @param patch The patch version of anope, the third part of the version number
- * @param build The build revision of anope from SVN
- * @return True if the version newer than the version specified.
- **/
-bool moduleMinVersion(int major, int minor, int patch, int build)
-{
- bool ret = false;
- if (VERSION_MAJOR > major) { /* Def. new */
- ret = true;
- } else if (VERSION_MAJOR == major) { /* Might be newer */
- if (minor == -1) {
- return true;
- } /* They dont care about minor */
- if (VERSION_MINOR > minor) { /* Def. newer */
- ret = true;
- } else if (VERSION_MINOR == minor) { /* Might be newer */
- if (patch == -1) {
- return true;
- } /* They dont care about patch */
- if (VERSION_PATCH > patch) {
- ret = true;
- } else if (VERSION_PATCH == patch) {
-#if 0
-// XXX
- if (build == -1) {
- return true;
- } /* They dont care about build */
- if (VERSION_BUILD >= build) {
- ret = true;
- }
-#endif
- }
- }
- }
- return ret;
-}
-
-void Module::NoticeLang(const char *source, User * u, int number, ...)
-{
- va_list va;
- char buffer[4096], outbuf[4096];
- char *fmt = NULL;
- int mlang = Config.NSDefLanguage;
- char *s, *t, *buf;
-
- /* Find the users lang, and use it if we can */
- if (u && u->Account()) {
- mlang = u->Account()->language;
- }
-
- /* If the users lang isnt supported, drop back to English */
- if (this->lang[mlang].argc == 0)
- {
- mlang = LANG_EN_US;
- }
-
- /* If the requested lang string exists for the language */
- if (this->lang[mlang].argc > number) {
- fmt = this->lang[mlang].argv[number];
-
- buf = sstrdup(fmt);
- va_start(va, number);
- vsnprintf(buffer, 4095, buf, va);
- va_end(va);
- s = buffer;
- while (*s) {
- t = s;
- s += strcspn(s, "\n");
- if (*s)
- *s++ = '\0';
- strscpy(outbuf, t, sizeof(outbuf));
- u->SendMessage(source, "%s", outbuf);
- }
- delete [] buf;
- } else {
- Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]";
- }
-}
-
-const char *Module::GetLangString(User * u, int number)
-{
- int mlang = Config.NSDefLanguage;
-
- /* Find the users lang, and use it if we can */
- if (u && u->Account())
- mlang = u->Account()->language;
-
- /* If the users lang isnt supported, drop back to English */
- if (this->lang[mlang].argc == 0)
- mlang = LANG_EN_US;
-
- /* If the requested lang string exists for the language */
- if (this->lang[mlang].argc > number) {
- return this->lang[mlang].argv[number];
- /* Return an empty string otherwise, because we might be used without
- * the return value being checked. If we would return NULL, bad things
- * would happen!
- */
- } else {
- Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]";
- return "";
- }
-}
-
-void Module::DeleteLanguage(int langNumber)
-{
- if (this->lang[langNumber].argc)
- {
- for (int idx = 0; idx > this->lang[langNumber].argc; idx++)
- delete [] this->lang[langNumber].argv[idx];
- delete [] this->lang[langNumber].argv;
- this->lang[langNumber].argc = 0;
- }
-}
-
-void ModuleRunTimeDirCleanUp()
-{
-#ifndef _WIN32
- DIR *dirp;
- struct dirent *dp;
-#else
- BOOL fFinished;
- HANDLE hList;
- TCHAR szDir[MAX_PATH + 1];
- WIN32_FIND_DATA FileData;
- char buffer[_MAX_PATH];
-#endif
- char dirbuf[BUFSIZE];
- char filebuf[BUFSIZE];
-
- snprintf(dirbuf, BUFSIZE, "%s/modules/runtime", services_dir.c_str());
-
- Alog(LOG_DEBUG) << "Cleaning out Module run time directory (" << dirbuf << ") - this may take a moment please wait";
-
-
-#ifndef _WIN32
- if ((dirp = opendir(dirbuf)) == NULL)
- {
- Alog(LOG_DEBUG) << "cannot open directory (" << dirbuf << ")";
- return;
- }
- while ((dp = readdir(dirp)) != NULL) {
- if (dp->d_ino == 0) {
- continue;
- }
- if (!stricmp(dp->d_name, ".") || !stricmp(dp->d_name, "..")) {
- continue;
- }
- snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, dp->d_name);
- unlink(filebuf);
- }
- closedir(dirp);
-#else
- /* Get the current working directory: */
- if (_getcwd(buffer, _MAX_PATH) == NULL)
- {
- Alog(LOG_DEBUG) << "Unable to set Current working directory";
- }
- snprintf(szDir, sizeof(szDir), "%s\\%s\\*", buffer, dirbuf);
-
- hList = FindFirstFile(szDir, &FileData);
- if (hList != INVALID_HANDLE_VALUE) {
- fFinished = FALSE;
- while (!fFinished) {
- if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, FileData.cFileName);
- DeleteFile(filebuf);
- }
- if (!FindNextFile(hList, &FileData)) {
- if (GetLastError() == ERROR_NO_MORE_FILES) {
- fFinished = TRUE;
- }
- }
- }
- } else {
- Alog(LOG_DEBUG) << "Invalid File Handle. GetLastError() reports "<< static_cast<int>(GetLastError());
- }
- FindClose(hList);
-#endif
- Alog(LOG_DEBUG) << "Module run time directory has been cleaned out";
-}
-
-/* EOF */