diff options
author | rob rob@31f1291d-b8d6-0310-a050-a5561fc1590b <rob rob@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2005-05-02 19:02:12 +0000 |
---|---|---|
committer | rob rob@31f1291d-b8d6-0310-a050-a5561fc1590b <rob rob@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2005-05-02 19:02:12 +0000 |
commit | e0583918834a3f8683e430adf3923ea89d2a449a (patch) | |
tree | ff36ada734c3874d3be1a806e3a2b994386b54ed /src/modules.c | |
parent | 49491770383e66f1b8074d8b0f80026e3086e9d8 (diff) |
BUILD : 1.7.8 (753) BUGS : N/a NOTES : Merged anope-dev with trunk
git-svn-id: svn://svn.anope.org/anope/trunk@753 31f1291d-b8d6-0310-a050-a5561fc1590b
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@516 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src/modules.c')
-rw-r--r-- | src/modules.c | 431 |
1 files changed, 369 insertions, 62 deletions
diff --git a/src/modules.c b/src/modules.c index 3d6150a4e..a508cda7e 100644 --- a/src/modules.c +++ b/src/modules.c @@ -86,6 +86,52 @@ void modules_init(void) #endif } +/** + * Load up a list of core modules from the conf. + * @param number The number of modules to load + * @param list The list of modules to load + **/ +void modules_core_init(int number, char **list) +{ + int idx; + Module *m; + int status = 0; + for (idx = 0; idx < number; idx++) { + m = findModule(list[idx]); + if (!m) { + m = createModule(list[idx]); + mod_current_module = m; + mod_current_user = NULL; + status = loadModule(mod_current_module, NULL); + if (debug || status) { + alog("trying to load core module [%s]", + mod_current_module->name); + alog("status: [%d]", status); + } + mod_current_module = NULL; + mod_current_user = NULL; + } + } +} + +/** + * Load the ircd protocol module up + **/ +int protocol_module_init(void) +{ + int ret = 0; + Module *m; + m = createModule(IRCDModule); + mod_current_module = m; + mod_current_user = NULL; + alog("Loading IRCD Protocol Module: [%s]", mod_current_module->name); + ret = loadModule(mod_current_module, NULL); + moduleSetType(PROTOCOL); + alog("status: [%d]", ret); + mod_current_module = NULL; + return ret; +} + /** * Automaticaly load modules at startup, delayed. * This function waits until the IRCD link has been made, and then attempts @@ -119,12 +165,14 @@ void modules_delayed_init(void) Module *createModule(char *filename) { Module *m; + int i = 0; if (!filename) { return NULL; } if ((m = malloc(sizeof(Module))) == NULL) { fatal("Out of memory!"); } + m->name = sstrdup(filename); /* Our Name */ m->handle = NULL; /* Handle */ m->version = NULL; @@ -137,6 +185,10 @@ Module *createModule(char *filename) m->hostHelp = NULL; m->helpHelp = NULL; + m->type = THIRD; + for (i = 0; i < NUM_LANGS; i++) { + m->lang[i].argc = 0; + } return m; /* return a nice new module */ } @@ -148,9 +200,16 @@ Module *createModule(char *filename) */ int destroyModule(Module * m) { + int i = 0; if (!m) { return MOD_ERR_PARAMS; } + + mod_current_module = m; + for (i = 0; i < NUM_LANGS; i++) { + moduleDeleteLanguage(i); + } + if (m->name) { free(m->name); } @@ -165,6 +224,7 @@ int destroyModule(Module * m) if (m->version) { free(m->version); } + /* No need to free our cmd/msg list, as they will always be empty by the module is destroyed */ free(m); return MOD_ERR_OK; @@ -262,6 +322,25 @@ Module *findModule(char *name) } +/** + * Search all loaded modules looking for a protocol module. + * @return 1 if one is found. + **/ +int protocolModuleLoaded() +{ + int idx = 0; + ModuleHash *current = NULL; + + for (idx = 0; idx != MAX_CMD_HASH; idx++) { + for (current = MODULE_HASH[idx]; current; current = current->next) { + if (current->m->type == PROTOCOL) { + return 1; + } + } + } + return 0; +} + /** * Copy the module from the modules folder to the runtime folder. * This will prevent module updates while the modules is loaded from @@ -375,7 +454,11 @@ int loadModule(Module * m, User * u) ano_modclearerr(); func = ano_modsym(m->handle, "AnopeInit"); if ((err = ano_moderr()) != NULL) { - ano_modclose(m->handle); /* If no AnopeInit - it isnt an Anope Module, close it */ + ano_modclose(m->handle); /* If no AnopeInit - it isnt an Anope Module, close it */ + if (u) { + notice_lang(s_OperServ, u, OPER_MODULE_LOAD_FAIL, m->name); + } + return MOD_ERR_NOLOAD; } if (func) { @@ -392,7 +475,14 @@ int loadModule(Module * m, User * u) if (u) { free(argv[0]); } + if (m->type == PROTOCOL && protocolModuleLoaded()) { + alog("You cannot load have 2 protocol modules."); + ret = MOD_STOP; + } if (ret == MOD_STOP) { + if (u) { + notice_lang(s_OperServ, u, OPER_MODULE_LOAD_FAIL, m->name); + } alog("%s requested unload...", m->name); unloadModule(m, NULL); mod_current_module_name = NULL; @@ -411,6 +501,10 @@ int loadModule(Module * m, User * u) return MOD_ERR_OK; #else + if (u) { + notice_lang(s_OperServ, u, OPER_MODULE_LOAD_FAIL, m->name); + } + return MOD_ERR_NOLOAD; #endif } @@ -433,6 +527,13 @@ int unloadModule(Module * m, User * u) return MOD_ERR_PARAMS; } + if (m->type == PROTOCOL) { + if (u) { + notice_lang(s_OperServ, u, OPER_MODULE_NO_UNLOAD); + } + return MOD_ERR_NOUNLOAD; + } + if (prepForUnload(mod_current_module) != MOD_ERR_OK) { return MOD_ERR_UNKNOWN; } @@ -463,6 +564,18 @@ int unloadModule(Module * m, User * u) } /** + * Module setType() + * Lets the module set a type, CORE,PROTOCOL,3RD etc.. + **/ +void moduleSetType(MODType type) +{ + if ((mod_current_module_name) && (!mod_current_module)) { + mod_current_module = findModule(mod_current_module_name); + } + mod_current_module->type = type; +} + +/** * Prepare a module to be unloaded. * Remove all commands and messages this module is providing, and delete * any callbacks which are still pending. @@ -474,8 +587,14 @@ int prepForUnload(Module * m) int idx; CommandHash *current = NULL; MessageHash *mcurrent = NULL; + EvtMessageHash *ecurrent = NULL; + EvtHookHash *ehcurrent = NULL; + Command *c; Message *msg; + EvtMessage *eMsg; + EvtHook *eHook; + int status = 0; if (!m) { return MOD_ERR_PARAMS; @@ -555,6 +674,25 @@ int prepForUnload(Module * m) } } } + + for (ecurrent = EVENT[idx]; ecurrent; ecurrent = ecurrent->next) { + for (eMsg = ecurrent->evm; eMsg; eMsg = eMsg->next) { + if ((eMsg->mod_name) + && (stricmp(eMsg->mod_name, m->name) == 0)) { + status = delEventHandler(EVENT, eMsg, m->name); + } + } + } + for (ehcurrent = EVENTHOOKS[idx]; ehcurrent; + ehcurrent = ehcurrent->next) { + for (eHook = ehcurrent->evh; eHook; eHook = eHook->next) { + if ((eHook->mod_name) + && (stricmp(eHook->mod_name, m->name) == 0)) { + status = delEventHook(EVENTHOOKS, eHook, m->name); + } + } + } + } return MOD_ERR_OK; } @@ -906,7 +1044,7 @@ int addCommand(CommandHash * cmdTable[], Command * c, int pos) if (!cmdTable || !c || (pos < 0 || pos > 2)) { return MOD_ERR_PARAMS; } - + if (mod_current_module_name && !c->mod_name) return MOD_ERR_NO_MOD_NAME; @@ -1131,6 +1269,7 @@ int addMessage(MessageHash * msgTable[], Message * m, int pos) MessageHash *newHash = NULL; MessageHash *lastHash = NULL; Message *tail = NULL; + int match = 0; if (!msgTable || !m || (pos < 0 || pos > 2)) { return MOD_ERR_PARAMS; @@ -1139,7 +1278,12 @@ int addMessage(MessageHash * msgTable[], Message * m, int pos) index = CMD_HASH(m->name); for (current = msgTable[index]; current; current = current->next) { - if (stricmp(m->name, current->name) == 0) { /* the msg exist's we are a addHead */ + if ((UseTokens) && (!ircd->tokencaseless)) { + match = strcmp(m->name, current->name); + } else { + 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; @@ -1754,54 +1898,34 @@ void moduleDisplayHelp(int service, User * u) int idx; int header_shown = 0; ModuleHash *current = NULL; + Module *calling_module = mod_current_module; + char *calling_module_name = mod_current_module_name; for (idx = 0; idx != MAX_CMD_HASH; idx++) { for (current = MODULE_HASH[idx]; current; current = current->next) { + mod_current_module_name = current->name; + mod_current_module = current->m; + if ((service == 1) && current->m->nickHelp) { - if (header_shown == 0) { - notice_lang(s_NickServ, u, MODULE_HELP_HEADER); - header_shown = 1; - } current->m->nickHelp(u); } else if ((service == 2) && current->m->chanHelp) { - if (header_shown == 0) { - notice_lang(s_ChanServ, u, MODULE_HELP_HEADER); - header_shown = 1; - } current->m->chanHelp(u); } else if ((service == 3) && current->m->memoHelp) { - if (header_shown == 0) { - notice_lang(s_MemoServ, u, MODULE_HELP_HEADER); - header_shown = 1; - } current->m->memoHelp(u); } else if ((service == 4) && current->m->botHelp) { - if (header_shown == 0) { - notice_lang(s_BotServ, u, MODULE_HELP_HEADER); - header_shown = 1; - } current->m->botHelp(u); } else if ((service == 5) && current->m->operHelp) { - if (header_shown == 0) { - notice_lang(s_OperServ, u, MODULE_HELP_HEADER); - header_shown = 1; - } current->m->operHelp(u); } else if ((service == 6) && current->m->hostHelp) { - if (header_shown == 0) { - notice_lang(s_HostServ, u, MODULE_HELP_HEADER); - header_shown = 1; - } current->m->hostHelp(u); } else if ((service == 7) && current->m->helpHelp) { - if (header_shown == 0) { - notice_lang(s_HelpServ, u, MODULE_HELP_HEADER); - header_shown = 1; - } current->m->helpHelp(u); } } } + + mod_current_module = calling_module; + mod_current_module_name = calling_module_name; #endif } @@ -1847,7 +1971,7 @@ int moduleAddData(ModuleData ** md, char *key, char *value) free(mod_name); return MOD_ERR_PARAMS; } - + if (mod_current_module_name == NULL) { alog("moduleAddData() called with mod_current_module_name being NULL"); if (debug) @@ -1901,8 +2025,9 @@ char *moduleGetData(ModuleData ** md, char *key) } while (current) { - if ((stricmp(current->moduleName, mod_name) == 0) && (stricmp(current->key, key) == 0)) { - free(mod_name); + if ((stricmp(current->moduleName, mod_name) == 0) + && (stricmp(current->key, key) == 0)) { + free(mod_name); return sstrdup(current->value); } current = current->next; @@ -1934,7 +2059,8 @@ void moduleDelData(ModuleData ** md, char *key) if (key) { while (current) { next = current->next; - if ((stricmp(current->moduleName, mod_name) == 0) && (stricmp(current->key, key) == 0)) { + if ((stricmp(current->moduleName, mod_name) == 0) + && (stricmp(current->key, key) == 0)) { if (prev) { prev->next = current->next; } else { @@ -2127,35 +2253,216 @@ const char *ano_moderr(void) /** * Allow ircd protocol files to update the protect level info tables. **/ -void updateProtectDetails(char *level_info_protect_word, char *level_info_protectme_word, char *fant_protect_add, char *fant_protect_del, char *level_protect_word, char *protect_set_mode, char *protect_unset_mode) { - int i = 0; - CSModeUtil ptr; - LevelInfo l_ptr; - - ptr = csmodeutils[i]; - while(ptr.name) { - if(strcmp(ptr.name,"PROTECT")==0) { - csmodeutils[i].bsname = sstrdup(fant_protect_add); - csmodeutils[i].mode = sstrdup(protect_set_mode); - } else if(strcmp(ptr.name,"DEPROTECT")==0) { - csmodeutils[i].bsname = sstrdup(fant_protect_del); - csmodeutils[i].mode = sstrdup(protect_unset_mode); - } - ptr = csmodeutils[++i]; - } - - i = 0; - l_ptr = levelinfo[i]; - while(l_ptr.what != -1) { - if(l_ptr.what == CA_PROTECT) { - levelinfo[i].name = sstrdup(level_info_protect_word); - } else if(l_ptr.what == CA_PROTECTME) { - levelinfo[i].name = sstrdup(level_info_protectme_word); - } else if(l_ptr.what == CA_AUTOPROTECT) { - levelinfo[i].name = sstrdup(level_protect_word); +void updateProtectDetails(char *level_info_protect_word, + char *level_info_protectme_word, + char *fant_protect_add, char *fant_protect_del, + char *level_protect_word, char *protect_set_mode, + char *protect_unset_mode) +{ + int i = 0; + CSModeUtil ptr; + LevelInfo l_ptr; + + ptr = csmodeutils[i]; + while (ptr.name) { + if (strcmp(ptr.name, "PROTECT") == 0) { + csmodeutils[i].bsname = sstrdup(fant_protect_add); + csmodeutils[i].mode = sstrdup(protect_set_mode); + } else if (strcmp(ptr.name, "DEPROTECT") == 0) { + csmodeutils[i].bsname = sstrdup(fant_protect_del); + csmodeutils[i].mode = sstrdup(protect_unset_mode); + } + ptr = csmodeutils[++i]; + } + + i = 0; + l_ptr = levelinfo[i]; + while (l_ptr.what != -1) { + if (l_ptr.what == CA_PROTECT) { + levelinfo[i].name = sstrdup(level_info_protect_word); + } else if (l_ptr.what == CA_PROTECTME) { + levelinfo[i].name = sstrdup(level_info_protectme_word); + } else if (l_ptr.what == CA_AUTOPROTECT) { + levelinfo[i].name = sstrdup(level_protect_word); + } + l_ptr = levelinfo[++i]; + } +} + +/** + * Deal with modules who want to lookup config directives! + * @param h The Directive to lookup in the config file + * @return 1 on success, 0 on error + **/ +int moduleGetConfigDirective(Directive * d) +{ + FILE *config; + char *dir; + char buf[1024]; + int linenum = 0; + int i; + int optind = 0; + int ac = 0; + char *av[MAXPARAMS]; + char *s, *t; + int retval; + + config = fopen(SERVICES_CONF, "r"); + if (!config) { + alog("Can't open %s", SERVICES_CONF); + return 0; + } + while (fgets(buf, sizeof(buf), config)) { + linenum++; + if (*buf == '#' || *buf == '\r' || *buf == '\n') + continue; + + dir = myStrGetOnlyToken(buf, '\t', 0); + if (dir) { + s = myStrGetTokenRemainder(buf, '\t', 1); + } else { + dir = myStrGetOnlyToken(buf, ' ', 0); + if (dir) { + s = myStrGetTokenRemainder(buf, ' ', 1); + } else { + continue; + } + } + + if (stricmp(dir, d->name) == 0) { + if (s) { + while (isspace(*s)) + s++; + while (*s) { + if (ac >= MAXPARAMS) { + alog("module error: too many config. params"); + break; + } + t = s; + if (*s == '"') { + t++; + s++; + while (*s && *s != '"') { + if (*s == '\\' && s[1] != 0) + s++; + s++; + } + if (!*s) + alog("module error: Warning: unterminated double-quoted string"); + else + *s++ = 0; + } else { + s += strcspn(s, " \t\r\n"); + if (*s) + *s++ = 0; + } + av[ac++] = t; + while (isspace(*s)) + s++; } - l_ptr = levelinfo[++i]; + } + retval = parse_directive(d, dir, ac, av, linenum, 0, s); + } + } + fclose(config); + return retval; +} + +/** + * Allow a module to add a set of language strings to anope + * @param langNumber the language number for the strings + * @param ac The language count for the strings + * @param av The language sring list. + **/ +void moduleInsertLanguage(int langNumber, int ac, char **av) +{ + int i; + + if ((mod_current_module_name) && (!mod_current_module)) { + mod_current_module = findModule(mod_current_module_name); + } + + if (debug) + alog("debug: %s Adding %d texts for language %d", mod_current_module->name, ac, langNumber); + + if (mod_current_module->lang[langNumber].argc > 0) { + moduleDeleteLanguage(langNumber); + } + + mod_current_module->lang[langNumber].argc = ac; + mod_current_module->lang[langNumber].argv = + malloc(sizeof(char *) * ac); + for (i = 0; i < ac; i++) { + mod_current_module->lang[langNumber].argv[i] = sstrdup(av[i]); + } +} + +/** + * Send a notice to the user in the correct language, or english. + * @param source Who sends the notice + * @param u The user to send the message to + * @param number The message number + * @param ... The argument list + **/ +void moduleNoticeLang(char *source, User * u, int number, ...) +{ + va_list va; + char buffer[4096], outbuf[4096]; + char *fmt = NULL; + int lang = LANG_EN_US; + char *s, *t, *buf; + + if ((mod_current_module_name) && (!mod_current_module)) { + mod_current_module = findModule(mod_current_module_name); + } + /* Find the users lang, and use it if we cant */ + if (u->na && u->na->nc) { + lang = u->na->nc->language; + } + + /* If the users lang isnt supported, drop back to enlgish */ + if (mod_current_module->lang[lang].argc == 0) { + lang = LANG_EN_US; + } + + /* If the requested lang string exists for the language */ + if (mod_current_module->lang[lang].argc > number) { + fmt = mod_current_module->lang[lang].argv[number]; + + buf = sstrdup(fmt); + s = buf; + while (*s) { + t = s; + s += strcspn(s, "\n"); + if (*s) + *s++ = '\0'; + strscpy(outbuf, t, sizeof(outbuf)); + + va_start(va, number); + vsnprintf(buffer, 4095, outbuf, va); + va_end(va); + notice(source, u->nick, buffer); } + free(buf); + } else { + alog("%s: INVALID language string call, language: [%d], String [%d]", mod_current_module->name, lang, number); + } +} + +/** + * Delete a language from a module + * @param langNumber the language Number to delete + **/ +void moduleDeleteLanguage(int langNumber) +{ + int idx = 0; + if ((mod_current_module_name) && (!mod_current_module)) { + mod_current_module = findModule(mod_current_module_name); + } + for (idx = 0; idx > mod_current_module->lang[langNumber].argc; idx++) { + free(mod_current_module->lang[langNumber].argv[idx]); + } + mod_current_module->lang[langNumber].argc = 0; } /* EOF */ |