00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "modules.h"
00015 #include "language.h"
00016 #include "version.h"
00017
00018 #if defined(USE_MODULES) && !defined(_WIN32)
00019 #include <dlfcn.h>
00020
00021 #ifndef RTLD_NOW
00022 #define RTLD_NOW 0
00023 #endif
00024 #ifndef RTLD_LAZY
00025 #define RTLD_LAZY RTLD_NOW
00026 #endif
00027 #ifndef RTLD_GLOBAL
00028 #define RTLD_GLOBAL 0
00029 #endif
00030 #ifndef RTLD_LOCAL
00031 #define RTLD_LOCAL 0
00032 #endif
00033 #endif
00034
00035 #ifdef _WIN32
00036 const char *ano_moderr(void);
00037 #endif
00038
00042 CommandHash *HOSTSERV[MAX_CMD_HASH];
00043 CommandHash *BOTSERV[MAX_CMD_HASH];
00044 CommandHash *MEMOSERV[MAX_CMD_HASH];
00045 CommandHash *NICKSERV[MAX_CMD_HASH];
00046 CommandHash *CHANSERV[MAX_CMD_HASH];
00047 CommandHash *HELPSERV[MAX_CMD_HASH];
00048 CommandHash *OPERSERV[MAX_CMD_HASH];
00049 MessageHash *IRCD[MAX_CMD_HASH];
00050 ModuleHash *MODULE_HASH[MAX_CMD_HASH];
00051
00052 Module *mod_current_module;
00053 char *mod_current_module_name = NULL;
00054 char *mod_current_buffer = NULL;
00055 User *mod_current_user;
00056 ModuleCallBack *moduleCallBackHead = NULL;
00057 ModuleQueue *mod_operation_queue = NULL;
00058
00059 int displayCommand(Command * c);
00060 int displayCommandFromHash(CommandHash * cmdTable[], char *name);
00061 int displayMessageFromHash(char *name);
00062 int displayMessage(Message * m);
00063 char *ModuleGetErrStr(int status);
00064
00065 char *ModuleGetErrStr(int status)
00066 {
00067 const char *module_err_str[] = {
00068 "Module, Okay - No Error",
00069 "Module Error, Allocating memory",
00070 "Module Error, Not enough parameters",
00071 "Module Error, Already loaded",
00072 "Module Error, File does not exist",
00073 "Module Error, No User",
00074 "Module Error, Error during load time or module returned MOD_STOP",
00075 "Module Error, Unable to unload",
00076 "Module Error, Incorrect syntax",
00077 "Module Error, Unable to delete",
00078 "Module Error, Unknown Error occuried",
00079 "Module Error, File I/O Error",
00080 "Module Error, No Service found for request",
00081 "Module Error, No module name for request"
00082 };
00083 return (char *) module_err_str[status];
00084 }
00085
00091 void modules_init(void)
00092 {
00093 #ifdef USE_MODULES
00094 int idx;
00095 int ret;
00096 Module *m;
00097
00098 if(nothird) {
00099 return;
00100 }
00101
00102 for (idx = 0; idx < ModulesNumber; idx++) {
00103 m = findModule(ModulesAutoload[idx]);
00104 if (!m) {
00105 m = createModule(ModulesAutoload[idx]);
00106 mod_current_module = m;
00107 mod_current_module_name = m->name;
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_module_name = NULL;
00116 mod_current_user = NULL;
00117 }
00118 }
00119 #endif
00120 }
00121
00127 void modules_core_init(int number, char **list)
00128 {
00129 int idx;
00130 Module *m;
00131 int status = 0;
00132 for (idx = 0; idx < number; idx++) {
00133 m = findModule(list[idx]);
00134 if (!m) {
00135 m = createModule(list[idx]);
00136 mod_current_module = m;
00137 mod_current_module_name = m->name;
00138 mod_current_user = NULL;
00139 status = loadModule(mod_current_module, NULL);
00140 mod_current_module = m;
00141 mod_current_module_name = m->name;
00142 if (debug || status) {
00143 alog("debug: trying to load core module [%s]",
00144 mod_current_module->name);
00145 alog("debug: status: [%d][%s]", status, ModuleGetErrStr(status));
00146 if (status != MOD_ERR_OK)
00147 destroyModule(mod_current_module);
00148 }
00149 mod_current_module = NULL;
00150 mod_current_module_name = NULL;
00151 mod_current_user = NULL;
00152 }
00153 }
00154 }
00158 int encryption_module_init(void) {
00159 int ret = 0;
00160 Module *m;
00161
00162 m = createModule(EncModule);
00163 mod_current_module = m;
00164 mod_current_module_name = m->name;
00165 mod_current_user = NULL;
00166 alog("Loading Encryption Module: [%s]", mod_current_module->name);
00167 ret = loadModule(mod_current_module, NULL);
00168 mod_current_module = m;
00169 mod_current_module_name = m->name;
00170 moduleSetType(ENCRYPTION);
00171 alog("status: [%d][%s]", ret, ModuleGetErrStr(ret));
00172 mod_current_module = NULL;
00173 mod_current_module_name = NULL;
00174 if (ret != MOD_ERR_OK) {
00175 destroyModule(m);
00176 }
00177 return ret;
00178 }
00179
00183 int protocol_module_init(void)
00184 {
00185 int ret = 0, noforksave = nofork;
00186 Module *m;
00187
00188 m = createModule(IRCDModule);
00189 mod_current_module = m;
00190 mod_current_module_name = m->name;
00191 mod_current_user = NULL;
00192 alog("Loading IRCD Protocol Module: [%s]", mod_current_module->name);
00193 ret = loadModule(mod_current_module, NULL);
00194 mod_current_module = m;
00195 mod_current_module_name = m->name;
00196 moduleSetType(PROTOCOL);
00197 alog("status: [%d][%s]", ret, ModuleGetErrStr(ret));
00198 mod_current_module = NULL;
00199 mod_current_module_name = NULL;
00200
00201 if (ret == MOD_ERR_OK) {
00202
00203
00204
00205
00206 if (UseTokens && !ircd->token) {
00207 alog("Anope does not support TOKENS for this ircd setting; unsetting UseToken");
00208 UseTokens = 0;
00209 }
00210
00211 if (UseTS6 && !ircd->ts6) {
00212 alog("Chosen IRCd does not support TS6, unsetting UseTS6");
00213 UseTS6 = 0;
00214 }
00215
00216
00217 if (UseTS6 && !Numeric) {
00218 nofork = 1;
00219 alog("UseTS6 requires the setting of Numeric to be enabled.");
00220 nofork = noforksave;
00221 ret = -1;
00222 }
00223 } else {
00224 destroyModule(m);
00225 }
00226
00227 return ret;
00228 }
00229
00235 void modules_delayed_init(void)
00236 {
00237 #ifdef USE_MODULES
00238 int idx;
00239 int ret;
00240 Module *m;
00241
00242 if(nothird) {
00243 return;
00244 }
00245
00246 for (idx = 0; idx < ModulesDelayedNumber; idx++) {
00247 m = findModule(ModulesDelayedAutoload[idx]);
00248 if (!m) {
00249 m = createModule(ModulesDelayedAutoload[idx]);
00250 mod_current_module = m;
00251 mod_current_module_name = m->name;
00252 mod_current_user = NULL;
00253 alog("trying to load [%s]", mod_current_module->name);
00254 ret = loadModule(mod_current_module, NULL);
00255 alog("status: [%d][%s]", ret, ModuleGetErrStr(ret));
00256 mod_current_module = NULL;
00257 mod_current_module_name = NULL;
00258 mod_current_user = NULL;
00259 if (ret != MOD_ERR_OK)
00260 destroyModule(m);
00261 }
00262 }
00263 #endif
00264 }
00265
00276 void modules_unload_all(boolean fini, boolean unload_proto)
00277 {
00278 #ifdef USE_MODULES
00279 int idx;
00280 ModuleHash *mh, *next;
00281
00282 for (idx = 0; idx < MAX_CMD_HASH; idx++) {
00283 mh = MODULE_HASH[idx];
00284 while (mh) {
00285 next = mh->next;
00286 if (unload_proto || (mh->m->type != PROTOCOL)) {
00287 mod_current_module = mh->m;
00288 mod_current_module_name = mh->m->name;
00289 if(fini) {
00290 union fini_union
00291 {
00292 void *ptr;
00293 void (*func)(void);
00294 } u;
00295 u.ptr = ano_modsym(mh->m->handle, "AnopeFini");
00296 if (u.ptr)
00297 u.func();
00298
00299 if (prepForUnload(mh->m) != MOD_ERR_OK) {
00300 mh = next;
00301 continue;
00302 }
00303
00304 if ((ano_modclose(mh->m->handle)) != 0)
00305 alog("%s", ano_moderr());
00306 else
00307 delModule(mh->m);
00308 } else {
00309 delModule(mh->m);
00310 }
00311 mod_current_module = NULL;
00312 mod_current_module_name = NULL;
00313 }
00314 mh = next;
00315 }
00316 }
00317 #endif
00318 }
00319
00325 Module *createModule(char *filename)
00326 {
00327 Module *m;
00328 int i = 0;
00329 if (!filename) {
00330 return NULL;
00331 }
00332 if ((m = malloc(sizeof(Module))) == NULL) {
00333 fatal("Out of memory!");
00334 }
00335
00336 m->name = sstrdup(filename);
00337 m->handle = NULL;
00338 m->version = NULL;
00339 m->author = NULL;
00340 m->nickHelp = NULL;
00341 m->chanHelp = NULL;
00342 m->memoHelp = NULL;
00343 m->botHelp = NULL;
00344 m->operHelp = NULL;
00345 m->hostHelp = NULL;
00346 m->helpHelp = NULL;
00347
00348 m->type = THIRD;
00349 for (i = 0; i < NUM_LANGS; i++) {
00350 m->lang[i].argc = 0;
00351 }
00352 return m;
00353 }
00354
00361 int destroyModule(Module * m)
00362 {
00363 int i = 0;
00364 if (!m) {
00365 return MOD_ERR_PARAMS;
00366 }
00367
00368 mod_current_module = m;
00369 mod_current_module_name = m->name;
00370 for (i = 0; i < NUM_LANGS; i++) {
00371 moduleDeleteLanguage(i);
00372 }
00373
00374 if (m->name) {
00375 free(m->name);
00376 }
00377 if (m->filename) {
00378 remove(m->filename);
00379 free(m->filename);
00380 }
00381 m->handle = NULL;
00382 if (m->author) {
00383 free(m->author);
00384 }
00385 if (m->version) {
00386 free(m->version);
00387 }
00388
00389
00390 free(m);
00391
00392 mod_current_module = NULL;
00393 mod_current_module_name = NULL;
00394
00395 return MOD_ERR_OK;
00396 }
00397
00403 int addModule(Module * m)
00404 {
00405 int index = 0;
00406 ModuleHash *current = NULL;
00407 ModuleHash *newHash = NULL;
00408 ModuleHash *lastHash = NULL;
00409
00410 index = CMD_HASH(m->name);
00411
00412 for (current = MODULE_HASH[index]; current; current = current->next) {
00413 if (stricmp(m->name, current->name) == 0)
00414 return MOD_ERR_EXISTS;
00415 lastHash = current;
00416 }
00417
00418 if ((newHash = malloc(sizeof(ModuleHash))) == NULL) {
00419 fatal("Out of memory");
00420 }
00421 m->time = time(NULL);
00422 newHash->next = NULL;
00423 newHash->name = sstrdup(m->name);
00424 newHash->m = m;
00425
00426 if (lastHash == NULL)
00427 MODULE_HASH[index] = newHash;
00428 else
00429 lastHash->next = newHash;
00430 return MOD_ERR_OK;
00431 }
00432
00438 int delModule(Module * m)
00439 {
00440 int index = 0;
00441 ModuleHash *current = NULL;
00442 ModuleHash *lastHash = NULL;
00443
00444 if (!m) {
00445 return MOD_ERR_PARAMS;
00446 }
00447
00448 index = CMD_HASH(m->name);
00449
00450 for (current = MODULE_HASH[index]; current; current = current->next) {
00451 if (stricmp(m->name, current->name) == 0) {
00452 if (!lastHash) {
00453 MODULE_HASH[index] = current->next;
00454 } else {
00455 lastHash->next = current->next;
00456 }
00457 destroyModule(current->m);
00458 free(current->name);
00459 free(current);
00460 return MOD_ERR_OK;
00461 }
00462 lastHash = current;
00463 }
00464 return MOD_ERR_NOEXIST;
00465 }
00466
00472 Module *findModule(char *name)
00473 {
00474 int idx;
00475 ModuleHash *current = NULL;
00476 if (!name) {
00477 return NULL;
00478 }
00479 idx = CMD_HASH(name);
00480
00481 for (current = MODULE_HASH[idx]; current; current = current->next) {
00482 if (stricmp(name, current->name) == 0) {
00483 return current->m;
00484 }
00485 }
00486 return NULL;
00487
00488 }
00489
00494 int protocolModuleLoaded()
00495 {
00496 int idx = 0;
00497 ModuleHash *current = NULL;
00498
00499 for (idx = 0; idx != MAX_CMD_HASH; idx++) {
00500 for (current = MODULE_HASH[idx]; current; current = current->next) {
00501 if (current->m->type == PROTOCOL) {
00502 return 1;
00503 }
00504 }
00505 }
00506 return 0;
00507 }
00508
00513 int encryptionModuleLoaded()
00514 {
00515 int idx = 0;
00516 ModuleHash *current = NULL;
00517
00518 for (idx = 0; idx != MAX_CMD_HASH; idx++) {
00519 for (current = MODULE_HASH[idx]; current; current = current->next) {
00520 if (current->m->type == ENCRYPTION) {
00521 return 1;
00522 }
00523 }
00524 }
00525 return 0;
00526 }
00527
00537 int moduleCopyFile(char *name, char *output)
00538 {
00539 #ifdef USE_MODULES
00540 int ch;
00541 FILE *source, *target;
00542 int srcfp;
00543 char input[4096] = "";
00544 int len;
00545
00546 strncpy(input, MODULE_PATH, 4095);
00547 len = strlen(input);
00548 strncat(input, name, 4095 - len);
00549 len = strlen(output);
00550 strncat(input, MODULE_EXT, 4095 - len);
00551
00552 #ifndef _WIN32
00553 if ((srcfp = mkstemp(output)) == -1)
00554 return MOD_ERR_FILE_IO;
00555 #else
00556 if (!mktemp(output))
00557 return MOD_ERR_FILE_IO;
00558 #endif
00559
00560 if (debug)
00561 alog("Runtime module location: %s", output);
00562
00563
00564
00565
00566 #ifndef _WIN32
00567 if ((source = fopen(input, "r")) == NULL) {
00568 close(srcfp);
00569 #else
00570 if ((source = fopen(input, "rb")) == NULL) {
00571 #endif
00572 return MOD_ERR_NOEXIST;
00573 }
00574 #ifndef _WIN32
00575 if ((target = fdopen(srcfp, "w")) == NULL) {
00576 #else
00577 if ((target = fopen(output, "wb")) == NULL) {
00578 #endif
00579 fclose(source);
00580 return MOD_ERR_FILE_IO;
00581 }
00582 while ((ch = fgetc(source)) != EOF) {
00583 fputc(ch, target);
00584 }
00585 fclose(source);
00586 if (fclose(target) != 0) {
00587 return MOD_ERR_FILE_IO;
00588 }
00589 #endif
00590 return MOD_ERR_OK;
00591 }
00592
00599 int loadModule(Module * m, User * u)
00600 {
00601 #ifdef USE_MODULES
00602 char buf[4096];
00603 int len;
00604 const char *err;
00605 int ret = 0;
00606 char *argv[1];
00607 int argc = 0;
00608
00609 union init_func_union
00610 {
00611 void *ptr;
00612 int (*func)(int, char **);
00613 } init_union;
00614
00615 union version_func_union
00616 {
00617 void *ptr;
00618 int (*func)();
00619 } version_union;
00620
00621 Module *m2;
00622 if (!m || !m->name) {
00623 return MOD_ERR_PARAMS;
00624 }
00625 if (m->handle) {
00626 return MOD_ERR_EXISTS;
00627 }
00628 if ((m2 = findModule(m->name)) != NULL) {
00629 return MOD_ERR_EXISTS;
00630 }
00631
00632
00633 strncpy(buf, MODULE_PATH, 4095);
00634 len = strlen(buf);
00635 #ifndef _WIN32
00636 strncat(buf, "runtime/", 4095 - len);
00637 #else
00638 strncat(buf, "runtime\\", 4095 - len);
00639 #endif
00640 len = strlen(buf);
00641 strncat(buf, m->name, 4095 - len);
00642 len = strlen(buf);
00643 strncat(buf, MODULE_EXT, 4095 - len);
00644 len = strlen(buf);
00645 strncat(buf, ".", 4095 - len);
00646 len = strlen(buf);
00647 strncat(buf, "XXXXXX", 4095 - len);
00648 buf[4095] = '\0';
00649
00650 if ((ret = moduleCopyFile(m->name, buf)) != MOD_ERR_OK) {
00651 m->filename = sstrdup(buf);
00652 return ret;
00653 }
00654
00655 m->filename = sstrdup(buf);
00656 ano_modclearerr();
00657 m->handle = ano_modopen(m->filename);
00658 if ( m->handle == NULL && (err = ano_moderr()) != NULL) {
00659 alog("%s", err);
00660 return MOD_ERR_NOLOAD;
00661 }
00662 ano_modclearerr();
00663
00664 init_union.ptr = ano_modsym(m->handle, "AnopeInit");
00665
00666 if ( init_union.ptr == NULL && (err = ano_moderr()) != NULL) {
00667 ano_modclose(m->handle);
00668 return MOD_ERR_NOLOAD;
00669 }
00670 if (init_union.ptr) {
00671 version_union.ptr = ano_modsym(m->handle,"getAnopeBuildVersion");
00672 if (version_union.ptr) {
00673 if (version_union.func() >= VERSION_BUILD ) {
00674 if(debug) {
00675 alog("Module %s compiled against current or newer anope revision %d, this is %d",m->name,version_union.func(),VERSION_BUILD);
00676 }
00677 } else {
00678 alog("Module %s is compiled against an old version of anope (%d) current is %d", m->name, version_union.func(), VERSION_BUILD);
00679 alog("Rebuild module %s against the current version to resolve this error", m->name);
00680 ano_modclose(m->handle);
00681 ano_modclearerr();
00682 return MOD_ERR_NOLOAD;
00683 }
00684 } else {
00685 ano_modclose(m->handle);
00686 ano_modclearerr();
00687 alog("Module %s is compiled against an older version of anope (unknown)", m->name);
00688 alog("Rebuild module %s against the current version to resolve this error", m->name);
00689 return MOD_ERR_NOLOAD;
00690 }
00691
00692 mod_current_module = m;
00693 mod_current_module_name = m->name;
00694
00695 if (u) {
00696 argv[0] = sstrdup(u->nick);
00697 } else {
00698 argv[0] = NULL;
00699 }
00700 argc++;
00701
00702 init_union.func(argc, argv);
00703 if (u) {
00704 free(argv[0]);
00705 }
00706 if (m->type == PROTOCOL && protocolModuleLoaded()) {
00707 alog("You cannot load two protocol modules");
00708 ret = MOD_STOP;
00709 } else if (m->type == ENCRYPTION && encryptionModuleLoaded()) {
00710 alog("You cannot load two encryption modules");
00711 ret = MOD_STOP;
00712 }
00713 if (ret == MOD_STOP) {
00714 alog("%s requested unload...", m->name);
00715 unloadModule(m, NULL);
00716 mod_current_module = NULL;
00717 mod_current_module_name = NULL;
00718 return MOD_ERR_NOLOAD;
00719 }
00720
00721 mod_current_module = NULL;
00722 mod_current_module_name = NULL;
00723 }
00724
00725 if (u) {
00726 anope_cmd_global(s_OperServ, "%s loaded module %s", u->nick,
00727 m->name);
00728 notice_lang(s_OperServ, u, OPER_MODULE_LOADED, m->name);
00729 }
00730 addModule(m);
00731
00732
00733 send_event(EVENT_MODLOAD, 1, m->name);
00734
00735 return MOD_ERR_OK;
00736
00737 #else
00738 return MOD_ERR_NOLOAD;
00739 #endif
00740 }
00741
00748 int unloadModule(Module * m, User * u)
00749 {
00750 #ifdef USE_MODULES
00751 union fini_union
00752 {
00753 void *ptr;
00754 void (*func)(void);
00755 } un;
00756
00757 if (!m || !m->handle) {
00758 if (u) {
00759 notice_lang(s_OperServ, u, OPER_MODULE_REMOVE_FAIL, m->name);
00760 }
00761 return MOD_ERR_PARAMS;
00762 }
00763
00764 if (m->type == PROTOCOL) {
00765 if (u) {
00766 notice_lang(s_OperServ, u, OPER_MODULE_NO_UNLOAD);
00767 }
00768 return MOD_ERR_NOUNLOAD;
00769 } else if(m->type == ENCRYPTION) {
00770 if (u) {
00771 notice_lang(s_OperServ, u, OPER_MODULE_NO_UNLOAD);
00772 }
00773 return MOD_ERR_NOUNLOAD;
00774 }
00775
00776 un.ptr = ano_modsym(m->handle, "AnopeFini");
00777 if (un.ptr) {
00778 mod_current_module = m;
00779 mod_current_module_name = m->name;
00780 un.func();
00781 }
00782
00783 if (prepForUnload(m) != MOD_ERR_OK) {
00784 return MOD_ERR_UNKNOWN;
00785 }
00786
00787
00788
00789 send_event(EVENT_MODUNLOAD, 1, m->name);
00790
00791 if ((ano_modclose(m->handle)) != 0) {
00792 alog("%s", ano_moderr());
00793 if (u) {
00794 notice_lang(s_OperServ, u, OPER_MODULE_REMOVE_FAIL, m->name);
00795 }
00796 mod_current_module = NULL;
00797 mod_current_module_name = NULL;
00798 return MOD_ERR_NOUNLOAD;
00799 } else {
00800 if (u) {
00801 anope_cmd_global(s_OperServ, "%s unloaded module %s", u->nick,
00802 m->name);
00803 notice_lang(s_OperServ, u, OPER_MODULE_UNLOADED, m->name);
00804 }
00805 delModule(m);
00806 mod_current_module = NULL;
00807 mod_current_module_name = NULL;
00808 return MOD_ERR_OK;
00809 }
00810 #else
00811 return MOD_ERR_NOUNLOAD;
00812 #endif
00813 }
00814
00819 void moduleSetType(MODType type)
00820 {
00821 mod_current_module->type = type;
00822 }
00823
00831 int prepForUnload(Module * m)
00832 {
00833 int idx;
00834 CommandHash *current = NULL;
00835 MessageHash *mcurrent = NULL;
00836 EvtMessageHash *ecurrent = NULL;
00837 EvtHookHash *ehcurrent = NULL;
00838
00839 Command *c;
00840 Message *msg;
00841 EvtMessage *eMsg;
00842 EvtHook *eHook;
00843
00844 if (!m) {
00845 return MOD_ERR_PARAMS;
00846 }
00847
00848
00849 moduleCallBackPrepForUnload(m->name);
00850
00851
00852 moduleDelAllDataMod(m);
00853
00857 for (idx = 0; idx < MAX_CMD_HASH; idx++) {
00858 for (current = HS_cmdTable[idx]; current; current = current->next) {
00859 for (c = current->c; c; c = c->next) {
00860 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00861 moduleDelCommand(HOSTSERV, c->name);
00862 }
00863 }
00864 }
00865
00866 for (current = BS_cmdTable[idx]; current; current = current->next) {
00867 for (c = current->c; c; c = c->next) {
00868 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00869 moduleDelCommand(BOTSERV, c->name);
00870 }
00871 }
00872 }
00873
00874 for (current = MS_cmdTable[idx]; current; current = current->next) {
00875 for (c = current->c; c; c = c->next) {
00876 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00877 moduleDelCommand(MEMOSERV, c->name);
00878 }
00879 }
00880 }
00881
00882 for (current = NS_cmdTable[idx]; current; current = current->next) {
00883 for (c = current->c; c; c = c->next) {
00884 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00885 moduleDelCommand(NICKSERV, c->name);
00886 }
00887 }
00888 }
00889
00890 for (current = CS_cmdTable[idx]; current; current = current->next) {
00891 for (c = current->c; c; c = c->next) {
00892 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00893 moduleDelCommand(CHANSERV, c->name);
00894 }
00895 }
00896 }
00897
00898 for (current = HE_cmdTable[idx]; current; current = current->next) {
00899 for (c = current->c; c; c = c->next) {
00900 if ((c->mod_name) && (strcmp(c->mod_name, m->name) == 0)) {
00901 moduleDelCommand(HELPSERV, c->name);
00902 }
00903 }
00904 }
00905
00906 for (current = OS_cmdTable[idx]; current; current = current->next) {
00907 for (c = current->c; c; c = c->next) {
00908 if ((c->mod_name) && (stricmp(c->mod_name, m->name) == 0)) {
00909 moduleDelCommand(OPERSERV, c->name);
00910 }
00911 }
00912 }
00913
00914 for (mcurrent = IRCD[idx]; mcurrent; mcurrent = mcurrent->next) {
00915 for (msg = mcurrent->m; msg; msg = msg->next) {
00916 if ((msg->mod_name)
00917 && (stricmp(msg->mod_name, m->name) == 0)) {
00918 moduleDelMessage(msg->name);
00919 }
00920 }
00921 }
00922
00923 for (ecurrent = EVENT[idx]; ecurrent; ecurrent = ecurrent->next) {
00924 for (eMsg = ecurrent->evm; eMsg; eMsg = eMsg->next) {
00925 if ((eMsg->mod_name)
00926 && (stricmp(eMsg->mod_name, m->name) == 0)) {
00927 delEventHandler(EVENT, eMsg, m->name);
00928 }
00929 }
00930 }
00931 for (ehcurrent = EVENTHOOKS[idx]; ehcurrent;
00932 ehcurrent = ehcurrent->next) {
00933 for (eHook = ehcurrent->evh; eHook; eHook = eHook->next) {
00934 if ((eHook->mod_name)
00935 && (stricmp(eHook->mod_name, m->name) == 0)) {
00936 delEventHook(EVENTHOOKS, eHook, m->name);
00937 }
00938 }
00939 }
00940
00941 }
00942 return MOD_ERR_OK;
00943 }
00944
00945
00946
00947
00960 Command *createCommand(const char *name, int (*func) (User * u),
00961 int (*has_priv) (User * u), int help_all,
00962 int help_reg, int help_oper, int help_admin,
00963 int help_root)
00964 {
00965 Command *c;
00966 if (!name || !*name) {
00967 return NULL;
00968 }
00969
00970 if ((c = malloc(sizeof(Command))) == NULL) {
00971 fatal("Out of memory!");
00972 }
00973 c->name = sstrdup(name);
00974 c->routine = func;
00975 c->has_priv = has_priv;
00976 c->helpmsg_all = help_all;
00977 c->helpmsg_reg = help_reg;
00978 c->helpmsg_oper = help_oper;
00979 c->helpmsg_admin = help_admin;
00980 c->helpmsg_root = help_root;
00981 c->help_param1 = NULL;
00982 c->help_param2 = NULL;
00983 c->help_param3 = NULL;
00984 c->help_param4 = NULL;
00985 c->next = NULL;
00986 c->mod_name = NULL;
00987 c->service = NULL;
00988 c->all_help = NULL;
00989 c->regular_help = NULL;
00990 c->oper_help = NULL;
00991 c->admin_help = NULL;
00992 c->root_help = NULL;
00993 return c;
00994 }
00995
01001 int destroyCommand(Command * c)
01002 {
01003 if (!c) {
01004 return MOD_ERR_PARAMS;
01005 }
01006 if (c->core == 1) {
01007 return MOD_ERR_UNKNOWN;
01008 }
01009 if (c->name) {
01010 free(c->name);
01011 }
01012 c->routine = NULL;
01013 c->has_priv = NULL;
01014 c->helpmsg_all = -1;
01015 c->helpmsg_reg = -1;
01016 c->helpmsg_oper = -1;
01017 c->helpmsg_admin = -1;
01018 c->helpmsg_root = -1;
01019 if (c->help_param1) {
01020 free(c->help_param1);
01021 }
01022 if (c->help_param2) {
01023 free(c->help_param2);
01024 }
01025 if (c->help_param3) {
01026 free(c->help_param3);
01027 }
01028 if (c->help_param4) {
01029 free(c->help_param4);
01030 }
01031 if (c->mod_name) {
01032 free(c->mod_name);
01033 }
01034 if (c->service) {
01035 free(c->service);
01036 }
01037 c->next = NULL;
01038 free(c);
01039 return MOD_ERR_OK;
01040 }
01041
01048 int addCoreCommand(CommandHash * cmdTable[], Command * c)
01049 {
01050 if (!cmdTable || !c) {
01051 return MOD_ERR_PARAMS;
01052 }
01053 c->core = 1;
01054 c->next = NULL;
01055 return addCommand(cmdTable, c, 0);
01056 }
01057
01067 int moduleAddCommand(CommandHash * cmdTable[], Command * c, int pos)
01068 {
01069 int status;
01070
01071 if (!cmdTable || !c) {
01072 return MOD_ERR_PARAMS;
01073 }
01074
01075 if (!mod_current_module) {
01076 return MOD_ERR_UNKNOWN;
01077 }
01078 c->core = 0;
01079 if (!c->mod_name) {
01080 c->mod_name = sstrdup(mod_current_module->name);
01081 }
01082
01083
01084 if (cmdTable == HOSTSERV) {
01085 if (s_HostServ) {
01086 c->service = sstrdup(s_HostServ);
01087 } else {
01088 return MOD_ERR_NOSERVICE;
01089 }
01090 } else if (cmdTable == BOTSERV) {
01091 if (s_BotServ) {
01092 c->service = sstrdup(s_BotServ);
01093 } else {
01094 return MOD_ERR_NOSERVICE;
01095 }
01096 } else if (cmdTable == MEMOSERV) {
01097 if (s_MemoServ) {
01098 c->service = sstrdup(s_MemoServ);
01099 } else {
01100 return MOD_ERR_NOSERVICE;
01101 }
01102 } else if (cmdTable == CHANSERV) {
01103 if (s_ChanServ) {
01104 c->service = sstrdup(s_ChanServ);
01105 } else {
01106 return MOD_ERR_NOSERVICE;
01107 }
01108 } else if (cmdTable == NICKSERV) {
01109 if (s_NickServ) {
01110 c->service = sstrdup(s_NickServ);
01111 } else {
01112 return MOD_ERR_NOSERVICE;
01113 }
01114 } else if (cmdTable == HELPSERV) {
01115 if (s_HelpServ) {
01116 c->service = sstrdup(s_HelpServ);
01117 } else {
01118 return MOD_ERR_NOSERVICE;
01119 }
01120 } else if (cmdTable == OPERSERV) {
01121 if (s_OperServ) {
01122 c->service = sstrdup(s_OperServ);
01123 } else {
01124 return MOD_ERR_NOSERVICE;
01125 }
01126 } else
01127 c->service = sstrdup("Unknown");
01128
01129 if (debug >= 2)
01130 displayCommandFromHash(cmdTable, c->name);
01131 status = addCommand(cmdTable, c, pos);
01132 if (debug >= 2)
01133 displayCommandFromHash(cmdTable, c->name);
01134 if (status != MOD_ERR_OK) {
01135 alog("ERROR! [%d]", status);
01136 }
01137 return status;
01138 }
01139
01146 int moduleDelCommand(CommandHash * cmdTable[], char *name)
01147 {
01148 Command *c = NULL;
01149 Command *cmd = NULL;
01150 int status = 0;
01151
01152 if (!mod_current_module) {
01153 return MOD_ERR_UNKNOWN;
01154 }
01155
01156 c = findCommand(cmdTable, name);
01157 if (!c) {
01158 return MOD_ERR_NOEXIST;
01159 }
01160
01161
01162 for (cmd = c; cmd; cmd = cmd->next) {
01163 if (cmd->mod_name
01164 && stricmp(cmd->mod_name, mod_current_module->name) == 0) {
01165 if (debug >= 2) {
01166 displayCommandFromHash(cmdTable, name);
01167 }
01168 status = delCommand(cmdTable, cmd, mod_current_module->name);
01169 if (debug >= 2) {
01170 displayCommandFromHash(cmdTable, name);
01171 }
01172 }
01173 }
01174 return status;
01175 }
01176
01184 int displayCommandFromHash(CommandHash * cmdTable[], char *name)
01185 {
01186 CommandHash *current = NULL;
01187 int index = 0;
01188 index = CMD_HASH(name);
01189 if (debug > 1) {
01190 alog("debug: trying to display command %s", name);
01191 }
01192 for (current = cmdTable[index]; current; current = current->next) {
01193 if (stricmp(name, current->name) == 0) {
01194 displayCommand(current->c);
01195 }
01196 }
01197 if (debug > 1) {
01198 alog("debug: done displaying command %s", name);
01199 }
01200 return 0;
01201 }
01202
01210 int displayCommand(Command * c)
01211 {
01212 Command *cmd = NULL;
01213 int i = 0;
01214 alog("Displaying command list for %s", c->name);
01215 for (cmd = c; cmd; cmd = cmd->next) {
01216 alog("%d: 0x%p", ++i, (void *) cmd);
01217 }
01218 alog("end");
01219 return 0;
01220 }
01221
01228 int displayMessageFromHash(char *name)
01229 {
01230 MessageHash *current = NULL;
01231 int index = 0;
01232 index = CMD_HASH(name);
01233 if (debug > 1) {
01234 alog("debug: trying to display message %s", name);
01235 }
01236 for (current = IRCD[index]; current; current = current->next) {
01237 if (stricmp(name, current->name) == 0) {
01238 displayMessage(current->m);
01239 }
01240 }
01241 if (debug > 1) {
01242 alog("debug: done displaying message %s", name);
01243 }
01244 return 0;
01245 }
01246
01253 int displayMessage(Message * m)
01254 {
01255 Message *msg = NULL;
01256 int i = 0;
01257 alog("Displaying message list for %s", m->name);
01258 for (msg = m; msg; msg = msg->next) {
01259 alog("%d: 0x%p", ++i, (void *) msg);
01260 }
01261 alog("end");
01262 return 0;
01263 }
01264
01265
01276 int addCommand(CommandHash * cmdTable[], Command * c, int pos)
01277 {
01278
01279 int index = 0;
01280 CommandHash *current = NULL;
01281 CommandHash *newHash = NULL;
01282 CommandHash *lastHash = NULL;
01283 Command *tail = NULL;
01284
01285 if (!cmdTable || !c || (pos < 0 || pos > 2)) {
01286 return MOD_ERR_PARAMS;
01287 }
01288
01289 if (mod_current_module_name && !c->mod_name)
01290 return MOD_ERR_NO_MOD_NAME;
01291
01292 index = CMD_HASH(c->name);
01293
01294 for (current = cmdTable[index]; current; current = current->next) {
01295 if ((c->service) && (current->c) && (current->c->service)
01296 && (!strcmp(c->service, current->c->service) == 0)) {
01297 continue;
01298 }
01299 if ((stricmp(c->name, current->name) == 0)) {
01300 if (pos == 1) {
01301 c->next = current->c;
01302 current->c = c;
01303 if (debug)
01304 alog("debug: existing cmd: (0x%p), new cmd (0x%p)",
01305 (void *) c->next, (void *) c);
01306 send_event(EVENT_ADDCOMMAND, 2, c->mod_name, c->name);
01307 return MOD_ERR_OK;
01308 } else if (pos == 2) {
01309
01310 tail = current->c;
01311 while (tail->next)
01312 tail = tail->next;
01313 if (debug)
01314 alog("debug: existing cmd: (0x%p), new cmd (0x%p)",
01315 (void *) tail, (void *) c);
01316 tail->next = c;
01317 c->next = NULL;
01318
01319 send_event(EVENT_ADDCOMMAND, 2, c->mod_name, c->name);
01320 return MOD_ERR_OK;
01321 } else
01322 return MOD_ERR_EXISTS;
01323 }
01324 lastHash = current;
01325 }
01326
01327 if ((newHash = malloc(sizeof(CommandHash))) == NULL) {
01328 fatal("Out of memory");
01329 }
01330 newHash->next = NULL;
01331 newHash->name = sstrdup(c->name);
01332 newHash->c = c;
01333
01334 if (lastHash == NULL)
01335 cmdTable[index] = newHash;
01336 else
01337 lastHash->next = newHash;
01338
01339 send_event(EVENT_ADDCOMMAND, 2, c->mod_name, c->name);
01340 return MOD_ERR_OK;
01341 }
01342
01350 int delCommand(CommandHash * cmdTable[], Command * c, char *mod_name)
01351 {
01352 int index = 0;
01353 CommandHash *current = NULL;
01354 CommandHash *lastHash = NULL;
01355 Command *tail = NULL, *last = NULL;
01356
01357 if (!c || !cmdTable) {
01358 return MOD_ERR_PARAMS;
01359 }
01360
01361 index = CMD_HASH(c->name);
01362 for (current = cmdTable[index]; current; current = current->next) {
01363 if (stricmp(c->name, current->name) == 0) {
01364 if (!lastHash) {
01365 tail = current->c;
01366 if (tail->next) {
01367 while (tail) {
01368 if (mod_name && tail->mod_name
01369 && (stricmp(mod_name, tail->mod_name) == 0)) {
01370 if (last) {
01371 last->next = tail->next;
01372 } else {
01373 current->c = tail->next;
01374 }
01375 send_event(EVENT_DELCOMMAND, 2, c->mod_name, c->name);
01376 return MOD_ERR_OK;
01377 }
01378 last = tail;
01379 tail = tail->next;
01380 }
01381 } else {
01382 cmdTable[index] = current->next;
01383 free(current->name);
01384 send_event(EVENT_DELCOMMAND, 2, c->mod_name, c->name);
01385 return MOD_ERR_OK;
01386 }
01387 } else {
01388 tail = current->c;
01389 if (tail->next) {
01390 while (tail) {
01391 if (mod_name && tail->mod_name
01392 && (stricmp(mod_name, tail->mod_name) == 0)) {
01393 if (last) {
01394 last->next = tail->next;
01395 } else {
01396 current->c = tail->next;
01397 }
01398 send_event(EVENT_DELCOMMAND, 2, c->mod_name, c->name);
01399 return MOD_ERR_OK;
01400 }
01401 last = tail;
01402 tail = tail->next;
01403 }
01404 } else {
01405 lastHash->next = current->next;
01406 free(current->name);
01407 send_event(EVENT_DELCOMMAND, 2, c->mod_name, c->name);
01408 return MOD_ERR_OK;
01409 }
01410 }
01411 }
01412 lastHash = current;
01413 }
01414 return MOD_ERR_NOEXIST;
01415 }
01416
01423 Command *findCommand(CommandHash * cmdTable[], const char *name)
01424 {
01425 int idx;
01426 CommandHash *current = NULL;
01427 if (!cmdTable || !name) {
01428 return NULL;
01429 }
01430
01431 idx = CMD_HASH(name);
01432
01433 for (current = cmdTable[idx]; current; current = current->next) {
01434 if (stricmp(name, current->name) == 0) {
01435 return current->c;
01436 }
01437 }
01438 return NULL;
01439 }
01440
01441
01442
01443
01444
01451 Message *createMessage(const char *name,
01452 int (*func) (char *source, int ac, char **av))
01453 {
01454 Message *m = NULL;
01455 if (!name || !func) {
01456 return NULL;
01457 }
01458 if ((m = malloc(sizeof(Message))) == NULL) {
01459 fatal("Out of memory!");
01460 }
01461 m->name = sstrdup(name);
01462 m->func = func;
01463 m->mod_name = NULL;
01464 m->next = NULL;
01465 return m;
01466 }
01467
01475 Message *findMessage(MessageHash * msgTable[], const char *name)
01476 {
01477 int idx;
01478 MessageHash *current = NULL;
01479 if (!msgTable || !name) {
01480 return NULL;
01481 }
01482 idx = CMD_HASH(name);
01483
01484 for (current = msgTable[idx]; current; current = current->next) {
01485 if (UseTokens) {
01486 if (ircd->tokencaseless) {
01487 if (stricmp(name, current->name) == 0) {
01488 return current->m;
01489 }
01490 } else {
01491 if (strcmp(name, current->name) == 0) {
01492 return current->m;
01493 }
01494 }
01495 } else {
01496 if (stricmp(name, current->name) == 0) {
01497 return current->m;
01498 }
01499 }
01500 }
01501 return NULL;
01502 }
01503
01512 int addMessage(MessageHash * msgTable[], Message * m, int pos)
01513 {
01514
01515 int index = 0;
01516 MessageHash *current = NULL;
01517 MessageHash *newHash = NULL;
01518 MessageHash *lastHash = NULL;
01519 Message *tail = NULL;
01520 int match = 0;
01521
01522 if (!msgTable || !m || (pos < 0 || pos > 2)) {
01523 return MOD_ERR_PARAMS;
01524 }
01525
01526 index = CMD_HASH(m->name);
01527
01528 for (current = msgTable[index]; current; current = current->next) {
01529 if ((UseTokens) && (!ircd->tokencaseless)) {
01530 match = strcmp(m->name, current->name);
01531 } else {
01532 match = stricmp(m->name, current->name);
01533 }
01534 if (match == 0) {
01535 if (pos == 1) {
01536 m->next = current->m;
01537 current->m = m;
01538 if (debug)
01539 alog("debug: existing msg: (0x%p), new msg (0x%p)",
01540 (void *) m->next, (void *) m);
01541 return MOD_ERR_OK;
01542 } else if (pos == 2) {
01543 tail = current->m;
01544 while (tail->next)
01545 tail = tail->next;
01546 if (debug)
01547 alog("debug: existing msg: (0x%p), new msg (0x%p)",
01548 (void *) tail, (void *) m);
01549 tail->next = m;
01550 m->next = NULL;
01551 return MOD_ERR_OK;
01552 } else
01553 return MOD_ERR_EXISTS;
01554 }
01555 lastHash = current;
01556 }
01557
01558 if ((newHash = malloc(sizeof(MessageHash))) == NULL) {
01559 fatal("Out of memory");
01560 }
01561 newHash->next = NULL;
01562 newHash->name = sstrdup(m->name);
01563 newHash->m = m;
01564
01565 if (lastHash == NULL)
01566 msgTable[index] = newHash;
01567 else
01568 lastHash->next = newHash;
01569 return MOD_ERR_OK;
01570 }
01571
01578 int addCoreMessage(MessageHash * msgTable[], Message * m)
01579 {
01580 if (!msgTable || !m) {
01581 return MOD_ERR_PARAMS;
01582 }
01583 m->core = 1;
01584 return addMessage(msgTable, m, 0);
01585 }
01586
01593 int moduleAddMessage(Message * m, int pos)
01594 {
01595 int status;
01596
01597 if (!m) {
01598 return MOD_ERR_PARAMS;
01599 }
01600
01601 if (!mod_current_module) {
01602 return MOD_ERR_UNKNOWN;
01603 }
01604 m->core = 0;
01605 if (!m->mod_name) {
01606 m->mod_name = sstrdup(mod_current_module->name);
01607 }
01608
01609 status = addMessage(IRCD, m, pos);
01610 if (debug) {
01611 displayMessageFromHash(m->name);
01612 }
01613 return status;
01614 }
01615
01621 int moduleDelMessage(char *name)
01622 {
01623 Message *m;
01624 int status;
01625
01626 if (!mod_current_module) {
01627 return MOD_ERR_UNKNOWN;
01628 }
01629 m = findMessage(IRCD, name);
01630 if (!m) {
01631 return MOD_ERR_NOEXIST;
01632 }
01633
01634 status = delMessage(IRCD, m, mod_current_module->name);
01635 if (debug) {
01636 displayMessageFromHash(m->name);
01637 }
01638 return status;
01639 }
01640
01648 int delMessage(MessageHash * msgTable[], Message * m, char *mod_name)
01649 {
01650 int index = 0;
01651 MessageHash *current = NULL;
01652 MessageHash *lastHash = NULL;
01653 Message *tail = NULL, *last = NULL;
01654
01655 if (!m || !msgTable) {
01656 return MOD_ERR_PARAMS;
01657 }
01658
01659 index = CMD_HASH(m->name);
01660
01661 for (current = msgTable[index]; current; current = current->next) {
01662 if (stricmp(m->name, current->name) == 0) {
01663 if (!lastHash) {
01664 tail = current->m;
01665 if (tail->next) {
01666 while (tail) {
01667 if (mod_name && tail->mod_name
01668 && (stricmp(mod_name, tail->mod_name) == 0)) {
01669 if (last) {
01670 last->next = tail->next;
01671 } else {
01672 current->m = tail->next;
01673 }
01674 return MOD_ERR_OK;
01675 }
01676 last = tail;
01677 tail = tail->next;
01678 }
01679 } else {
01680 msgTable[index] = current->next;
01681 free(current->name);
01682 return MOD_ERR_OK;
01683 }
01684 } else {
01685 tail = current->m;
01686 if (tail->next) {
01687 while (tail) {
01688 if (mod_name && tail->mod_name
01689 && (stricmp(mod_name, tail->mod_name) == 0)) {
01690 if (last) {
01691 last->next = tail->next;
01692 } else {
01693 current->m = tail->next;
01694 }
01695 return MOD_ERR_OK;
01696 }
01697 last = tail;
01698 tail = tail->next;
01699 }
01700 } else {
01701 lastHash->next = current->next;
01702 free(current->name);
01703 return MOD_ERR_OK;
01704 }
01705 }
01706 }
01707 lastHash = current;
01708 }
01709 return MOD_ERR_NOEXIST;
01710 }
01711
01717 int destroyMessage(Message * m)
01718 {
01719 if (!m) {
01720 return MOD_ERR_PARAMS;
01721 }
01722 if (m->name) {
01723 free(m->name);
01724 }
01725 m->func = NULL;
01726 if (m->mod_name) {
01727 free(m->mod_name);
01728 }
01729 m->next = NULL;
01730 return MOD_ERR_OK;
01731 }
01732
01737 void moduleAddVersion(const char *version)
01738 {
01739 if (mod_current_module && version) {
01740 mod_current_module->version = sstrdup(version);
01741 }
01742 }
01743
01748 void moduleAddAuthor(const char *author)
01749 {
01750 if (mod_current_module && author) {
01751 mod_current_module->author = sstrdup(author);
01752 }
01753 }
01754
01755
01756
01757
01769 int moduleAddCallback(char *name, time_t when,
01770 int (*func) (int argc, char *argv[]), int argc,
01771 char **argv)
01772 {
01773 ModuleCallBack *new, *tmp, *prev;
01774 int i;
01775 new = malloc(sizeof(ModuleCallBack));
01776 if (!new)
01777 return MOD_ERR_MEMORY;
01778
01779 if (name)
01780 new->name = sstrdup(name);
01781 else
01782 new->name = NULL;
01783 new->when = when;
01784 if (mod_current_module_name) {
01785 new->owner_name = sstrdup(mod_current_module_name);
01786 } else {
01787 new->owner_name = NULL;
01788 }
01789 new->func = func;
01790 new->argc = argc;
01791 new->argv = malloc(sizeof(char *) * argc);
01792 for (i = 0; i < argc; i++) {
01793 new->argv[i] = sstrdup(argv[i]);
01794 }
01795 new->next = NULL;
01796
01797 if (moduleCallBackHead == NULL) {
01798 moduleCallBackHead = new;
01799 } else {
01800 tmp = moduleCallBackHead;
01801 prev = tmp;
01802 if (new->when < tmp->when) {
01803 new->next = tmp;
01804 moduleCallBackHead = new;
01805 } else {
01806 while (tmp && new->when >= tmp->when) {
01807 prev = tmp;
01808 tmp = tmp->next;
01809 }
01810 prev->next = new;
01811 new->next = tmp;
01812 }
01813 }
01814 if (debug)
01815 alog("debug: added module CallBack: [%s] due to execute at %ld",
01816 new->name ? new->name : "?", (long int) new->when);
01817 return MOD_ERR_OK;
01818 }
01819
01823 void moduleCallBackRun(void)
01824 {
01825 ModuleCallBack *tmp;
01826
01827 while ((tmp = moduleCallBackHead) && (tmp->when <= time(NULL))) {
01828 if (debug)
01829 alog("debug: executing callback: %s", tmp->name ? tmp->name : "<unknown>");
01830 if (tmp->func) {
01831 mod_current_module = findModule(tmp->owner_name);
01832 mod_current_module_name = tmp->owner_name;
01833 tmp->func(tmp->argc, tmp->argv);
01834 mod_current_module = NULL;
01835 mod_current_module_name = NULL;
01836 moduleCallBackDeleteEntry(NULL);
01837 }
01838 }
01839 }
01840
01845 void moduleCallBackDeleteEntry(ModuleCallBack * prev)
01846 {
01847 ModuleCallBack *tmp = NULL;
01848 int i;
01849 if (prev == NULL) {
01850 tmp = moduleCallBackHead;
01851 moduleCallBackHead = tmp->next;
01852 } else {
01853 tmp = prev->next;
01854 prev->next = tmp->next;
01855 }
01856 if (tmp->name)
01857 free(tmp->name);
01858 if (tmp->owner_name)
01859 free(tmp->owner_name);
01860 tmp->func = NULL;
01861 for (i = 0; i < tmp->argc; i++) {
01862 free(tmp->argv[i]);
01863 }
01864 tmp->argc = 0;
01865 tmp->next = NULL;
01866 free(tmp);
01867 }
01868
01875 ModuleCallBack *moduleCallBackFindEntry(char *mod_name, boolean * found)
01876 {
01877 ModuleCallBack *prev = NULL, *current = NULL;
01878 *found = false;
01879 current = moduleCallBackHead;
01880 while (current != NULL) {
01881 if (current->owner_name
01882 && (strcmp(mod_name, current->owner_name) == 0)) {
01883 *found = true;
01884 break;
01885 } else {
01886 prev = current;
01887 current = current->next;
01888 }
01889 }
01890 if (current == moduleCallBackHead) {
01891 return NULL;
01892 } else {
01893 return prev;
01894 }
01895 }
01896
01901 void moduleDelCallback(char *name)
01902 {
01903 ModuleCallBack *current = NULL;
01904 ModuleCallBack *prev = NULL, *tmp = NULL;
01905 int del = 0;
01906 if (!mod_current_module_name) {
01907 return;
01908 }
01909 if (!name) {
01910 return;
01911 }
01912 current = moduleCallBackHead;
01913 while (current) {
01914 if ((current->owner_name) && (current->name)) {
01915 if ((strcmp(mod_current_module_name, current->owner_name) == 0)
01916 && (strcmp(current->name, name) == 0)) {
01917 if (debug) {
01918 alog("debug: removing CallBack %s for module %s", name,
01919 mod_current_module_name);
01920 }
01921 tmp = current->next;
01922 moduleCallBackDeleteEntry(prev);
01923 del = 1;
01924 }
01925 }
01926 if (del == 1) {
01927 current = tmp;
01928 tmp = NULL;
01929 del = 0;
01930 } else {
01931 prev = current;
01932 current = current->next;
01933 }
01934 }
01935 }
01936
01942 void moduleCallBackPrepForUnload(char *mod_name)
01943 {
01944 boolean found = false;
01945 ModuleCallBack *tmp = NULL;
01946
01947 tmp = moduleCallBackFindEntry(mod_name, &found);
01948 while (found) {
01949 if (debug) {
01950 alog("debug: removing CallBack for module %s", mod_name);
01951 }
01952 moduleCallBackDeleteEntry(tmp);
01953 tmp = moduleCallBackFindEntry(mod_name, &found);
01954 }
01955 }
01956
01962 char *moduleGetLastBuffer(void)
01963 {
01964 char *tmp = NULL;
01965 if (mod_current_buffer) {
01966 tmp = strchr(mod_current_buffer, ' ');
01967 if (tmp) {
01968 tmp++;
01969 }
01970 }
01971 return tmp;
01972 }
01973
01974
01975
01976
01982 int moduleAddRootHelp(Command * c, int (*func) (User * u))
01983 {
01984 if (c) {
01985 c->root_help = func;
01986 return MOD_STOP;
01987 }
01988 return MOD_CONT;
01989 }
01990
01996 int moduleAddAdminHelp(Command * c, int (*func) (User * u))
01997 {
01998 if (c) {
01999 c->admin_help = func;
02000 return MOD_STOP;
02001 }
02002 return MOD_CONT;
02003 }
02004
02010 int moduleAddOperHelp(Command * c, int (*func) (User * u))
02011 {
02012 if (c) {
02013 c->oper_help = func;
02014 return MOD_STOP;
02015 }
02016 return MOD_CONT;
02017 }
02018
02024 int moduleAddRegHelp(Command * c, int (*func) (User * u))
02025 {
02026 if (c) {
02027 c->regular_help = func;
02028 return MOD_STOP;
02029 }
02030 return MOD_CONT;
02031 }
02032
02038 int moduleAddHelp(Command * c, int (*func) (User * u))
02039 {
02040 if (c) {
02041 c->all_help = func;
02042 return MOD_STOP;
02043 }
02044 return MOD_CONT;
02045 }
02046
02052 void moduleSetNickHelp(void (*func) (User * u))
02053 {
02054 if (mod_current_module) {
02055 mod_current_module->nickHelp = func;
02056 }
02057 }
02058
02064 void moduleSetChanHelp(void (*func) (User * u))
02065 {
02066 if (mod_current_module) {
02067 mod_current_module->chanHelp = func;
02068 }
02069 }
02070
02076 void moduleSetMemoHelp(void (*func) (User * u))
02077 {
02078 if (mod_current_module) {
02079 mod_current_module->memoHelp = func;
02080 }
02081 }
02082
02088 void moduleSetBotHelp(void (*func) (User * u))
02089 {
02090 if (mod_current_module) {
02091 mod_current_module->botHelp = func;
02092 }
02093 }
02094
02100 void moduleSetOperHelp(void (*func) (User * u))
02101 {
02102 if (mod_current_module) {
02103 mod_current_module->operHelp = func;
02104 }
02105 }
02106
02112 void moduleSetHostHelp(void (*func) (User * u))
02113 {
02114 if (mod_current_module) {
02115 mod_current_module->hostHelp = func;
02116 }
02117 }
02118
02124 void moduleSetHelpHelp(void (*func) (User * u))
02125 {
02126 if (mod_current_module) {
02127 mod_current_module->helpHelp = func;
02128 }
02129 }
02130
02136 void moduleDisplayHelp(int service, User * u)
02137 {
02138 #ifdef USE_MODULES
02139 int idx;
02140 ModuleHash *current = NULL;
02141 Module *calling_module = mod_current_module;
02142 char *calling_module_name = mod_current_module_name;
02143
02144 for (idx = 0; idx != MAX_CMD_HASH; idx++) {
02145 for (current = MODULE_HASH[idx]; current; current = current->next) {
02146 mod_current_module_name = current->name;
02147 mod_current_module = current->m;
02148
02149 if ((service == 1) && current->m->nickHelp) {
02150 current->m->nickHelp(u);
02151 } else if ((service == 2) && current->m->chanHelp) {
02152 current->m->chanHelp(u);
02153 } else if ((service == 3) && current->m->memoHelp) {
02154 current->m->memoHelp(u);
02155 } else if ((service == 4) && current->m->botHelp) {
02156 current->m->botHelp(u);
02157 } else if ((service == 5) && current->m->operHelp) {
02158 current->m->operHelp(u);
02159 } else if ((service == 6) && current->m->hostHelp) {
02160 current->m->hostHelp(u);
02161 } else if ((service == 7) && current->m->helpHelp) {
02162 current->m->helpHelp(u);
02163 }
02164 }
02165 }
02166
02167 mod_current_module = calling_module;
02168 mod_current_module_name = calling_module_name;
02169 #endif
02170 }
02171
02179 int moduleDataDebug(ModuleData ** md)
02180 {
02181 ModuleData *current = NULL;
02182 alog("Dumping module data....");
02183 for (current = *md; current; current = current->next) {
02184 alog("Module: [%s]", current->moduleName);
02185 alog(" Key [%s]\tValue [%s]", current->key, current->value);
02186 }
02187 alog("End of module data dump");
02188 return 0;
02189 }
02190
02199 int moduleAddData(ModuleData ** md, char *key, char *value)
02200 {
02201 ModuleData *newData = NULL;
02202
02203 if (mod_current_module_name == NULL) {
02204 alog("moduleAddData() called with mod_current_module_name being NULL");
02205 if (debug)
02206 do_backtrace(0);
02207 }
02208
02209 if (!key || !value) {
02210 alog("A module (%s) tried to use ModuleAddData() with one or more NULL arguments... returning", mod_current_module_name);
02211 return MOD_ERR_PARAMS;
02212 }
02213
02214 moduleDelData(md, key);
02215
02216 newData = malloc(sizeof(ModuleData));
02217 if (!newData) {
02218 return MOD_ERR_MEMORY;
02219 }
02220
02221 newData->moduleName = sstrdup(mod_current_module_name);
02222 newData->key = sstrdup(key);
02223 newData->value = sstrdup(value);
02224 newData->next = *md;
02225 *md = newData;
02226
02227 if (debug) {
02228 moduleDataDebug(md);
02229 }
02230 return MOD_ERR_OK;
02231 }
02232
02240 char *moduleGetData(ModuleData ** md, char *key)
02241 {
02242
02243 char *mod_name = sstrdup(mod_current_module_name);
02244 ModuleData *current = *md;
02245
02246 if (mod_current_module_name == NULL) {
02247 alog("moduleGetData() called with mod_current_module_name being NULL");
02248 if (debug)
02249 do_backtrace(0);
02250 }
02251
02252 if (debug > 1) {
02253 alog("debug: moduleGetData %p : key %s", (void *) md, key);
02254 alog("debug: Current Module %s", mod_name);
02255 }
02256
02257 while (current) {
02258 if ((stricmp(current->moduleName, mod_name) == 0)
02259 && (stricmp(current->key, key) == 0)) {
02260 free(mod_name);
02261 return sstrdup(current->value);
02262 }
02263 current = current->next;
02264 }
02265 free(mod_name);
02266 return NULL;
02267 }
02268
02275 void moduleDelData(ModuleData ** md, char *key)
02276 {
02277
02278 char *mod_name = sstrdup(mod_current_module_name);
02279 ModuleData *current = *md;
02280 ModuleData *prev = NULL;
02281 ModuleData *next = NULL;
02282
02283 if (mod_current_module_name == NULL) {
02284 alog("moduleDelData() called with mod_current_module_name being NULL");
02285 if (debug)
02286 do_backtrace(0);
02287 }
02288
02289 if (key) {
02290 while (current) {
02291 next = current->next;
02292 if ((stricmp(current->moduleName, mod_name) == 0)
02293 && (stricmp(current->key, key) == 0)) {
02294 if (prev) {
02295 prev->next = current->next;
02296 } else {
02297 *md = current->next;
02298 }
02299 free(current->moduleName);
02300 free(current->key);
02301 free(current->value);
02302 current->next = NULL;
02303 free(current);
02304 } else {
02305 prev = current;
02306 }
02307 current = next;
02308 }
02309 }
02310 free(mod_name);
02311 }
02312
02319 void moduleDelAllData(ModuleData ** md)
02320 {
02321
02322 char *mod_name = sstrdup(mod_current_module_name);
02323 ModuleData *current = *md;
02324 ModuleData *prev = NULL;
02325 ModuleData *next = NULL;
02326
02327 if (mod_current_module_name == NULL) {
02328 alog("moduleDelAllData() called with mod_current_module_name being NULL");
02329 if (debug)
02330 do_backtrace(0);
02331 }
02332
02333 while (current) {
02334 next = current->next;
02335 if ((stricmp(current->moduleName, mod_name) == 0)) {
02336 if (prev) {
02337 prev->next = current->next;
02338 } else {
02339 *md = current->next;
02340 }
02341 free(current->moduleName);
02342 free(current->key);
02343 free(current->value);
02344 current->next = NULL;
02345 free(current);
02346 } else {
02347 prev = current;
02348 }
02349 current = next;
02350 }
02351 free(mod_name);
02352 }
02353
02358 void moduleDelAllDataMod(Module * m)
02359 {
02360 boolean freeme = false;
02361 int i, j;
02362 User *user;
02363 NickAlias *na;
02364 NickCore *nc;
02365 ChannelInfo *ci;
02366
02367 if (!mod_current_module_name) {
02368 mod_current_module_name = sstrdup(m->name);
02369 freeme = true;
02370 }
02371
02372 for (i = 0; i < 1024; i++) {
02373
02374 for (user = userlist[i]; user; user = user->next) {
02375 moduleDelAllData(&user->moduleData);
02376 }
02377
02378 for (nc = nclists[i]; nc; nc = nc->next) {
02379 moduleDelAllData(&nc->moduleData);
02380
02381 for (j = 0; j < nc->memos.memocount; j++) {
02382 moduleCleanStruct(&nc->memos.memos[j].moduleData);
02383 }
02384 }
02385
02386 for (na = nalists[i]; na; na = na->next) {
02387 moduleDelAllData(&na->moduleData);
02388 }
02389 }
02390
02391 for (i = 0; i < 256; i++) {
02392
02393 for (ci = chanlists[i]; ci; ci = ci->next) {
02394 moduleDelAllData(&ci->moduleData);
02395
02396 for (j = 0; j < ci->memos.memocount; j++) {
02397 moduleCleanStruct(&ci->memos.memos[j].moduleData);
02398 }
02399 }
02400 }
02401
02402 if (freeme) {
02403 free(mod_current_module_name);
02404 mod_current_module_name = NULL;
02405 }
02406 }
02407
02413 void moduleCleanStruct(ModuleData ** moduleData)
02414 {
02415 ModuleData *current = *moduleData;
02416 ModuleData *next = NULL;
02417
02418 while (current) {
02419 next = current->next;
02420 free(current->moduleName);
02421 free(current->key);
02422 free(current->value);
02423 current->next = NULL;
02424 free(current);
02425 current = next;
02426 }
02427 *moduleData = NULL;
02428 }
02429
02439 boolean moduleMinVersion(int major, int minor, int patch, int build)
02440 {
02441 boolean ret = false;
02442 if (VERSION_MAJOR > major) {
02443 ret = true;
02444 } else if (VERSION_MAJOR == major) {
02445 if (minor == -1) {
02446 return true;
02447 }
02448 if (VERSION_MINOR > minor) {
02449 ret = true;
02450 } else if (VERSION_MINOR == minor) {
02451 if (patch == -1) {
02452 return true;
02453 }
02454 if (VERSION_PATCH > patch) {
02455 ret = true;
02456 } else if (VERSION_PATCH == patch) {
02457 if (build == -1) {
02458 return true;
02459 }
02460 if (VERSION_BUILD >= build) {
02461 ret = true;
02462 }
02463 }
02464 }
02465 }
02466 return ret;
02467 }
02468
02469 #ifdef _WIN32
02470 const char *ano_moderr(void)
02471 {
02472 static char errbuf[513];
02473 DWORD err = GetLastError();
02474 if (err == 0)
02475 return NULL;
02476 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
02477 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, errbuf, 512,
02478 NULL);
02479 return errbuf;
02480 }
02481 #endif
02482
02486 void updateProtectDetails(char *level_info_protect_word,
02487 char *level_info_protectme_word,
02488 char *fant_protect_add, char *fant_protect_del,
02489 char *level_protect_word, char *protect_set_mode,
02490 char *protect_unset_mode)
02491 {
02492 int i = 0;
02493 CSModeUtil ptr;
02494 LevelInfo l_ptr;
02495
02496 ptr = csmodeutils[i];
02497 while (ptr.name) {
02498 if (strcmp(ptr.name, "PROTECT") == 0) {
02499 csmodeutils[i].bsname = sstrdup(fant_protect_add);
02500 csmodeutils[i].mode = sstrdup(protect_set_mode);
02501 } else if (strcmp(ptr.name, "DEPROTECT") == 0) {
02502 csmodeutils[i].bsname = sstrdup(fant_protect_del);
02503 csmodeutils[i].mode = sstrdup(protect_unset_mode);
02504 }
02505 ptr = csmodeutils[++i];
02506 }
02507
02508 i = 0;
02509 l_ptr = levelinfo[i];
02510 while (l_ptr.what != -1) {
02511 if (l_ptr.what == CA_PROTECT) {
02512 levelinfo[i].name = sstrdup(level_info_protect_word);
02513 } else if (l_ptr.what == CA_PROTECTME) {
02514 levelinfo[i].name = sstrdup(level_info_protectme_word);
02515 } else if (l_ptr.what == CA_AUTOPROTECT) {
02516 levelinfo[i].name = sstrdup(level_protect_word);
02517 }
02518 l_ptr = levelinfo[++i];
02519 }
02520 }
02521
02527 int moduleGetConfigDirective(Directive * d)
02528 {
02529 FILE *config;
02530 char *dir = NULL;
02531 char buf[1024];
02532 char *directive;
02533 int linenum = 0;
02534 int ac = 0;
02535 char *av[MAXPARAMS];
02536 char *str = NULL;
02537 char *s = NULL;
02538 char *t = NULL;
02539 int retval = 1;
02540
02541 config = fopen(SERVICES_CONF, "r");
02542 if (!config) {
02543 alog("Can't open %s", SERVICES_CONF);
02544 return 0;
02545 }
02546 while (fgets(buf, sizeof(buf), config)) {
02547 linenum++;
02548 if (*buf == '#' || *buf == '\r' || *buf == '\n') {
02549 continue;
02550 }
02551 dir = myStrGetOnlyToken(buf, '\t', 0);
02552 if (dir) {
02553 str = myStrGetTokenRemainder(buf, '\t', 1);
02554 } else {
02555 dir = myStrGetOnlyToken(buf, ' ', 0);
02556 if (dir || (dir = myStrGetOnlyToken(buf, '\n', 0))) {
02557 str = myStrGetTokenRemainder(buf, ' ', 1);
02558 } else {
02559 continue;
02560 }
02561 }
02562 if (dir) {
02563 directive = normalizeBuffer(dir);
02564 } else {
02565 continue;
02566 }
02567
02568 if (stricmp(directive, d->name) == 0) {
02569 if (str) {
02570 s = str;
02571 while (isspace(*s))
02572 s++;
02573 while (*s) {
02574 if (ac >= MAXPARAMS) {
02575 alog("module error: too many config. params");
02576 break;
02577 }
02578 t = s;
02579 if (*s == '"') {
02580 t++;
02581 s++;
02582 while (*s && *s != '"') {
02583 if (*s == '\\' && s[1] != 0)
02584 s++;
02585 s++;
02586 }
02587 if (!*s)
02588 alog("module error: Warning: unterminated double-quoted string");
02589 else
02590 *s++ = 0;
02591 } else {
02592 s += strcspn(s, " \t\r\n");
02593 if (*s)
02594 *s++ = 0;
02595 }
02596 av[ac++] = t;
02597 while (isspace(*s))
02598 s++;
02599 }
02600 }
02601 retval = parse_directive(d, directive, ac, av, linenum, 0, s);
02602 }
02603 if (directive) {
02604 free(directive);
02605 }
02606 }
02607 if (dir)
02608 free(dir);
02609 if (str)
02610 free(str);
02611 fclose(config);
02612 return retval;
02613 }
02614
02621 void moduleInsertLanguage(int langNumber, int ac, char **av)
02622 {
02623 int i;
02624
02625 if ((mod_current_module_name) && (!mod_current_module || strcmp(mod_current_module_name, mod_current_module->name))) {
02626 mod_current_module = findModule(mod_current_module_name);
02627 }
02628
02629 if (debug)
02630 alog("debug: %s Adding %d texts for language %d", mod_current_module->name, ac, langNumber);
02631
02632 if (mod_current_module->lang[langNumber].argc > 0) {
02633 moduleDeleteLanguage(langNumber);
02634 }
02635
02636 mod_current_module->lang[langNumber].argc = ac;
02637 mod_current_module->lang[langNumber].argv =
02638 malloc(sizeof(char *) * ac);
02639 for (i = 0; i < ac; i++) {
02640 mod_current_module->lang[langNumber].argv[i] = sstrdup(av[i]);
02641 }
02642 }
02643
02651 void moduleNoticeLang(char *source, User * u, int number, ...)
02652 {
02653 va_list va;
02654 char buffer[4096], outbuf[4096];
02655 char *fmt = NULL;
02656 int lang = NSDefLanguage;
02657 char *s, *t, *buf;
02658
02659 if ((mod_current_module_name) && (!mod_current_module || strcmp(mod_current_module_name, mod_current_module->name))) {
02660 mod_current_module = findModule(mod_current_module_name);
02661 }
02662
02663
02664 if (u && u->na && u->na->nc) {
02665 lang = u->na->nc->language;
02666 }
02667
02668
02669 if (mod_current_module->lang[lang].argc == 0) {
02670 lang = LANG_EN_US;
02671 }
02672
02673
02674 if (mod_current_module->lang[lang].argc > number) {
02675 fmt = mod_current_module->lang[lang].argv[number];
02676
02677 buf = sstrdup(fmt);
02678 va_start(va, number);
02679 vsnprintf(buffer, 4095, buf, va);
02680 va_end(va);
02681 s = buffer;
02682 while (*s) {
02683 t = s;
02684 s += strcspn(s, "\n");
02685 if (*s)
02686 *s++ = '\0';
02687 strscpy(outbuf, t, sizeof(outbuf));
02688 notice_user(source, u, "%s", outbuf);
02689 }
02690 free(buf);
02691 } else {
02692 alog("%s: INVALID language string call, language: [%d], String [%d]", mod_current_module->name, lang, number);
02693 }
02694 }
02695
02702 char *moduleGetLangString(User * u, int number)
02703 {
02704 int lang = NSDefLanguage;
02705
02706 if ((mod_current_module_name) && (!mod_current_module || strcmp(mod_current_module_name, mod_current_module->name)))
02707 mod_current_module = findModule(mod_current_module_name);
02708
02709
02710 if (u && u->na && u->na->nc)
02711 lang = u->na->nc->language;
02712
02713
02714 if (mod_current_module->lang[lang].argc == 0)
02715 lang = LANG_EN_US;
02716
02717
02718 if (mod_current_module->lang[lang].argc > number) {
02719 return mod_current_module->lang[lang].argv[number];
02720
02721
02722
02723
02724 } else {
02725 alog("%s: INVALID language string call, language: [%d], String [%d]", mod_current_module->name, lang, number);
02726 return "";
02727 }
02728 }
02729
02734 void moduleDeleteLanguage(int langNumber)
02735 {
02736 int idx = 0;
02737 if ((mod_current_module_name) && (!mod_current_module || strcmp(mod_current_module_name, mod_current_module->name))) {
02738 mod_current_module = findModule(mod_current_module_name);
02739 }
02740 for (idx = 0; idx > mod_current_module->lang[langNumber].argc; idx++) {
02741 free(mod_current_module->lang[langNumber].argv[idx]);
02742 }
02743 mod_current_module->lang[langNumber].argc = 0;
02744 }
02745
02752 void queueModuleOperation(Module *m, ModuleOperation op, User *u)
02753 {
02754 ModuleQueue *qm;
02755
02756 qm = scalloc(1, sizeof(ModuleQueue));
02757 qm->m = m;
02758 qm->op = op;
02759 qm->u = u;
02760 qm->next = mod_operation_queue;
02761 mod_operation_queue = qm;
02762 }
02763
02770 int queueModuleLoad(char *name, User *u)
02771 {
02772 Module *m;
02773
02774 if (!name || !u)
02775 return 0;
02776
02777 if (findModule(name))
02778 return 0;
02779 m = createModule(name);
02780 queueModuleOperation(m, MOD_OP_LOAD, u);
02781
02782 return 1;
02783 }
02784
02791 int queueModuleUnload(char *name, User *u)
02792 {
02793 Module *m;
02794
02795 if (!name || !u)
02796 return 0;
02797
02798 m = findModule(name);
02799 if (!m)
02800 return 0;
02801 queueModuleOperation(m, MOD_OP_UNLOAD, u);
02802
02803 return 1;
02804 }
02805
02809 void handleModuleOperationQueue(void)
02810 {
02811 ModuleQueue *next;
02812 int status;
02813
02814 if (!mod_operation_queue)
02815 return;
02816
02817 while (mod_operation_queue) {
02818 next = mod_operation_queue->next;
02819
02820 mod_current_module = mod_operation_queue->m;
02821 mod_current_user = mod_operation_queue->u;
02822
02823 if (mod_operation_queue->op == MOD_OP_LOAD) {
02824 alog("Trying to load module [%s]", mod_operation_queue->m->name);
02825 status = loadModule(mod_operation_queue->m, mod_operation_queue->u);
02826 alog("Module loading status: %d (%s)", status, ModuleGetErrStr(status));
02827 if (status != MOD_ERR_OK) {
02828 if(mod_current_user) {
02829 notice_lang(s_OperServ, mod_current_user, OPER_MODULE_LOAD_FAIL,mod_operation_queue->m->name);
02830 }
02831 destroyModule(mod_operation_queue->m);
02832 }
02833 } else if (mod_operation_queue->op == MOD_OP_UNLOAD) {
02834 alog("Trying to unload module [%s]", mod_operation_queue->m->name);
02835 status = unloadModule(mod_operation_queue->m, mod_operation_queue->u);
02836 alog("Module unloading status: %d (%s)", status, ModuleGetErrStr(status));
02837 }
02838
02839
02840 free(mod_operation_queue);
02841
02842 mod_operation_queue = next;
02843 }
02844
02845 mod_current_module = NULL;
02846 mod_current_user = NULL;
02847 }
02848
02849 void ModuleRunTimeDirCleanUp(void)
02850 {
02851 #ifndef _WIN32
02852 DIR *dirp;
02853 struct dirent *dp;
02854 #else
02855 BOOL fFinished;
02856 HANDLE hList;
02857 TCHAR szDir[MAX_PATH + 1];
02858 TCHAR szSubDir[MAX_PATH + 1];
02859 WIN32_FIND_DATA FileData;
02860 char buffer[_MAX_PATH];
02861 #endif
02862 char dirbuf[BUFSIZE];
02863 char filebuf[BUFSIZE];
02864
02865
02866 #ifndef _WIN32
02867 snprintf(dirbuf, BUFSIZE, "%s/modules/runtime", services_dir);
02868 #else
02869 snprintf(dirbuf, BUFSIZE, "\\%s", "modules/runtime");
02870 #endif
02871
02872 if (debug) {
02873 alog("debug: Cleaning out Module run time directory (%s) - this may take a moment please wait", dirbuf);
02874 }
02875
02876 #ifndef _WIN32
02877 if ((dirp = opendir(dirbuf)) == NULL) {
02878 if (debug) {
02879 alog("debug: cannot open directory (%s)", dirbuf);
02880 }
02881 return;
02882 }
02883 while ((dp = readdir(dirp)) != NULL) {
02884 if (dp->d_ino == 0) {
02885 continue;
02886 }
02887 if (!stricmp(dp->d_name, ".") || !stricmp(dp->d_name, "..")) {
02888 continue;
02889 }
02890 snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, dp->d_name);
02891 unlink(filebuf);
02892 }
02893 closedir(dirp);
02894 #else
02895
02896 if (_getcwd(buffer, _MAX_PATH) == NULL) {
02897 if (debug) {
02898 alog("debug: Unable to set Current working directory");
02899 }
02900 }
02901 snprintf(szDir, sizeof(szDir), "%s\\%s\\*", buffer, dirbuf);
02902
02903 hList = FindFirstFile(szDir, &FileData);
02904 if (hList != INVALID_HANDLE_VALUE) {
02905 fFinished = FALSE;
02906 while (!fFinished) {
02907 if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
02908 snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, FileData.cFileName);
02909 DeleteFile(filebuf);
02910 }
02911 if (!FindNextFile(hList, &FileData)) {
02912 if (GetLastError() == ERROR_NO_MORE_FILES) {
02913 fFinished = TRUE;
02914 }
02915 }
02916 }
02917 } else {
02918 if (debug) {
02919 alog("debug: Invalid File Handle. GetLastError reports %d\n", GetLastError());
02920 }
02921 }
02922 FindClose(hList);
02923 #endif
02924 if (debug) {
02925 alog("debug: Module run time directory has been cleaned out");
02926 }
02927 }
02928
02929