diff options
Diffstat (limited to 'src/modules.c')
-rw-r--r-- | src/modules.c | 784 |
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 */ |