diff --git a/Changes b/Changes index 0dcc5552b..51116a8ea 100644 --- a/Changes +++ b/Changes @@ -1117,3 +1117,5 @@ v- Fixed some bugreport stuff event the IRCd will not crash. Also fixed a crash involving delayed unloads and cleaned up notices - Problem with sendto_ops and !aClient->user fix - Fixed bug in m_tkl_line and various m_line functions (was checking for wrong # of paras) +- Recoded hooks to take advantage of the module object code +- Fixed a memory leak in hooks diff --git a/include/modules.h b/include/modules.h index fba96e593..75aa2d6ae 100644 --- a/include/modules.h +++ b/include/modules.h @@ -50,6 +50,7 @@ typedef char (*cFP)(); /* char * function pointer */ typedef struct _mod_symboltable Mod_SymbolDepTable; typedef struct _event Event; typedef struct _eventinfo EventInfo; +typedef struct _irchook Hook; /* * Module header that every module must include, with the name of @@ -89,6 +90,16 @@ typedef struct _ModuleObject { } object; } ModuleObject; +struct _irchook { + Hook *prev, *next; + short type; + union { + int (*intfunc)(); + void (*voidfunc)(); + } func; + Module *owner; +}; + /* * What we use to keep track internally of the modules */ @@ -178,15 +189,19 @@ vFP Module_Sym(char *name); vFP Module_SymX(char *name, Module **mptr); int Module_free(Module *mod); -#define add_Hook(hooktype, func) HookAddEx(hooktype, func, NULL) +#define add_Hook(hooktype, func) HookAddMain(NULL, hooktype, func, NULL) #define del_Hook(hooktype, func) HookDelEx(hooktype, func, NULL) -#define HookAdd(hooktype, func) HookAddEx(hooktype, func, NULL) +#define HookAdd(hooktype, func) HookAddMain(NULL, hooktype, func, NULL) +#define HookAddEx(module, hooktype, func) HookAddMain(module, hooktype, func, NULL) #define HookDel(hooktype, func) HookDelEx(hooktype, func, NULL) +#define HookAddInt(hooktype, func) HookAddMain(NULL, hooktype, NULL, func) +#define HookAddIntEx(module, hooktype, func) HookAddMain(module, hooktype, NULL, func) +#define HookDelInt(hooktype, func) HookDelEx(hooktype, NULL, func) -#define add_HookX(hooktype, func1, func2) HookAddEx(hooktype, func1, func2) +#define add_HookX(hooktype, func1, func2) HookAddMain(NULL, hooktype, func1, func2) #define del_HookX(hooktype, func1, func2) HookDelEx(hooktype, func1, func2) -void HookAddEx(int hooktype, int (*intfunc)(), void (*voidfunc)()); +void HookAddMain(Module *module, int hooktype, int (*intfunc)(), void (*voidfunc)()); void HookDelEx(int hooktype, int (*intfunc)(), void (*voidfunc)()); #define RunHook0(hooktype) for (global_i = Hooks[hooktype]; global_i; global_i = global_i->next)(*(global_i->func.intfunc))() diff --git a/include/struct.h b/include/struct.h index 1f3dc0ec9..965752f79 100644 --- a/include/struct.h +++ b/include/struct.h @@ -115,7 +115,6 @@ typedef struct Command aCommand; typedef struct SMember Member; typedef struct SMembership Membership; typedef struct SMembershipL MembershipL; -typedef struct _irchook Hook; #ifdef NEED_U_INT32_T typedef unsigned int u_int32_t; /* XXX Hope this works! */ @@ -1078,16 +1077,6 @@ struct _configitem_help { aMotd *text; }; -struct _irchook { - Hook *prev, *next; - ConfigFlag flag; - union - { - int (*intfunc)(); - void (*voidfunc)(); - } func; -}; - #define HM_HOST 1 #define HM_IPV4 2 #define HM_IPV6 3 diff --git a/src/events.c b/src/events.c index e73a83b22..1ac528063 100644 --- a/src/events.c +++ b/src/events.c @@ -106,6 +106,7 @@ Event *EventDel(Event *event) for (eventobjs = p->owner->objects; eventobjs; eventobjs = eventobjs->next) { if (eventobjs->type == MOBJ_EVENT && eventobjs->object.event == p) { DelListItem(eventobjs, p->owner->objects); + MyFree(eventobjs); break; } } diff --git a/src/modules.c b/src/modules.c index 931d7d02f..059b27cc3 100644 --- a/src/modules.c +++ b/src/modules.c @@ -253,8 +253,14 @@ int Module_free(Module *mod) } for (objs = mod->objects; objs; objs = next) { next = objs->next; - if (objs->type == MOBJ_EVENT) + if (objs->type == MOBJ_EVENT) { EventDel(objs->object.event); + + } + else if (objs->type == MOBJ_HOOK) { + HookDelEx(objs->object.hook->type, objs->object.hook->func.intfunc, + objs->object.hook->func.voidfunc); + } } for (p = Modules; p; p = p->next) { @@ -597,7 +603,7 @@ int m_module(aClient *cptr, aClient *sptr, int parc, char *parv[]) return 1; } -void HookAddEx(int hooktype, int (*func)(), void (*vfunc)()) +void HookAddMain(Module *module, int hooktype, int (*func)(), void (*vfunc)()) { Hook *p; @@ -606,7 +612,15 @@ void HookAddEx(int hooktype, int (*func)(), void (*vfunc)()) p->func.intfunc = func; if (vfunc) p->func.voidfunc = vfunc; + p->type = hooktype; + p->owner = module; AddListItem(p, Hooks[hooktype]); + if (module) { + ModuleObject *hookobj = (ModuleObject *)MyMallocEx(sizeof(ModuleObject)); + hookobj->object.hook = p; + hookobj->type = MOBJ_HOOK; + AddListItem(hookobj, module->objects); + } } void HookDelEx(int hooktype, int (*func)(), void (*vfunc)()) @@ -618,6 +632,17 @@ void HookDelEx(int hooktype, int (*func)(), void (*vfunc)()) (vfunc && (p->func.voidfunc == vfunc))) { DelListItem(p, Hooks[hooktype]); + if (p->owner) { + ModuleObject *hookobj; + for (hookobj = p->owner->objects; hookobj; hookobj = hookobj->next) { + if (hookobj->type == MOBJ_HOOK && hookobj->object.hook == p) { + DelListItem(hookobj, p->owner->objects); + MyFree(hookobj); + break; + } + } + } + MyFree(p); return; } } diff --git a/src/modules/m_guest.c b/src/modules/m_guest.c index e8f90a728..9c164cf38 100644 --- a/src/modules/m_guest.c +++ b/src/modules/m_guest.c @@ -47,6 +47,7 @@ DLLFUNC int m_guest(aClient *cptr, aClient *sptr, int parc, char *parv[]); /* Place includes here */ +Module *Mod_Handle = NULL; #ifndef DYNAMIC_LINKING ModuleHeader m_guest_Header #else @@ -77,7 +78,7 @@ int m_guest_Init(int module_load) * We call our add_Command crap here */ #ifdef GUEST - add_Hook(HOOKTYPE_GUEST, m_guest); + HookAddEx(Mod_Handle, HOOKTYPE_GUEST, m_guest); #endif return MOD_SUCCESS; @@ -103,7 +104,7 @@ int m_guest_Unload(int module_unload) #endif { #ifdef GUEST - del_Hook(HOOKTYPE_GUEST, m_guest); + HookDel(HOOKTYPE_GUEST, m_guest); #endif return MOD_SUCCESS; } diff --git a/src/modules/scan_http.c b/src/modules/scan_http.c index 8c45d29a8..5f7119ea7 100644 --- a/src/modules/scan_http.c +++ b/src/modules/scan_http.c @@ -68,7 +68,7 @@ static struct SOCKADDR_IN *xScan_endpoint = NULL; extern void Eadd_scan(); extern struct SOCKADDR_IN Scan_endpoint; #endif - +Module *Mod_Handle = NULL; static Mod_SymbolDepTable modsymdep[] = { MOD_Dep(Eadd_scan, xEadd_scan, "src/modules/scan.so"), @@ -107,7 +107,7 @@ int scan_http_Init(int module_load) /* * Add scanning hooks */ - HookAddEx(HOOKTYPE_SCAN_HOST, NULL, scan_http_scan); + HookAddIntEx(Mod_Handle, HOOKTYPE_SCAN_HOST, scan_http_scan); return MOD_SUCCESS; } diff --git a/src/modules/scan_socks.c b/src/modules/scan_socks.c index 0fdf8d72d..4bf2917cf 100644 --- a/src/modules/scan_socks.c +++ b/src/modules/scan_socks.c @@ -104,7 +104,7 @@ int scan_socks_Init(int module_load) /* * Add scanning hooks */ - HookAddEx(HOOKTYPE_SCAN_HOST, NULL, scan_socks_scan); + HookAddIntEx(Mod_Handle, HOOKTYPE_SCAN_HOST, scan_socks_scan); return MOD_SUCCESS; } @@ -125,7 +125,7 @@ DLLFUNC int Mod_Unload(int module_unload) int scan_socks_Unload(int module_unload) #endif { - HookDelEx(HOOKTYPE_SCAN_HOST, NULL, scan_socks_scan); + HookDelInt(HOOKTYPE_SCAN_HOST, scan_socks_scan); } #define HICHAR(s) (((unsigned short) s) >> 8) diff --git a/src/modules/web/httpd.c b/src/modules/web/httpd.c index a091bc904..a40a205a6 100644 --- a/src/modules/web/httpd.c +++ b/src/modules/web/httpd.c @@ -71,7 +71,7 @@ int httpd_parse(HTTPd_Request *request); void httpd_badrequest(HTTPd_Request *request, char *reason); void httpd_parse_final(HTTPd_Request *request); void httpd_404_header(HTTPd_Request *request, char *path); - +Module *Mod_Handle = NULL; #ifndef DYNAMIC_LINKING @@ -95,9 +95,9 @@ DLLFUNC int Mod_Init(int module_load) int httpd_Init(int module_load) #endif { - HookAddEx(HOOKTYPE_HTTPD_URL, h_u_stats, NULL); - HookAddEx(HOOKTYPE_HTTPD_URL, h_u_vfs, NULL); - HookAddEx(HOOKTYPE_HTTPD_URL, h_u_phtml, NULL); + HookAddEx(Mod_Handle, HOOKTYPE_HTTPD_URL, h_u_stats); + HookAddEx(Mod_Handle, HOOKTYPE_HTTPD_URL, h_u_vfs); + HookAddEx(Mod_Handle, HOOKTYPE_HTTPD_URL, h_u_phtml); return 1; }