00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "modules.h"
00016 #include "language.h"
00017 #include "version.h"
00018
00019 #if defined(USE_MODULES) && !defined(_WIN32)
00020 #include <dlfcn.h>
00021
00022 #ifndef RTLD_NOW
00023 #define RTLD_NOW 0
00024 #endif
00025 #ifndef RTLD_LAZY
00026 #define RTLD_LAZY RTLD_NOW
00027 #endif
00028 #ifndef RTLD_GLOBAL
00029 #define RTLD_GLOBAL 0
00030 #endif
00031 #ifndef RTLD_LOCAL
00032 #define RTLD_LOCAL 0
00033 #endif
00034 #endif
00035
00036 #ifdef _WIN32
00037 const char *ano_moderr(void);
00038 #endif
00039
00043 CommandHash *HOSTSERV[MAX_CMD_HASH];
00044 CommandHash *BOTSERV[MAX_CMD_HASH];
00045 CommandHash *MEMOSERV[MAX_CMD_HASH];
00046 CommandHash *NICKSERV[MAX_CMD_HASH];
00047 CommandHash *CHANSERV[MAX_CMD_HASH];
00048 CommandHash *HELPSERV[MAX_CMD_HASH];
00049 CommandHash *OPERSERV[MAX_CMD_HASH];
00050 MessageHash *IRCD[MAX_CMD_HASH];
00051 ModuleHash *MODULE_HASH[MAX_CMD_HASH];
00052
00053 Module *mod_current_module;
00054 char *mod_current_module_name = NULL;
00055 char *mod_current_buffer = NULL;
00056 User *mod_current_user;
00057 ModuleCallBack *moduleCallBackHead = NULL;
00058 ModuleQueue *mod_operation_queue = NULL;
00059
00060 int displayCommand(Command * c);
00061 int displayCommandFromHash(CommandHash * cmdTable[], char *name);
00062 int displayMessageFromHash(char *name);
00063 int displayMessage(Message * m);
00064 char *ModuleGetErrStr(int status);
00065
00066 char *ModuleGetErrStr(int status)
00067 {
00068 const char *module_err_str[] = {
00069 "Module, Okay - No Error",
00070 "Module Error, Allocating memory",
00071 "Module Error, Not enough parameters",
00072 "Module Error, Already loaded",
00073 "Module Error, File does not exist",
00074 "Module Error, No User",
00075 "Module Error, Error during load time or module returned MOD_STOP",
00076 "Module Error, Unable to unload",
00077 "Module Error, Incorrect syntax",
00078 "Module Error, Unable to delete",
00079 "Module Error, Unknown Error occuried",
00080 "Module Error, File I/O Error",
00081 "Module Error, No Service found for request",
00082 "Module Error, No module name for request"
00083 };
00084 return (char *) module_err_str[status];
00085 }
00086
00092 void modules_init(void)
00093 {
00094 #ifdef USE_MODULES
00095 int idx;
00096 int ret;
00097 Module *m;
00098
00099 if(nothird) {
00100 return;
00101 }
00102
00103 for (idx = 0; idx < ModulesNumber; idx++) {
00104 m = findModule(ModulesAutoload[idx]);
00105 if (!m) {
00106 m = createModule(ModulesAutoload[idx]);
00107 mod_current_module = m;
00108 mod_current_user = NULL;
00109 alog("trying to load [%s]", mod_current_module->name);
00110 ret = loadModule(mod_current_module, NULL);
00111 alog("status: [%d][%s]", ret, ModuleGetErrStr(ret));
00112 if (ret != MOD_ERR_OK)
00113 destroyModule(m);
00114 mod_current_module = NULL;
00115 mod_current_user = NULL;
00116 }
00117 }
00118 #endif
00119 }
00120
00126 void modules_core_init(int number, char **list)
00127 {
00128 int idx;
00129 Module *m;
00130 int status = 0;
00131 for (idx = 0; idx < number; idx++) {
00132 m = findModule(list[idx]);
00133 if (!m) {
00134 m = createModule(list[idx]);
00135 mod_current_module = m;
00136 mod_current_user = NULL;
00137 status = loadModule(mod_current_module, NULL);
00138 if (debug || status) {
00139 alog("debug: trying to load core module [%s]",
00140 mod_current_module->name);
00141 alog("debug: status: [%d][%s]", status, ModuleGetErrStr(status));
00142 if (status != MOD_ERR_OK)
00143 destroyModule(mod_current_module);
00144 }
00145 mod_current_module = NULL;
00146 mod_current_user = NULL;
00147 }
00148 }
00149 }
00153 int encryption_module_init(void) {
00154 int ret = 0;
00155 Module *m;
00156
00157 m = createModule(EncModule);
00158 mod_current_module = m;
00159 mod_current_user = NULL;
00160 alog("Loading Encryption Module: [%s]", mod_current_module->name);
00161 ret = loadModule(mod_current_module, NULL);
00162 moduleSetType(ENCRYPTION);
00163 alog("status: [%d][%s]", ret, ModuleGetErrStr(ret));
00164 mod_current_module = NULL;
00165 if (ret != MOD_ERR_OK) {
00166 destroyModule(m);
00167 }
00168 return ret;
00169 }
00170
00174 int protocol_module_init(void)
00175 {
00176 int ret = 0;
00177 Module *m;
00178
00179 m = createModule(IRCDModule);
00180 mod_current_module = m;
00181 mod_current_user = NULL;
00182 alog("Loading IRCD Protocol Module: [%s]", mod_current_module->name);
00183 ret = loadModule(mod_current_module, NULL);
00184 moduleSetType(PROTOCOL);
00185 alog("status: [%d][%s]", ret, ModuleGetErrStr(ret));
00186 mod_current_module = NULL;
00187
00188 if (ret == MOD_ERR_OK) {
00189
00190
00191
00192
00193 if (UseTokens && !(ircd->token)) {
00194 alog("Anope does not support TOKENS for this ircd setting; unsetting UseToken");
00195 UseTokens = 0;
00196 }
00197
00198 if (UseTS6 && !(ircd->ts6)) {
00199 alog("Chosen IRCd does not support TS6, unsetting UseTS6");
00200 UseTS6 = 0;
00201 }
00202
00203
00204 if (UseTS6 && !Numeric) {
00205 alog("UseTS6 requires the setting of Numeric to be enabled.");
00206 ret = -1;
00207 }
00208 } else {
00209 destroyModule(m);
00210 }
00211
00212 return ret;
00213 }
00214
00220 void modules_delayed_init(void)
00221 {
00222 #ifdef USE_MODULES
00223 int idx;
00224 int ret;
00225 Module *m;
00226
00227 if(nothird) {
00228 return;
00229 }
00230
00231 for (idx = 0; idx < ModulesDelayedNumber; idx++) {
00232 m = findModule(ModulesDelayedAutoload[idx]);
00233 if (!m) {
00234 m = createModule(ModulesDelayedAutoload[idx]);
00235 mod_current_module = m;
00236 mod_current_user = NULL;
00237 alog("trying to load [%s]", mod_current_module->name);
00238 ret = loadModule(mod_current_module, NULL);
00239 alog("status: [%d][%s]", ret, ModuleGetErrStr(ret));
00240 mod_current_module = NULL;
00241 mod_current_user = NULL;
00242 if (ret != MOD_ERR_OK)
00243 destroyModule(m);
00244 }
00245 }
00246 #endif
00247 }
00248
00259 void modules_unload_all(boolean fini, boolean unload_proto)
00260 {
00261 #ifdef USE_MODULES
00262 int idx;
00263 ModuleHash *mh, *next;
00264 void (*func) (void);
00265
00266 for (idx = 0; idx < MAX_CMD_HASH; idx++) {
00267 mh = MODULE_HASH[idx];
00268 while (mh) {
00269 next = mh->next;
00270 if (unload_proto || (mh->m->type != PROTOCOL)) {
00271 mod_current_module = mh->m;
00272 if(fini) {
00273 func = (void (*)(void))ano_modsym(mh->m->handle, "AnopeFini");
00274 if (func) {
00275 mod_current_module_name = mh->m->name;
00276 func();
00277 mod_current_module_name = NULL;
00278 }
00279
00280 if (prepForUnload(mh->m) != MOD_ERR_OK) {
00281 mh = next;
00282 continue;
00283 }
00284
00285 if ((ano_modclose(mh->m->handle)) != 0)
00286 alog(ano_moderr());
00287 else
00288 delModule(mh->m);
00289 } else {
00290 delModule(mh->m);
00291 }
00292 }
00293 mh = next;
00294 }
00295 }
00296 #endif
00297 }
00298
00304 Module *createModule(char *filename)
00305 {
00306 Module *m;
00307 int i = 0;
00308 if (!filename) {
00309 return NULL;
00310 }
00311 if ((m = malloc(sizeof(Module))) == NULL) {
00312 fatal("Out of memory!");
00313 }
00314
00315 m->name = sstrdup(filename);
00316 m->handle = NULL;
00317 m->version = NULL;
00318 m->author = NULL;
00319 m->nickHelp = NULL;
00320 m->chanHelp = NULL;
00321 m->memoHelp = NULL;
00322 m->botHelp = NULL;
00323 m->operHelp = NULL;
00324 m->hostHelp = NULL;
00325 m->helpHelp = NULL;
00326
00327 m->type = THIRD;
00328 for (i = 0; i < NUM_LANGS; i++) {
00329 m->lang[i].argc = 0;
00330 }
00331 return m;
00332 }
00333
00340 int destroyModule(Module * m)
00341 {
00342 int i = 0;
00343 if (!m) {
00344 return MOD_ERR_PARAMS;
00345 }
00346
00347 mod_current_module = m;
00348 for (i = 0; i < NUM_LANGS; i++) {
00349 moduleDeleteLanguage(i);
00350 }
00351
00352 if (m->name) {
00353 free(m->name);
00354 }
00355 if (m->filename) {
00356 remove(m->filename);
00357 free(m->filename);
00358 }
00359 m->handle = NULL;
00360 if (m->author) {
00361 free(m->author);
00362 }
00363 if (m->version) {
00364 free(m->version);
00365 }
00366
00367
00368 free(m);
00369 return MOD_ERR_OK;
00370 }
00371
00377 int addModule(Module * m)
00378 {
00379 int index = 0;
00380 ModuleHash *current = NULL;
00381 ModuleHash *newHash = NULL;
00382 ModuleHash *lastHash = NULL;
00383
00384 index = CMD_HASH(m->name);
00385
00386 for (current = MODULE_HASH[index]; current; current = current->next) {
00387 if (stricmp(m->name, current->name) == 0)
00388 return MOD_ERR_EXISTS;
00389 lastHash = current;
00390 }
00391
00392 if ((newHash = malloc(sizeof(ModuleHash))) == NULL) {
00393 fatal("Out of memory");
00394 }
00395 m->time = time(NULL);
00396 newHash->next = NULL;
00397 newHash->name = sstrdup(m->name);
00398 newHash->m = m;
00399
00400 if (lastHash == NULL)
00401 MODULE_HASH[index] = newHash;
00402 else
00403 lastHash->next = newHash;
00404 return MOD_ERR_OK;
00405 }
00406
00412 int delModule(Module * m)
00413 {
00414 int index = 0;
00415 ModuleHash *current = NULL;
00416 ModuleHash *lastHash = NULL;
00417
00418 if (!m) {
00419 return MOD_ERR_PARAMS;
00420 }
00421
00422 index = CMD_HASH(m->name);
00423
00424 for (current = MODULE_HASH[index]; current; current = current->next) {
00425 if (stricmp(m->name, current->name) == 0) {
00426 if (!lastHash) {
00427 MODULE_HASH[index] = current->next;
00428 } else {
00429 lastHash->next = current->next;
00430 }
00431 destroyModule(current->m);
00432 free(current->name);
00433 free(current);
00434 return MOD_ERR_OK;
00435 }
00436 lastHash = current;
00437 }
00438 return MOD_ERR_NOEXIST;
00439 }
00440
00446 Module *findModule(char *name)
00447 {
00448 int idx;
00449 ModuleHash *current = NULL;
00450 if (!name) {
00451 return NULL;
00452 }
00453 idx = CMD_HASH(name);
00454
00455 for (current = MODULE_HASH[idx]; current; current = current->next) {
00456 if (stricmp(name, current->name) == 0) {
00457 return current->m;
00458 }
00459 }
00460 return NULL;
00461
00462 }
00463
00468 int protocolModuleLoaded()
00469 {
00470 int idx = 0;
00471 ModuleHash *current = NULL;
00472
00473 for (idx = 0; idx != MAX_CMD_HASH; idx++) {
00474 for (current = MODULE_HASH[idx]; current; current = current->next) {
00475 if (current->m->type == PROTOCOL) {
00476 return 1;
00477 }
00478 }
00479 }
00480 return 0;
00481 }
00482
00487 int encryptionModuleLoaded()
00488 {
00489 int idx = 0;
00490 ModuleHash *current = NULL;
00491
00492 for (idx = 0; idx != MAX_CMD_HASH; idx++) {
00493 for (current = MODULE_HASH[idx]; current; current = current->next) {
00494 if (current->m->type == ENCRYPTION) {
00495 return 1;
00496 }
00497 }
00498 }
00499 return 0;
00500 }
00501
00511 int moduleCopyFile(char *name, char *output)
00512 {
00513 #ifdef USE_MODULES
00514 int ch;
00515 FILE *source, *target;
00516 int srcfp;
00517 char input[4096];
00518 int len;
00519
00520 strncpy(input, MODULE_PATH, 4095);
00521 len = strlen(input);
00522 strncat(input, name, 4095 - len);
00523 len = strlen(output);
00524 strncat(input, MODULE_EXT, 4095 - len);
00525
00526 #ifndef _WIN32
00527 if ((srcfp = mkstemp(output)) == -1)
00528 return MOD_ERR_FILE_IO;
00529 #else
00530 if (!mktemp(output))
00531 return MOD_ERR_FILE_IO;
00532 #endif
00533
00534 if (debug)
00535 alog("Runtime module location: %s", output);
00536
00537
00538
00539
00540 #ifndef _WIN32
00541 if ((source = fopen(input, "r")) == NULL) {
00542 #else
00543 if ((source = fopen(input, "rb")) == NULL) {
00544 #endif
00545 return MOD_ERR_NOEXIST;
00546 }
00547 #ifndef _WIN32
00548 if ((target = fdopen(srcfp, "w")) == NULL) {
00549 #else
00550 if ((target = fopen(output, "wb")) == NULL) {
00551 #endif
00552 return MOD_ERR_FILE_IO;
00553 }
00554 while ((ch = fgetc(source)) != EOF) {
00555 fputc(ch, target);
00556 }
00557 fclose(source);
00558 if (fclose(target) != 0) {
00559 return MOD_ERR_FILE_IO;
00560 }
00561 #endif
00562 return MOD_ERR_OK;
00563 }
00564
00571 int loadModule(Module * m, User * u)
00572 {
00573 #ifdef USE_MODULES
00574 char buf[4096];
00575 int len;
00576 const char *err;
00577 int (*func) (int, char **);
00578 int (*version)();
00579 int ret = 0;
00580 char *argv[1];
00581 int argc = 0;
00582
00583 Module *m2;
00584 if (!m || !m->name) {
00585 return MOD_ERR_PARAMS;
00586 }
00587 if (m->handle) {
00588 return MOD_ERR_EXISTS;
00589 }
00590 if ((m2 = findModule(m->name)) != NULL) {
00591 return MOD_ERR_EXISTS;
00592 }
00593
00594
00595 strncpy(buf, MODULE_PATH, 4095);
00596 len = strlen(buf);
00597 #ifndef _WIN32
00598 strncat(buf, "runtime/", 4095 - len);
00599 #else
00600 strncat(buf, "runtime\\", 4095 - len);
00601 #endif
00602 len = strlen(buf);
00603 strncat(buf, m->name, 4095 - len);
00604 len = strlen(buf);
00605 strncat(buf, MODULE_EXT, 4095 - len);
00606 len = strlen(buf);
00607 strncat(buf, ".", 4095 - len);
00608 len = strlen(buf);
00609 strncat(buf, "XXXXXX", 4095 - len);
00610 buf[4095] = '\0';
00611
00612 if ((ret = moduleCopyFile(m->name, buf)) != MOD_ERR_OK) {
00613 m->filename = sstrdup(buf);
00614 return ret;
00615 }
00616
00617 m->filename = sstrdup(buf);
00618 ano_modclearerr();
00619 m->handle = ano_modopen(m->filename);
00620 if ((err = ano_moderr()) != NULL) {
00621 alog(err);
00622 return MOD_ERR_NOLOAD;
00623 }
00624 ano_modclearerr();
00625 func = (int (*)(int, char **))ano_modsym(m->handle, "AnopeInit");
00626 if ((err = ano_moderr()) != NULL) {
00627 ano_modclose(m->handle);
00628 return MOD_ERR_NOLOAD;
00629 }
00630 if (func) {
00631 version = (int (*)())ano_modsym(m->handle,"getAnopeBuildVersion");
00632 if (version) {
00633 if (version() >= VERSION_BUILD ) {
00634 if(debug) {
00635 alog("Module %s compiled against current or newer anope revision %d, this is %d",m->name,version(),VERSION_BUILD);
00636 }
00637 } else {
00638 alog("Module %s is compiled against an old version of anope (%d) current is %d", m->name, version(), VERSION_BUILD);
00639 alog("Rebuild module %s against the current version to resolve this error", m->name);
00640 ano_modclose(m->handle);
00641 ano_modclearerr();
00642 return MOD_ERR_NOLOAD;
00643 }
00644 } else {
00645 ano_modclose(m->handle);
00646 ano_modclearerr();
00647 alog("Module %s is compiled against an older version of anope (unknown)", m->name);
00648 alog("Rebuild module %s against the current version to resolve this error", m->name);
00649 return MOD_ERR_NOLOAD;
00650 }
00651
00652 mod_current_module_name = m->name;
00653
00654 if (u) {
00655 argv[0] = sstrdup(u->nick);
00656 } else {
00657 argv[0] = NULL;
00658 }
00659 argc++;
00660
00661 ret = func(argc, argv);
00662 if (u) {
00663 free(argv[0]);
00664 }
00665 if (m->type == PROTOCOL && protocolModuleLoaded()) {
00666 alog("You cannot load two protocol modules");
00667 ret = MOD_STOP;
00668 } else if (m->type == ENCRYPTION && encryptionModuleLoaded()) {
00669 alog("You cannot load two encryption modules");
00670 ret = MOD_STOP;
00671 }
00672 if (ret == MOD_STOP) {
00673 alog("%s requested unload...", m->name);
00674 unloadModule(m, NULL);
00675 mod_current_module_name = NULL;
00676 return MOD_ERR_NOLOAD;
00677 }
00678
00679 mod_current_module_name = NULL;
00680 }
00681
00682 if (u) {
00683 anope_cmd_global(s_OperServ, "%s loaded module %s", u->nick,
00684 m->name);
00685 notice_lang(s_OperServ, u, OPER_MODULE_LOADED, m->name);
00686 }
00687 addModule(m);
00688 return MOD_ERR_OK;
00689
00690 #else
00691 return MOD_ERR_NOLOAD;
00692 #endif
00693 }
00694
00701 int unloadModule(Module * m, User * u)
00702 {
00703 #ifdef USE_MODULES
00704 void (*func) (void);
00705
00706 if (!m || !m->handle) {
00707 if (u) {
00708 notice_lang(s_OperServ, u, OPER_MODULE_REMOVE_FAIL, m->name);
00709 }
00710 return MOD_ERR_PARAMS;
00711 }
00712
00713 if (m->type == PROTOCOL) {
00714 if (u) {
00715 notice_lang(s_OperServ, u, OPER_MODULE_NO_UNLOAD);
00716 }
00717 return MOD_ERR_NOUNLOAD;
00718 } else if(m->type == ENCRYPTION) {
00719 if (u) {
00720 notice_lang(s_OperServ, u, OPER_MODULE_NO_UNLOAD);
00721 }
00722 return MOD_ERR_NOUNLOAD;
00723 }
00724
00725 func = (void (*)(void))ano_modsym(m->handle, "AnopeFini");
00726 if (func) {
00727 mod_current_module_name = m->name;
00728 func();
00729 mod_current_module_name = NULL;
00730 }
00731
00732 if (prepForUnload(m) != MOD_ERR_OK) {
00733 return MOD_ERR_UNKNOWN;
00734 }
00735
00736 if ((ano_modclose(m->handle)) != 0) {
00737 alog(ano_moderr());
00738 if (u) {
00739 notice_lang(s_OperServ, u, OPER_MODULE_REMOVE_FAIL, m->name);
00740 }
00741 return MOD_ERR_NOUNLOAD;
00742 } else {
00743 if (u) {
00744 anope_cmd_global(s_OperServ, "%s unloaded module %s", u->nick,
00745 m->name);
00746 notice_lang(s_OperServ, u, OPER_MODULE_UNLOADED, m->name);
00747 }
00748 delModule(m);
00749 return MOD_ERR_OK;
00750 }
00751 #else
00752 return MOD_ERR_NOUNLOAD;
00753 #endif
00754 }
00755
00760 void moduleSetType(MODType type)
00761 {
00762 if ((mod_current_module_name) && (!mod_current_module)) {
00763 mod_current_module = findModule(mod_current_module_name);
00764 }
00765 mod_current_module->type = type;
00766 }
00767
00775 int prepForUnload(Module * m)
00776 {
00777 int idx;
00778 CommandHash *current = NULL;
00779 MessageHash *mcurrent = NULL;
00780 EvtMessageHash *ecurrent = NULL;
00781 EvtHookHash *ehcurrent = NULL;
00782
00783 Command *c;
00784 Message *msg;
00785 EvtMessage *eMsg;
00786 EvtHook *eHook;
00787 int status = 0;
00788
00789 if (!m) {
00790 return MOD_ERR_PARAMS;
00791 }
00792
00793
00794 moduleCallBackPrepForUnload(m->name);
00795
00796
00797 moduleDelAllDataMod(m);
00798
00802 for (idx = 0; idx < MAX_CMD_HASH; idx++) {
00803 for (current = HS_cmdTable[idx]; current; current = current->next) {
00804 for (c = current->c; c; c = c->next) {
00805 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00806 moduleDelCommand(HOSTSERV, c->name);
00807 }
00808 }
00809 }
00810
00811 for (current = BS_cmdTable[idx]; current; current = current->next) {
00812 for (c = current->c; c; c = c->next) {
00813 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00814 moduleDelCommand(BOTSERV, c->name);
00815 }
00816 }
00817 }
00818
00819 for (current = MS_cmdTable[idx]; current; current = current->next) {
00820 for (c = current->c; c; c = c->next) {
00821 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00822 moduleDelCommand(MEMOSERV, c->name);
00823 }
00824 }
00825 }
00826
00827 for (current = NS_cmdTable[idx]; current; current = current->next) {
00828 for (c = current->c; c; c = c->next) {
00829 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00830 moduleDelCommand(NICKSERV, c->name);
00831 }
00832 }
00833 }
00834
00835 for (current = CS_cmdTable[idx]; current; current = current->next) {
00836 for (c = current->c; c; c = c->next) {
00837 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00838 moduleDelCommand(CHANSERV, c->name);
00839 }
00840 }
00841 }
00842
00843 for (current = HE_cmdTable[idx]; current; current = current->next) {
00844 for (c = current->c; c; c = c->next) {
00845 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00846 moduleDelCommand(HELPSERV, c->name);
00847 }
00848 }
00849 }
00850
00851 for (current = OS_cmdTable[idx]; current; current = current->next) {
00852 for (c = current->c; c; c = c->next) {
00853 if ((c->mod_name) && (stricmp(c->mod_name, m->name) == 0)) {
00854 moduleDelCommand(OPERSERV, c->name);
00855 }
00856 }
00857 }
00858
00859 for (mcurrent = IRCD[idx]; mcurrent; mcurrent = mcurrent->next) {
00860 for (msg = mcurrent->m; msg; msg = msg->next) {
00861 if ((msg->mod_name)
00862 && (stricmp(msg->mod_name, m->name) == 0)) {
00863 moduleDelMessage(msg->name);
00864 }
00865 }
00866 }
00867
00868 for (ecurrent = EVENT[idx]; ecurrent; ecurrent = ecurrent->next) {
00869 for (eMsg = ecurrent->evm; eMsg; eMsg = eMsg->next) {
00870 if ((eMsg->mod_name)
00871 && (stricmp(eMsg->mod_name, m->name) == 0)) {
00872 status = delEventHandler(EVENT, eMsg, m->name);
00873 }
00874 }
00875 }
00876 for (ehcurrent = EVENTHOOKS[idx]; ehcurrent;
00877 ehcurrent = ehcurrent->next) {
00878 for (eHook = ehcurrent->evh; eHook; eHook = eHook->next) {
00879 if ((eHook->mod_name)
00880 && (stricmp(eHook->mod_name, m->name) == 0)) {
00881 status = delEventHook(EVENTHOOKS, eHook, m->name);
00882 }
00883 }
00884 }
00885
00886 }
00887 return MOD_ERR_OK;
00888 }
00889
00890
00891
00892
00905 Command *createCommand(const char *name, int (*func) (User * u),
00906 int (*has_priv) (User * u), int help_all,
00907 int help_reg, int help_oper, int help_admin,
00908 int help_root)
00909 {
00910 Command *c;
00911 if (!name || !*name) {
00912 return NULL;
00913 }
00914
00915 if ((c = malloc(sizeof(Command))) == NULL) {
00916 fatal("Out of memory!");
00917 }
00918 c->name = sstrdup(name);
00919 c->routine = func;
00920 c->has_priv = has_priv;
00921 c->helpmsg_all = help_all;
00922 c->helpmsg_reg = help_reg;
00923 c->helpmsg_oper = help_oper;
00924 c->helpmsg_admin = help_admin;
00925 c->helpmsg_root = help_root;
00926 c->help_param1 = NULL;
00927 c->help_param2 = NULL;
00928 c->help_param3 = NULL;
00929 c->help_param4 = NULL;
00930 c->next = NULL;
00931 c->mod_name = NULL;
00932 c->service = NULL;
00933 c->all_help = NULL;
00934 c->regular_help = NULL;
00935 c->oper_help = NULL;
00936 c->admin_help = NULL;
00937 c->root_help = NULL;
00938 return c;
00939 }
00940
00946 int destroyCommand(Command * c)
00947 {
00948 if (!c) {
00949 return MOD_ERR_PARAMS;
00950 }
00951 if (c->core == 1) {
00952 return MOD_ERR_UNKNOWN;
00953 }
00954 if (c->name) {
00955 free(c->name);
00956 }
00957 c->routine = NULL;
00958 c->has_priv = NULL;
00959 c->helpmsg_all = -1;
00960 c->helpmsg_reg = -1;
00961 c->helpmsg_oper = -1;
00962 c->helpmsg_admin = -1;
00963 c->helpmsg_root = -1;
00964 if (c->help_param1) {
00965 free(c->help_param1);
00966 }
00967 if (c->help_param2) {
00968 free(c->help_param2);
00969 }
00970 if (c->help_param3) {
00971 free(c->help_param3);
00972 }
00973 if (c->help_param4) {
00974 free(c->help_param4);
00975 }
00976 if (c->mod_name) {
00977 free(c->mod_name);
00978 }
00979 if (c->service) {
00980 free(c->service);
00981 }
00982 c->next = NULL;
00983 free(c);
00984 return MOD_ERR_OK;
00985 }
00986
00993 int addCoreCommand(CommandHash * cmdTable[], Command * c)
00994 {
00995 if (!cmdTable || !c) {
00996 return MOD_ERR_PARAMS;
00997 }
00998 c->core = 1;
00999 c->next = NULL;
01000 return addCommand(cmdTable, c, 0);
01001 }
01002
01012 int moduleAddCommand(CommandHash * cmdTable[], Command * c, int pos)
01013 {
01014 int status;
01015
01016 if (!cmdTable || !c) {
01017 return MOD_ERR_PARAMS;
01018 }
01019
01020 if ((mod_current_module_name) && (!mod_current_module)) {
01021 mod_current_module = findModule(mod_current_module_name);
01022 }
01023
01024 if (!mod_current_module) {
01025 return MOD_ERR_UNKNOWN;
01026 }
01027 c->core = 0;
01028 if (!c->mod_name) {
01029 c->mod_name = sstrdup(mod_current_module->name);
01030 }
01031
01032
01033 if (cmdTable == HOSTSERV) {
01034 if (s_HostServ) {
01035 c->service = sstrdup(s_HostServ);
01036 } else {
01037 return MOD_ERR_NOSERVICE;
01038 }
01039 } else if (cmdTable == BOTSERV) {
01040 if (s_BotServ) {
01041 c->service = sstrdup(s_BotServ);
01042 } else {
01043 return MOD_ERR_NOSERVICE;
01044 }
01045 } else if (cmdTable == MEMOSERV) {
01046 if (s_MemoServ) {
01047 c->service = sstrdup(s_MemoServ);
01048 } else {
01049 return MOD_ERR_NOSERVICE;
01050 }
01051 } else if (cmdTable == CHANSERV) {
01052 if (s_ChanServ) {
01053 c->service = sstrdup(s_ChanServ);
01054 } else {
01055 return MOD_ERR_NOSERVICE;
01056 }
01057 } else if (cmdTable == NICKSERV) {
01058 if (s_NickServ) {
01059 c->service = sstrdup(s_NickServ);
01060 } else {
01061 return MOD_ERR_NOSERVICE;
01062 }
01063 } else if (cmdTable == HELPSERV) {
01064 if (s_HelpServ) {
01065 c->service = sstrdup(s_HelpServ);
01066 } else {
01067 return MOD_ERR_NOSERVICE;
01068 }
01069 } else if (cmdTable == OPERSERV) {
01070 if (s_OperServ) {
01071 c->service = sstrdup(s_OperServ);
01072 } else {
01073 return MOD_ERR_NOSERVICE;
01074 }
01075 } else
01076 c->service = sstrdup("Unknown");
01077
01078 if (debug >= 2)
01079 displayCommandFromHash(cmdTable, c->name);
01080 status = addCommand(cmdTable, c, pos);
01081 if (debug >= 2)
01082 displayCommandFromHash(cmdTable, c->name);
01083 if (status != MOD_ERR_OK) {
01084 alog("ERROR! [%d]", status);
01085 }
01086 return status;
01087 }
01088
01095 int moduleDelCommand(CommandHash * cmdTable[], char *name)
01096 {
01097 Command *c = NULL;
01098 Command *cmd = NULL;
01099 int status = 0;
01100
01101 if (!mod_current_module) {
01102 return MOD_ERR_UNKNOWN;
01103 }
01104
01105 c = findCommand(cmdTable, name);
01106 if (!c) {
01107 return MOD_ERR_NOEXIST;
01108 }
01109
01110
01111 for (cmd = c; cmd; cmd = cmd->next) {
01112 if (cmd->mod_name
01113 && stricmp(cmd->mod_name, mod_current_module->name) == 0) {
01114 if (debug >= 2) {
01115 displayCommandFromHash(cmdTable, name);
01116 }
01117 status = delCommand(cmdTable, cmd, mod_current_module->name);
01118 if (debug >= 2) {
01119 displayCommandFromHash(cmdTable, name);
01120 }
01121 }
01122 }
01123 return status;
01124 }
01125
01133 int displayCommandFromHash(CommandHash * cmdTable[], char *name)
01134 {
01135 CommandHash *current = NULL;
01136 int index = 0;
01137 index = CMD_HASH(name);
01138 if (debug > 1) {
01139 alog("debug: trying to display command %s", name);
01140 }
01141 for (current = cmdTable[index]; current; current = current->next) {
01142 if (stricmp(name, current->name) == 0) {
01143 displayCommand(current->c);
01144 }
01145 }
01146 if (debug > 1) {
01147 alog("debug: done displaying command %s", name);
01148 }
01149 return 0;
01150 }
01151
01159 int displayCommand(Command * c)
01160 {
01161 Command *cmd = NULL;
01162 int i = 0;
01163 alog("Displaying command list for %s", c->name);
01164 for (cmd = c; cmd; cmd = cmd->next) {
01165 alog("%d: 0x%p", ++i, (void *) cmd);
01166 }
01167 alog("end");
01168 return 0;
01169 }
01170
01177 int displayMessageFromHash(char *name)
01178 {
01179 MessageHash *current = NULL;
01180 int index = 0;
01181 index = CMD_HASH(name);
01182 if (debug > 1) {
01183 alog("debug: trying to display message %s", name);
01184 }
01185 for (current = IRCD[index]; current; current = current->next) {
01186 if (stricmp(name, current->name) == 0) {
01187 displayMessage(current->m);
01188 }
01189 }
01190 if (debug > 1) {
01191 alog("debug: done displaying message %s", name);
01192 }
01193 return 0;
01194 }
01195
01202 int displayMessage(Message * m)
01203 {
01204 Message *msg = NULL;
01205 int i = 0;
01206 alog("Displaying message list for %s", m->name);
01207 for (msg = m; msg; msg = msg->next) {