-/* modules.c - NeonServ v5.3
+/* modules.c - NeonServ v5.5
* Copyright (C) 2011-2012 Philipp Kreil (pk910)
*
* This program is free software: you can redistribute it and/or modify
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "modules.h"
+#ifndef WIN32
+#include <dlfcn.h>
+#endif
/* 000-011 */ #include "main.h"
/* 012 */ #include "BanNode.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"
+/* 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 */
-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,
+#define Function void *
+
+void *global_functions[] = {
+/* 000 */ (Function) getStartTime,
+/* 001 */ (Function) getRunningThreads,
+/* 002 */ (Function) exit_daemon,
+/* 003 */ (Function) stricmp,
+/* 004 */ (Function) stricmplen,
+/* 005 */ (Function) restart_process,
+/* 006 */ (Function) cleanup,
+/* 007 */ (Function) restart_bot,
+/* 008 */ (Function) stop_bot,
+/* 009 */ (Function) reload_config,
+/* 010 */ (Function) putlog,
#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
};
-#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) {
+ putlog(LOGLEVEL_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;
+ putlog(LOGLEVEL_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) {
+ putlog(LOGLEVEL_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;
+ putlog(LOGLEVEL_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;
+ putlog(LOGLEVEL_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
}
#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);
+ }
}
}
unregister_module_hooks(modinfo->module_id);
((void (*)(int)) modinfo->stopfunc)(MODSTATE_STARTSTOP);
closemodule(modinfo->module);
+ free_module_functions(modinfo);
free(modinfo->name);
free(modinfo);
}
unregister_module_commands(module_id);
unregister_module_events(module_id);
unregister_module_timers(module_id);
+
}
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;
+}
+
+