X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=blobdiff_plain;f=src%2Fmodules.c;h=f48c41a0b2b0eda7a55987eda7522398057f807f;hp=0c2034e3bfdf9032ae79e346a844d8302b0473bb;hb=HEAD;hpb=706e48b1e666054030c491d864f740071e390038 diff --git a/src/modules.c b/src/modules.c index 0c2034e..f48c41a 100644 --- a/src/modules.c +++ b/src/modules.c @@ -1,4 +1,4 @@ -/* modules.c - NeonServ v5.3 +/* modules.c - NeonServ v5.6 * Copyright (C) 2011-2012 Philipp Kreil (pk910) * * This program is free software: you can redistribute it and/or modify @@ -15,8 +15,18 @@ * along with this program. If not, see . */ #include "modules.h" +#ifndef WIN32 +#include +#endif -/* 000-011 */ #include "main.h" +/* 000-001 */ #include "main.h" +/* 002-004 */ #include "tools.h" +#ifdef ENABLE_MUTEX_DEBUG +/* 005-006 */ #include "mutexDebug.h" +#endif +/* 007-009 */ /* main.h */ +/* 010 */ #include "log.h" +/* 011 */ /* main.h */ /* 012 */ #include "BanNode.h" /* 013-019 */ #include "bots.h" /* 020-025 */ #include "ChanNode.h" @@ -33,295 +43,336 @@ /* 099-102 */ #include "memoryDebug.h" #endif /* 103-106 */ #include "memoryInfo.h" -/* 107-125 */ #include "modcmd.h" +/* 107-122 */ #include "modcmd.h" +/* 123 */ /* deprecated */ +/* 124-125 */ /* modcmd.h */ /* 126-136 */ #include "ModeNode.h" /* 137-142 */ #include "mysqlConn.h" /* 143-149 */ #include "timeq.h" -/* 150-169 */ #include "tools.h" -/* 170-178 */ #include "UserNode.h" -/* 179 */ #include "version.h" -/* 180-182 */ #include "WHOHandler.h" +/* 150-169 */ /* tools.h */ +/* 170-180 */ #include "UserNode.h" +/* 181-183 */ #include "WHOHandler.h" +/* 184-188 */ #include "version.h" +/* 189 */ /* modules.h */ +/* 190 */ /* UserNode.h */ +/* 191-193 */ #include "ModuleFunctions.h" +/* 194 */ /* bots.h */ +/* 195-196 */ /* version.h */ +/* 197-198 */ /* IRCEvents.h */ + +#define Function void * -void **global_functions = { -/* 000 */ getStartTime, -/* 001 */ getRunningThreads, -/* 002 */ exit_daemon, -/* 003 */ stricmp, -/* 004 */ stricmplen, -/* 005 */ restart_process, -/* 006 */ cleanup, -/* 007 */ restart_bot, -/* 008 */ stop_bot, -/* 009 */ reload_config, -/* 010 */ putlog, +void *global_functions[] = { +/* 000 */ (Function) getStartTime, +/* 001 */ (Function) getRunningThreads, +/* 002 */ (Function) getCurrentSecondsOfDay, +/* 003 */ (Function) stricmp, +/* 004 */ (Function) stricmplen, +#ifdef ENABLE_MUTEX_DEBUG +/* 005 */ (Function) xmutex, +/* 006 */ (Function) mutex_debug, +#else +/* 005 */ (Function) NULL, +/* 006 */ (Function) NULL, +#endif +/* 007 */ (Function) restart_bot, +/* 008 */ (Function) stop_bot, +/* 009 */ (Function) reload_config, +/* 010 */ (Function) printf_log, #ifdef HAVE_THREADS -/* 011 */ getCurrentThreadID, +/* 011 */ (Function) getCurrentThreadID, #else -/* 011 */ NULL, +/* 011 */ (Function) NULL, #endif -/* 012 */ getMatchingChannelBan, -/* 013 */ getChannelBot, -/* 014 */ requestOp, -/* 015 */ channel_ban_timeout, -/* 016 */ general_event_privctcp, -/* 017 */ set_bot_alias, -/* 018 */ resolve_botid, -/* 019 */ resolve_botalias, -/* 020 */ is_valid_chan, -/* 021 */ getAllChans, -/* 022 */ getChanByName, -/* 023 */ getChannelCount, -/* 024 */ getChanUserCount, -/* 025 */ getChanBanCount, -/* 026 */ isUserOnChan, -/* 027 */ getChanUser, -/* 028 */ getChannelUsers, -/* 029 */ getUserChannels, -/* 030 */ create_socket, -/* 031 */ connect_socket, -/* 032 */ close_socket, -/* 033 */ disconnect_socket, -/* 034 */ write_socket, -/* 035 */ putsock, -/* 036 */ getBots, -/* 037 */ get_int_field, -/* 038 */ get_string_field, -/* 039 */ _loadUserSettings, -/* 040 */ isGodMode, -/* 041 */ getChanDefault, -/* 042 */ getChannelAccess, -/* 043 */ checkChannelAccess, -/* 044 */ _loadChannelSettings, -/* 045 */ isUserProtected, -/* 046 */ getBanAffectingMask, -/* 047 */ renameAccount, -/* 048 */ deleteUser, -/* 049 */ logEvent, -/* 050 */ lookup_authname, -/* 051 */ bind_join, -/* 052 */ unbind_join, -/* 053 */ bind_nick, -/* 054 */ unbind_nick, -/* 055 */ bind_part, -/* 056 */ unbind_part, -/* 057 */ bind_quit, -/* 058 */ unbind_quit, -/* 059 */ bind_kick, -/* 060 */ unbind_kick, -/* 061 */ bind_topic, -/* 062 */ unbind_topic, -/* 063 */ bind_mode, -/* 064 */ unbind_mode, -/* 065 */ bind_chanmsg, -/* 066 */ unbind_chanmsg, -/* 067 */ bind_privmsg, -/* 068 */ unbind_privmsg, -/* 069 */ bind_channotice, -/* 070 */ unbind_channotice, -/* 071 */ bind_privnotice, -/* 072 */ unbind_privnotice, -/* 073 */ bind_chanctcp, -/* 074 */ unbind_chanctcp, -/* 075 */ bind_privctcp, -/* 076 */ unbind_privctcp, -/* 077 */ bind_invite, -/* 078 */ unbind_invite, -/* 079 */ bind_raw, -/* 080 */ unbind_raw, -/* 081 */ bind_bot_ready, -/* 082 */ unbind_bot_ready, -/* 083 */ bind_registered, -/* 084 */ unbind_registered, -/* 085 */ bind_freeuser, -/* 086 */ unbind_freeuser, -/* 087 */ bind_freechan, -/* 088 */ unbind_freechan, -/* 089 */ reply, -/* 090 */ merge_argv, -/* 091 */ merge_argv_char, -/* 092 */ get_language_by_tag, -/* 093 */ get_language_by_name, -/* 094 */ get_default_language, -/* 095 */ load_language, -/* 096 */ register_default_language_table, -/* 097 */ get_language_string, -/* 098 */ build_language_string, +/* 012 */ (Function) getMatchingChannelBan, +/* 013 */ (Function) getChannelBot, +/* 014 */ (Function) requestOp, +/* 015 */ (Function) channel_ban_timeout, +/* 016 */ (Function) general_event_privctcp, +/* 017 */ (Function) set_bot_alias, +/* 018 */ (Function) resolve_botid, +/* 019 */ (Function) resolve_botalias, +/* 020 */ (Function) is_valid_chan, +/* 021 */ (Function) getAllChans, +/* 022 */ (Function) getChanByName, +/* 023 */ (Function) getChannelCount, +/* 024 */ (Function) getChanUserCount, +/* 025 */ (Function) getChanBanCount, +/* 026 */ (Function) isUserOnChan, +/* 027 */ (Function) getChanUser, +/* 028 */ (Function) getChannelUsers, +/* 029 */ (Function) getUserChannels, +/* 030 */ (Function) create_socket, +/* 031 */ (Function) connect_socket, +/* 032 */ (Function) close_socket, +/* 033 */ (Function) destroy_socket, +/* 034 */ (Function) write_socket, +/* 035 */ (Function) putsock, +/* 036 */ (Function) getBots, +/* 037 */ (Function) get_int_field, +/* 038 */ (Function) get_string_field, +/* 039 */ (Function) _loadUserSettings, +/* 040 */ (Function) isGodMode, +/* 041 */ (Function) getChanDefault, +/* 042 */ (Function) getChannelAccess, +/* 043 */ (Function) checkChannelAccess, +/* 044 */ (Function) _loadChannelSettings, +/* 045 */ (Function) isUserProtected, +/* 046 */ (Function) getBanAffectingMask, +/* 047 */ (Function) renameAccount, +/* 048 */ (Function) deleteUser, +/* 049 */ (Function) logEvent, +/* 050 */ (Function) lookup_authname, +/* 051 */ (Function) bind_join, +/* 052 */ (Function) unbind_join, +/* 053 */ (Function) bind_nick, +/* 054 */ (Function) unbind_nick, +/* 055 */ (Function) bind_part, +/* 056 */ (Function) unbind_part, +/* 057 */ (Function) bind_reload, +/* 058 */ (Function) unbind_reload, +/* 059 */ (Function) bind_kick, +/* 060 */ (Function) unbind_kick, +/* 061 */ (Function) bind_topic, +/* 062 */ (Function) unbind_topic, +/* 063 */ (Function) bind_mode, +/* 064 */ (Function) unbind_mode, +/* 065 */ (Function) bind_chanmsg, +/* 066 */ (Function) unbind_chanmsg, +/* 067 */ (Function) bind_privmsg, +/* 068 */ (Function) unbind_privmsg, +/* 069 */ (Function) bind_channotice, +/* 070 */ (Function) unbind_channotice, +/* 071 */ (Function) bind_privnotice, +/* 072 */ (Function) unbind_privnotice, +/* 073 */ (Function) bind_chanctcp, +/* 074 */ (Function) unbind_chanctcp, +/* 075 */ (Function) bind_privctcp, +/* 076 */ (Function) unbind_privctcp, +/* 077 */ (Function) bind_invite, +/* 078 */ (Function) unbind_invite, +/* 079 */ (Function) bind_raw, +/* 080 */ (Function) unbind_raw, +/* 081 */ (Function) bind_bot_ready, +/* 082 */ (Function) unbind_bot_ready, +/* 083 */ (Function) bind_registered, +/* 084 */ (Function) unbind_registered, +/* 085 */ (Function) bind_freeuser, +/* 086 */ (Function) unbind_freeuser, +/* 087 */ (Function) bind_freechan, +/* 088 */ (Function) unbind_freechan, +/* 089 */ (Function) reply, +/* 090 */ (Function) merge_argv, +/* 091 */ (Function) merge_argv_char, +/* 092 */ (Function) get_language_by_tag, +/* 093 */ (Function) get_language_by_name, +/* 094 */ (Function) get_default_language, +/* 095 */ (Function) load_language, +/* 096 */ (Function) register_default_language_table, +/* 097 */ (Function) get_language_string, +/* 098 */ (Function) build_language_string, #ifdef ENABLE_MEMORY_DEBUG -/* 099 */ xmalloc, -/* 100 */ xcalloc, -/* 101 */ xstrdup, -/* 102 */ xfree, +/* 099 */ (Function) xmalloc, +/* 100 */ (Function) xcalloc, +/* 101 */ (Function) xstrdup, +/* 102 */ (Function) xfree, #else -/* 099 */ NULL, -/* 100 */ NULL, -/* 101 */ NULL, -/* 102 */ NULL, +/* 099 */ (Function) NULL, +/* 100 */ (Function) NULL, +/* 101 */ (Function) NULL, +/* 102 */ (Function) NULL, #endif -/* 103 */ getMemoryInfoFiles, -/* 104 */ freeMemoryInfoFiles, -/* 105 */ getMemoryInfoLines, -/* 106 */ freeMemoryInfoLines, -/* 107 */ get_botwise_prefered_bot, -/* 108 */ register_command, -/* 109 */ set_trigger_callback, -/* 110 */ flush_trigger_cache, -/* 111 */ changeBotwiseChannelTrigger, -/* 112 */ bind_botwise_cmd_to_function, -/* 113 */ bind_botwise_cmd_to_command, -/* 114 */ unbind_botwise_cmd, -/* 115 */ unbind_botwise_allcmd, -/* 116 */ bind_botwise_set_parameters, -/* 117 */ bind_botwise_set_global_access, -/* 118 */ bind_botwise_set_channel_access, -/* 119 */ bind_botwise_set_bind_flags, -/* 120 */ find_botwise_cmd_binding, -/* 121 */ bind_botwise_unbound_required_functions, -/* 122 */ find_cmd_function, -/* 123 */ getTextBot, -/* 124 */ register_command_alias, -/* 125 */ getAllBinds, -/* 126 */ createModeNode, -/* 127 */ freeModeNode, -/* 128 */ isModeSet, -/* 129 */ isModeAffected, -/* 130 */ getModeValue, -/* 131 */ getModeType, -/* 132 */ parseModes, -/* 133 */ parseModeString, -/* 134 */ parseMode, -/* 135 */ getModeString, -/* 136 */ getFullModeString, -/* 137 */ mysql_use, -/* 138 */ mysql_free, -/* 139 */ printf_mysql_query, -/* 140 */ printf_long_mysql_query, -/* 141 */ escape_string, -/* 142 */ get_mysql_conn, -/* 143 */ timeq_add, -/* 144 */ timeq_uadd, -/* 145 */ timeq_add_name, -/* 146 */ timeq_uadd_name, -/* 147 */ timeq_del, -/* 148 */ timeq_del_name, -/* 149 */ timeq_name_exists, -/* 150 */ match, -/* 151 */ table_init, -/* 152 */ table_add, -/* 153 */ table_change, -/* 154 */ table_change_field, -/* 155 */ table_set_bold, -/* 156 */ table_end, -/* 157 */ table_free, -/* 158 */ timeToStr, -/* 159 */ strToTime, -/* 160 */ initModeBuffer, -/* 161 */ modeBufferSet, -/* 162 */ flushModeBuffer, -/* 163 */ freeModeBuffer, -/* 164 */ is_ircmask, -/* 165 */ generate_banmask, -/* 166 */ make_banmask, -/* 167 */ isFakeHost, -/* 168 */ mask_match, -/* 169 */ crc32, -/* 170 */ is_valid_nick, -/* 171 */ getUserByNick, -/* 172 */ getUserByMask, -/* 173 */ countUsersWithHost, -/* 174 */ getAuthFakehost, -/* 175 */ searchUserByNick, -/* 176 */ getAllUsers, -/* 177 */ getUsersWithAuth, -/* 178 */ getUserCount, -/* 179 */ get_userlist, -/* 180 */ _get_userlist_with_invisible, -/* 181 */ get_userauth, -/* 182 */ &compilation, -/* 183 */ &creation, -/* 184 */ &revision, -/* 185 */ &codelines, -/* 186 */ &patchlevel +/* 103 */ (Function) getMemoryInfoFiles, +/* 104 */ (Function) freeMemoryInfoFiles, +/* 105 */ (Function) getMemoryInfoLines, +/* 106 */ (Function) freeMemoryInfoLines, +/* 107 */ (Function) get_botwise_prefered_bot, +/* 108 */ (Function) register_command, +/* 109 */ (Function) set_trigger_callback, +/* 110 */ (Function) flush_trigger_cache, +/* 111 */ (Function) changeBotwiseChannelTrigger, +/* 112 */ (Function) bind_botwise_cmd_to_function, +/* 113 */ (Function) bind_botwise_cmd_to_command, +/* 114 */ (Function) unbind_botwise_cmd, +/* 115 */ (Function) unbind_botwise_allcmd, +/* 116 */ (Function) bind_botwise_set_parameters, +/* 117 */ (Function) bind_botwise_set_global_access, +/* 118 */ (Function) bind_botwise_set_channel_access, +/* 119 */ (Function) bind_botwise_set_bind_flags, +/* 120 */ (Function) find_botwise_cmd_binding, +/* 121 */ (Function) bind_botwise_unbound_required_functions, +/* 122 */ (Function) find_cmd_function, +/* 123 */ (Function) NULL, /* deprecated */ +/* 124 */ (Function) register_command_alias, +/* 125 */ (Function) getAllBinds, +/* 126 */ (Function) createModeNode, +/* 127 */ (Function) freeModeNode, +/* 128 */ (Function) isModeSet, +/* 129 */ (Function) isModeAffected, +/* 130 */ (Function) getModeValue, +/* 131 */ (Function) getModeType, +/* 132 */ (Function) parseModes, +/* 133 */ (Function) parseModeString, +/* 134 */ (Function) parseMode, +/* 135 */ (Function) getModeString, +/* 136 */ (Function) getFullModeString, +/* 137 */ (Function) mysql_use, +/* 138 */ (Function) mysql_free, +/* 139 */ (Function) printf_mysql_query, +/* 140 */ (Function) printf_long_mysql_query, +/* 141 */ (Function) escape_string, +/* 142 */ (Function) get_mysql_conn, +/* 143 */ (Function) timeq_add, +/* 144 */ (Function) timeq_uadd, +/* 145 */ (Function) timeq_add_name, +/* 146 */ (Function) timeq_uadd_name, +/* 147 */ (Function) timeq_del, +/* 148 */ (Function) timeq_del_name, +/* 149 */ (Function) timeq_name_exists, +/* 150 */ (Function) match, +/* 151 */ (Function) table_init, +/* 152 */ (Function) table_add, +/* 153 */ (Function) table_change, +/* 154 */ (Function) table_change_field, +/* 155 */ (Function) table_set_bold, +/* 156 */ (Function) table_end, +/* 157 */ (Function) table_free, +/* 158 */ (Function) timeToStr, +/* 159 */ (Function) strToTime, +/* 160 */ (Function) initModeBuffer, +/* 161 */ (Function) modeBufferSet, +/* 162 */ (Function) flushModeBuffer, +/* 163 */ (Function) freeModeBuffer, +/* 164 */ (Function) is_ircmask, +/* 165 */ (Function) generate_banmask, +/* 166 */ (Function) make_banmask, +/* 167 */ (Function) isFakeHost, +/* 168 */ (Function) mask_match, +/* 169 */ (Function) crc32, +/* 170 */ (Function) is_valid_nick, +/* 171 */ (Function) getUserByNick, +/* 172 */ (Function) getUserByMask, +/* 173 */ (Function) countUsersWithHost, +/* 174 */ (Function) getAuthFakehost, +/* 175 */ (Function) searchUserByNick, +/* 176 */ (Function) getAllUsers, +/* 177 */ (Function) getUsersWithAuth, +/* 178 */ (Function) getUserCount, +/* 179 */ (Function) createTempUser, +/* 180 */ (Function) createTempUserMask, +/* 181 */ (Function) get_userlist, +/* 182 */ (Function) _get_userlist_with_invisible, +/* 183 */ (Function) get_userauth, +/* 184 */ (Function) get_compilation, +/* 185 */ (Function) get_creation, +/* 186 */ (Function) get_revision, +/* 187 */ (Function) get_codelines, +/* 188 */ (Function) get_patchlevel, +/* 189 */ (Function) get_module_name, +/* 190 */ (Function) isUserModeSet, +/* 191 */ (Function) module_global_cmd_register_neonbackup, +/* 192 */ (Function) module_global_cmd_unregister_neonbackup, +/* 193 */ (Function) module_neonbackup_recover_chan, +/* 194 */ (Function) requestInvite, +/* 195 */ (Function) is_stable_revision, +/* 196 */ (Function) get_dev_revision, +/* 197 */ (Function) bind_freeclient, +/* 198 */ (Function) unbind_freeclient }; -#define MODINFO_STATE_STARTED 0x01 - -struct ModuleInfo { - char *name; - int module_id; - #ifndef WIN32 - void *module; - #else - HMODULE module; - #endif - int state; - void *startfunc; - void *loopfunc; - void *stopfunc; - struct ModuleInfo *next; -} - static int module_id_counter = 1; static struct ModuleInfo *modules = NULL; static void unregister_module_hooks(int module_id); -int loadModule(char *name) { +void loadModules() { + char **modulelist = get_all_fieldnames("modules"); + if(!modulelist) return; + int i = 0; + char tmp[MAXLEN]; + struct ModuleInfo *modinfo; + while(modulelist[i]) { + sprintf(tmp, "modules.%s.enabled", modulelist[i]); + if(get_int_field(tmp)) { + modinfo = loadModule(modulelist[i]); + sprintf(tmp, "modules.%s.protected", modulelist[i]); + if(get_int_field(tmp)) + modinfo->state |= MODINFO_STATE_PROTECTED; + } + i++; + } + free(modulelist); + start_modules(); +} + +struct ModuleInfo *loadModule(char *name) { + struct ModuleInfo *modinfo; + for(modinfo = modules; modinfo; modinfo = modinfo->next) { + if(!stricmp(modinfo->name, name)) return NULL; + } char fname[256]; #ifndef WIN32 sprintf(fname, "%s.so", name); void* module = dlopen(fname, RTLD_LAZY); if(!module) { - putlog(LOGLEVEL_ERROR, "Error loading module '%s': %s not found.", name, fname); - return 0; + sprintf(fname, "./%s.so", name); + module = dlopen(fname, RTLD_LAZY); + } + if(!module) { + sprintf(fname, ".libs/%s.so", name); + module = dlopen(fname, RTLD_LAZY); + } + if(!module) { + printf_log("main", LOG_ERROR, "Error loading module '%s': %s not found.\n", name, fname); + return NULL; } void* initfunc = dlsym(module, "init_module"); void* startfunc = dlsym(module, "start_module"); - void* loopfunc = dlsym(module, "loop_module"); void* stopfunc = dlsym(module, "stop_module"); void* modversion = dlsym(module, "modversion"); #else sprintf(fname, "%s.dll", name); HMODULE module = LoadLibrary(fname); if(!module) { - putlog(LOGLEVEL_ERROR, "Error loading module '%s': %s not found.", name, fname); - return 0; + printf_log("main", LOG_ERROR, "Error loading module '%s': %s not found.\n", name, fname); + return NULL; } FARPROC initfunc = GetProcAddress(module, "init_module"); FARPROC startfunc = GetProcAddress(module, "start_module"); - FARPROC loopfunc = GetProcAddress(module, "loop_module"); FARPROC stopfunc = GetProcAddress(module, "stop_module"); FARPROC modversion = GetProcAddress(module, "modversion"); #endif - if(!startfunc || !loopfunc || !stopfunc || !modversion) { - putlog(LOGLEVEL_ERROR, "Error loading module '%s': required symbols not found.", name); - return 0; + if(!startfunc || !stopfunc || !modversion) { + printf_log("main", LOG_ERROR, "Error loading module '%s': required symbols not found.\n", name); + return NULL; } int version = ((int (*)(void)) modversion)(); if(version != MODULE_VERSION) { - putlog(LOGLEVEL_ERROR, "Error loading module '%s': version mismatch ('%d' main code, '%d' module)", name, MODULE_VERSION, version); - return 0; + printf_log("main", LOG_ERROR, "Error loading module '%s': version mismatch ('%d' main code, '%d' module)\n", name, MODULE_VERSION, version); + return NULL; } //start module int errid; int module_id = module_id_counter++; if((errid = ((int (*)(void **, int)) initfunc)(global_functions, module_id))) { - putlog(LOGLEVEL_ERROR, "Error loading module '%s': module reported error (errid: %d)", name, errid); - return 0; + printf_log("main", LOG_ERROR, "Error loading module '%s': module reported error (errid: %d)\n", name, errid); + return NULL; } - struct ModuleInfo *modinfo = malloc(sizeof(*modinfo)); + modinfo = malloc(sizeof(*modinfo)); if(!modinfo) { unregister_module_hooks(module_id); - return 0; + return NULL; } modinfo->name = strdup(name); modinfo->module_id = module_id; modinfo->module = module; modinfo->startfunc = startfunc; - modinfo->loopfunc = loopfunc; modinfo->stopfunc = stopfunc; + modinfo->state = 0; modinfo->next = modules; modules = modinfo; - return 1; + scan_module(modinfo); + return modinfo; } #ifndef WIN32 @@ -334,46 +385,86 @@ static void closemodule(HMODULE module) { } #endif -int reload_module(char *name) { - struct ModuleInfo *old_modinfo, *old_prev = NULL; - for(old_modinfo = modules; old_modinfo; old_modinfo = old_modinfo->next) { - if(old_prev) - old_prev->next = old_modinfo->next; - else - modules = old_modinfo->next; - unregister_module_hooks(old_modinfo->module_id); - ((void (*)(void)) old_modinfo->stopfunc)(MODSTATE_RELOAD); - closemodule(old_modinfo->module); - free(old_modinfo->name); - free(old_modinfo); - break; - } else - old_prev = old_modinfo; +int ext_load_module(char *name) { if(!loadModule(name)) return 0; struct ModuleInfo *modinfo; for(modinfo = modules; modinfo; modinfo = modinfo->next) { if(!(modinfo->state & MODINFO_STATE_STARTED)) { modinfo->state |= MODINFO_STATE_STARTED; - ((void (*)(void)) modinfo->startfunc)(MODSTATE_STARTSTOP); + ((void (*)(int)) modinfo->startfunc)(MODSTATE_STARTSTOP); } else - ((void (*)(void)) modinfo->startfunc)(MODSTATE_REBIND); + ((void (*)(int)) modinfo->startfunc)(MODSTATE_REBIND); } + return 1; } -void start_modules() { +int ext_unload_module(char *name) { + struct ModuleInfo *old_modinfo, *old_prev = NULL; + for(old_modinfo = modules; old_modinfo; old_modinfo = old_modinfo->next) { + if(!stricmp(old_modinfo->name, name)) { + if(old_modinfo->state & MODINFO_STATE_PROTECTED) { + return 0; + } + if(old_prev) + old_prev->next = old_modinfo->next; + else + modules = old_modinfo->next; + unregister_module_hooks(old_modinfo->module_id); + ((void (*)(int)) old_modinfo->stopfunc)(MODSTATE_STARTSTOP); + closemodule(old_modinfo->module); + free_module_functions(old_modinfo); + free(old_modinfo->name); + free(old_modinfo); + return 1; + } else + old_prev = old_modinfo; + } + return 0; +} + +int ext_reload_module(char *name) { + char libname[256]; + struct ModuleInfo *old_modinfo, *old_prev = NULL; + for(old_modinfo = modules; old_modinfo; old_modinfo = old_modinfo->next) { + if(!stricmp(old_modinfo->name, name)) { + strcpy(libname, old_modinfo->name); + if(old_prev) + old_prev->next = old_modinfo->next; + else + modules = old_modinfo->next; + unregister_module_hooks(old_modinfo->module_id); + ((void (*)(int)) old_modinfo->stopfunc)(MODSTATE_RELOAD); + closemodule(old_modinfo->module); + free_module_functions(old_modinfo); + free(old_modinfo->name); + free(old_modinfo); + break; + } else + old_prev = old_modinfo; + } + if(!loadModule(libname)) return 0; struct ModuleInfo *modinfo; for(modinfo = modules; modinfo; modinfo = modinfo->next) { if(!(modinfo->state & MODINFO_STATE_STARTED)) { modinfo->state |= MODINFO_STATE_STARTED; - ((void (*)(void)) modinfo->startfunc)(MODSTATE_STARTSTOP); - } + ((void (*)(int)) modinfo->startfunc)(MODSTATE_RELOAD); + } else + ((void (*)(int)) modinfo->startfunc)(MODSTATE_REBIND); } + return 1; } -void loop_modules() { +struct ModuleInfo *ext_get_modules(struct ModuleInfo *last) { + return (last ? last->next : modules); +} + +void start_modules() { struct ModuleInfo *modinfo; for(modinfo = modules; modinfo; modinfo = modinfo->next) { - ((void (*)(void)) modinfo->loopfunc)(); + if(!(modinfo->state & MODINFO_STATE_STARTED)) { + modinfo->state |= MODINFO_STATE_STARTED; + ((void (*)(int)) modinfo->startfunc)(MODSTATE_STARTSTOP); + } } } @@ -384,6 +475,7 @@ void stop_modules() { unregister_module_hooks(modinfo->module_id); ((void (*)(int)) modinfo->stopfunc)(MODSTATE_STARTSTOP); closemodule(modinfo->module); + free_module_functions(modinfo); free(modinfo->name); free(modinfo); } @@ -394,6 +486,7 @@ static void unregister_module_hooks(int module_id) { unregister_module_commands(module_id); unregister_module_events(module_id); unregister_module_timers(module_id); + } int module_loaded(int module_id) { @@ -405,3 +498,15 @@ int module_loaded(int module_id) { } return 0; } + +char *get_module_name(int module_id) { + if(!module_id) return NULL; + struct ModuleInfo *modinfo; + for(modinfo = modules; modinfo; modinfo = modinfo->next) { + if(modinfo->module_id == module_id) + return modinfo->name; + } + return NULL; +} + +