diff --git a/Changes b/Changes index 8b5c5dacf..4e78ad687 100644 --- a/Changes +++ b/Changes @@ -2362,3 +2362,5 @@ seen. gmtime warning still there code is based on the ircu Windows NT port by run. - Fixed a problem with /quote dns i - Rewrote a whole bunch of stuff in the extcmode code +- Extended the module system to allow better error reporting using ModuleGetError and + ModuleGetErrorStr diff --git a/include/modules.h b/include/modules.h index d7d5fd255..f1cfed555 100644 --- a/include/modules.h +++ b/include/modules.h @@ -261,6 +261,16 @@ struct _hooktype { * What we use to keep track internally of the modules */ +#define MODERR_NOERROR 0 +#define MODERR_EXISTS 1 +#define MODERR_NOSPACE 2 +#define MODERR_INVALID 3 + +unsigned int ModuleGetError(Module *module); +const char *ModuleGetErrorStr(Module *module); +unsigned int ModuleGetOptions(Module *module); +unsigned int ModuleSetOptions(Module *module, unsigned int options); + struct _Module { struct _Module *prev, *next; @@ -277,6 +287,7 @@ struct _Module ModuleObject *objects; ModuleInfo modinfo; /* Used to store handle info for module */ unsigned char options; + unsigned char errorcode; }; /* * Symbol table diff --git a/src/events.c b/src/events.c index 5f44ee70e..c44a7bb2b 100644 --- a/src/events.c +++ b/src/events.c @@ -61,6 +61,8 @@ Event *EventAddEx(Module *module, char *name, long every, long howmany, if (!name || (every < 0) || (howmany < 0) || !event) { + if (module) + module->errorcode = MODERR_INVALID; return NULL; } newevent = (Event *) MyMallocEx(sizeof(Event)); @@ -78,6 +80,7 @@ Event *EventAddEx(Module *module, char *name, long every, long howmany, eventobj->object.event = newevent; eventobj->type = MOBJ_EVENT; AddListItem(eventobj, module->objects); + module->errorcode = MODERR_NOERROR; } return newevent; @@ -126,7 +129,11 @@ Event *EventFind(char *name) int EventMod(Event *event, EventInfo *mods) { if (!event || !mods) + { + if (event && event->owner) + event->owner->errorcode = MODERR_INVALID; return -1; + } if (mods->flags & EMOD_EVERY) event->every = mods->every; @@ -140,6 +147,8 @@ int EventMod(Event *event, EventInfo *mods) { event->event = mods->event; if (mods->flags & EMOD_DATA) event->data = mods->data; + if (event->owner) + event->owner->errorcode = MODERR_NOERROR; return 0; } diff --git a/src/modules.c b/src/modules.c index 29e60dc50..f0fb430a3 100644 --- a/src/modules.c +++ b/src/modules.c @@ -261,6 +261,7 @@ Module *Module_make(ModuleHeader *header, modp->dll = mod; modp->flags = MODFLAG_NONE; modp->options = 0; + modp->errorcode = MODERR_NOERROR; modp->children = NULL; modp->modinfo.size = sizeof(ModuleInfo); modp->modinfo.module_load = 0; @@ -768,6 +769,7 @@ Versionflag *VersionflagAdd(Module *module, char flag) vflagobj->type = MOBJ_VERSIONFLAG; vflagobj->object.versionflag = vflag; AddListItem(vflagobj, module->objects); + module->errorcode = MODERR_NOERROR; } AddListItem(parent,vflag->parents); } @@ -784,6 +786,7 @@ Versionflag *VersionflagAdd(Module *module, char flag) vflagobj->type = MOBJ_VERSIONFLAG; vflagobj->object.versionflag = vflag; AddListItem(vflagobj, module->objects); + module->errorcode = MODERR_NOERROR; } flag_add(flag); AddListItem(parent,vflag->parents); @@ -796,6 +799,7 @@ void VersionflagDel(Versionflag *vflag, Module *module) ModuleChild *owner; if (!vflag) return; + for (owner = vflag->parents; owner; owner = owner->next) { if (owner->child == module) @@ -843,6 +847,7 @@ Hooktype *HooktypeAdd(Module *module, char *string, int *type) { hooktypeobj->type = MOBJ_HOOKTYPE; hooktypeobj->object.hooktype = hooktype; AddListItem(hooktypeobj, module->objects); + module->errorcode = MODERR_NOERROR; } AddListItem(parent,hooktype->parents); } @@ -852,7 +857,11 @@ Hooktype *HooktypeAdd(Module *module, char *string, int *type) { for (hooktype = Hooktypes, i = 0; hooktype->string; hooktype++, i++) ; if (i >= 29) + { + if (module) + module->errorcode = MODERR_NOSPACE; return NULL; + } Hooktypes[i].id = i+31; Hooktypes[i].string = strdup(string); @@ -863,6 +872,7 @@ Hooktype *HooktypeAdd(Module *module, char *string, int *type) { hooktypeobj->type = MOBJ_HOOKTYPE; hooktypeobj->object.hooktype = &Hooktypes[i]; AddListItem(hooktypeobj,module->objects); + module->errorcode = MODERR_NOERROR; } AddListItem(parent,Hooktypes[i].parents); *type = i+31; @@ -916,6 +926,7 @@ Hook *HookAddMain(Module *module, int hooktype, int (*func)(), void (*vfunc)(), hookobj->object.hook = p; hookobj->type = MOBJ_HOOK; AddListItem(hookobj, module->objects); + module->errorcode = MODERR_NOERROR; } return p; } @@ -985,3 +996,20 @@ unsigned int ModuleGetOptions(Module *module) { return module->options; } + +unsigned int ModuleGetError(Module *module) +{ + return module->errorcode; +} + +static const char *module_error_str[] = { + "No error", + "Object already exists", + "No space available", + "Invalid parameter(s)" +}; + +const char *ModuleGetErrorStr(Module *module) +{ + return module_error_str[module->errorcode]; +} diff --git a/src/packet.c b/src/packet.c index 2b4e97c08..574f2d226 100644 --- a/src/packet.c +++ b/src/packet.c @@ -345,6 +345,7 @@ Command *CommandAdd(Module *module, char *cmd, char *tok, int (*func)(), unsigne cmdobj->object.command = command; cmdobj->type = MOBJ_COMMAND; AddListItem(cmdobj, module->objects); + module->errorcode = MODERR_NOERROR; } return command; } diff --git a/src/umodes.c b/src/umodes.c index 349a98863..d8aad4028 100644 --- a/src/umodes.c +++ b/src/umodes.c @@ -181,11 +181,20 @@ Umode *UmodeAdd(Module *module, char ch, int global, int (*allowed)(aClient *spt { if (!Usermode_Table[i].flag && save == -1) save = i; - else if (Usermode_Table[i].flag == ch && Usermode_Table[i].unloaded) + else if (Usermode_Table[i].flag == ch) { - save = i; - Usermode_Table[i].unloaded = 0; - break; + if (Usermode_Table[i].unloaded) + { + save = i; + Usermode_Table[i].unloaded = 0; + break; + } + else + { + if (module) + module->errorcode = MODERR_EXISTS; + return NULL; + } } i++; } @@ -213,12 +222,15 @@ Umode *UmodeAdd(Module *module, char ch, int global, int (*allowed)(aClient *spt umodeobj->object.umode = &(Usermode_Table[i]); umodeobj->type = MOBJ_UMODE; AddListItem(umodeobj, module->objects); + module->errorcode = MODERR_NOERROR; } return &(Usermode_Table[i]); } else { Debug((DEBUG_DEBUG, "UmodeAdd failed, no space")); + if (module) + module->errorcode = MODERR_NOSPACE; return NULL; } } @@ -269,11 +281,20 @@ Snomask *SnomaskAdd(Module *module, char ch, int (*allowed)(aClient *sptr), long { if (!Snomask_Table[i].flag && save == -1) save = i; - else if (Snomask_Table[i].flag == ch && Snomask_Table[i].unloaded) + else if (Snomask_Table[i].flag == ch) { - save = i; - Snomask_Table[i].unloaded = 0; - break; + if (Snomask_Table[i].unloaded) + { + save = i; + Snomask_Table[i].unloaded = 0; + break; + } + else + { + if (module) + module->errorcode = MODERR_EXISTS; + return NULL; + } } i++; } @@ -295,6 +316,7 @@ Snomask *SnomaskAdd(Module *module, char ch, int (*allowed)(aClient *sptr), long snoobj->object.snomask = &(Snomask_Table[i]); snoobj->type = MOBJ_SNOMASK; AddListItem(snoobj, module->objects); + module->errorcode = MODERR_NOERROR; } return &(Snomask_Table[i]); } @@ -302,6 +324,8 @@ Snomask *SnomaskAdd(Module *module, char ch, int (*allowed)(aClient *sptr), long { Debug((DEBUG_DEBUG, "SnomaskAdd failed, no space")); *mode = 0; + if (module) + module->errorcode = MODERR_NOSPACE; return NULL; } }