diff --git a/include/modules.h b/include/modules.h index be4a4e29d..864f333a4 100644 --- a/include/modules.h +++ b/include/modules.h @@ -945,9 +945,45 @@ extern RPCHandler *RPCHandlerAdd(Module *module, RPCHandlerInfo *mreq); extern void RPCHandlerDel(RPCHandler *m); #ifndef GCC_TYPECHECKING +/** Add a hook that returns an int. + * @param module The module adding the hook + * @param hooktype The hook type (HOOKTYPE_*) + * @param priority Priority for hook execution order. Lower value = called first. Use 0 for normal. + * @param func The hook function to add + * @returns The Hook pointer, or NULL on failure. + * @note Call this from MOD_INIT(), except for HOOKTYPE_CONFIGTEST and + * HOOKTYPE_CONFIGPOSTTEST hooks which should be added in MOD_TEST(). + */ #define HookAdd(module, hooktype, priority, func) HookAddMain(module, hooktype, priority, func, NULL, NULL, NULL) +/** Add a hook that returns void. + * @param module The module adding the hook + * @param hooktype The hook type (HOOKTYPE_*) + * @param priority Priority for hook execution order. Lower value = called first. Use 0 for normal. + * @param func The hook function to add + * @returns The Hook pointer, or NULL on failure. + * @note Call this from MOD_INIT(), except for HOOKTYPE_CONFIGTEST and + * HOOKTYPE_CONFIGPOSTTEST hooks which should be added in MOD_TEST(). + */ #define HookAddVoid(module, hooktype, priority, func) HookAddMain(module, hooktype, priority, NULL, func, NULL, NULL) +/** Add a hook that returns a string (char *). + * @param module The module adding the hook + * @param hooktype The hook type (HOOKTYPE_*) + * @param priority Priority for hook execution order. Lower value = called first. Use 0 for normal. + * @param func The hook function to add + * @returns The Hook pointer, or NULL on failure. + * @note Call this from MOD_INIT(), except for HOOKTYPE_CONFIGTEST and + * HOOKTYPE_CONFIGPOSTTEST hooks which should be added in MOD_TEST(). + */ #define HookAddString(module, hooktype, priority, func) HookAddMain(module, hooktype, priority, NULL, NULL, func, NULL) +/** Add a hook that returns a const string (const char *). + * @param module The module adding the hook + * @param hooktype The hook type (HOOKTYPE_*) + * @param priority Priority for hook execution order. Lower value = called first. Use 0 for normal. + * @param func The hook function to add + * @returns The Hook pointer, or NULL on failure. + * @note Call this from MOD_INIT(), except for HOOKTYPE_CONFIGTEST and + * HOOKTYPE_CONFIGPOSTTEST hooks which should be added in MOD_TEST(). + */ #define HookAddConstString(module, hooktype, priority, func) HookAddMain(module, hooktype, priority, NULL, NULL, NULL, func) #else #define HookAdd(module, hooktype, priority, func) \ @@ -974,13 +1010,39 @@ __extension__ ({ \ }) #endif /* GCC_TYPCHECKING */ +/** Add a hook - internal function. + * Use the HookAdd(), HookAddVoid(), HookAddString() + * or HookAddConstString() macros instead. + * @param module The module adding the hook + * @param hooktype The hook type (HOOKTYPE_*) + * @param priority Priority for hook execution order. Lower value = called first. Use 0 for normal. + * @param intfunc Function returning int (or NULL) + * @param voidfunc Function returning void (or NULL) + * @param stringfunc Function returning char* (or NULL) + * @param conststringfunc Function returning const char* (or NULL) + * @returns The Hook pointer, or NULL on failure. + * @note Call this from MOD_INIT(), except for HOOKTYPE_CONFIGTEST and + * HOOKTYPE_CONFIGPOSTTEST hooks which should be added in MOD_TEST(). + */ extern Hook *HookAddMain(Module *module, int hooktype, int priority, int (*intfunc)(), void (*voidfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)()); extern Hook *HookDel(Hook *hook); extern Hooktype *HooktypeAdd(Module *module, const char *string, int *type); extern void HooktypeDel(Hooktype *hooktype, Module *module); +/** Run all hooks for a given hook type (used by the IRCd core to call modules). + * All hook functions registered for the hooktype are called with the provided arguments. + * Return values from the hook functions are ignored. + * @param hooktype The hook type (HOOKTYPE_*) + * @param ... Arguments to pass to the hook functions + */ #define RunHook(hooktype,...) do { Hook *h; for (h = Hooks[hooktype]; h; h = h->next) (*(h->func.intfunc))(__VA_ARGS__); } while(0) +/** Run all hooks for a given hook type, returning early from the calling function + * if a hook signals to stop processing (used by the IRCd core to call modules). + * @param hooktype The hook type (HOOKTYPE_*) + * @param retchk Condition on return value to stop processing, eg != 0 + * @param ... Arguments to pass to the hook functions + */ #define RunHookReturn(hooktype,retchk,...) \ { \ int retval; \ @@ -991,6 +1053,14 @@ extern void HooktypeDel(Hooktype *hooktype, Module *module); if (retval retchk) return; \ } \ } +/** Run all hooks for a given hook type, returning the hook's return value from + * the calling function if a hook signals to stop processing + * (used by the IRCd core to call modules). + * @param hooktype The hook type (HOOKTYPE_*) + * @param retchk Condition on return value to stop processing, eg != 0 + * @param ... Arguments to pass to the hook functions + * @returns The return value of the hook function that triggered the early return + */ #define RunHookReturnInt(hooktype,retchk,...) \ { \ int retval; \ @@ -1002,21 +1072,115 @@ extern void HooktypeDel(Hooktype *hooktype, Module *module); } \ } +/** Add a callback that returns an int. + * @param module The module adding the callback + * @param cbtype The callback type (CALLBACKTYPE_*) + * @param func The callback function to add + * @returns The Callback pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only one callback per type can be registered. + */ #define CallbackAdd(module, cbtype, func) CallbackAddMain(module, cbtype, func, NULL, NULL, NULL, NULL) +/** Add a callback that returns void. + * @param module The module adding the callback + * @param cbtype The callback type (CALLBACKTYPE_*) + * @param func The callback function to add + * @returns The Callback pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only one callback per type can be registered. + */ #define CallbackAddVoid(module, cbtype, func) CallbackAddMain(module, cbtype, NULL, func, NULL, NULL, NULL) +/** Add a callback that returns a pointer (void *). + * @param module The module adding the callback + * @param cbtype The callback type (CALLBACKTYPE_*) + * @param func The callback function to add + * @returns The Callback pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only one callback per type can be registered. + */ #define CallbackAddPVoid(module, cbtype, func) CallbackAddMain(module, cbtype, NULL, NULL, func, NULL, NULL) +/** Add a callback that returns a string (char *). + * @param module The module adding the callback + * @param cbtype The callback type (CALLBACKTYPE_*) + * @param func The callback function to add + * @returns The Callback pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only one callback per type can be registered. + */ #define CallbackAddString(module, cbtype, func) CallbackAddMain(module, cbtype, NULL, NULL, NULL, func, NULL) +/** Add a callback that returns a const string (const char *). + * @param module The module adding the callback + * @param cbtype The callback type (CALLBACKTYPE_*) + * @param func The callback function to add + * @returns The Callback pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only one callback per type can be registered. + */ #define CallbackAddConstString(module, cbtype, func) CallbackAddMain(module, cbtype, NULL, NULL, NULL, NULL, func) extern Callback *CallbackAddMain(Module *module, int cbtype, int (*func)(), void (*vfunc)(), void *(*pvfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)()); extern Callback *CallbackDel(Callback *cb); +/** Add an efunction that returns an int. + * @param module The module adding the efunction + * @param cbtype The efunction type (EFUNC_*) + * @param func The function to add + * @returns The Efunction pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only official (core) modules may add efunctions. + */ #define EfunctionAdd(module, cbtype, func) EfunctionAddMain(module, cbtype, func, NULL, NULL, NULL, NULL) +/** Add an efunction that returns void. + * @param module The module adding the efunction + * @param cbtype The efunction type (EFUNC_*) + * @param func The function to add + * @returns The Efunction pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only official (core) modules may add efunctions. + */ #define EfunctionAddVoid(module, cbtype, func) EfunctionAddMain(module, cbtype, NULL, func, NULL, NULL, NULL) +/** Add an efunction that returns a pointer (void *). + * @param module The module adding the efunction + * @param cbtype The efunction type (EFUNC_*) + * @param func The function to add + * @returns The Efunction pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only official (core) modules may add efunctions. + */ #define EfunctionAddPVoid(module, cbtype, func) EfunctionAddMain(module, cbtype, NULL, NULL, func, NULL, NULL) +/** Add an efunction that returns a string (char *). + * @param module The module adding the efunction + * @param cbtype The efunction type (EFUNC_*) + * @param func The function to add + * @returns The Efunction pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only official (core) modules may add efunctions. + */ #define EfunctionAddString(module, cbtype, func) EfunctionAddMain(module, cbtype, NULL, NULL, NULL, func, NULL) +/** Add an efunction that returns a const string (const char *). + * @param module The module adding the efunction + * @param cbtype The efunction type (EFUNC_*) + * @param func The function to add + * @returns The Efunction pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only official (core) modules may add efunctions. + */ #define EfunctionAddConstString(module, cbtype, func) EfunctionAddMain(module, cbtype, NULL, NULL, NULL, NULL, func) +/** Add an efunction (enhanced function) - internal function. + * Use the EfunctionAdd(), EfunctionAddVoid(), EfunctionAddPVoid(), + * EfunctionAddString() or EfunctionAddConstString() macros instead. + * @param module The module adding the efunction + * @param eftype The efunction type (EFUNC_*) + * @param intfunc Function returning int (or NULL) + * @param voidfunc Function returning void (or NULL) + * @param pvoidfunc Function returning void* (or NULL) + * @param stringfunc Function returning char* (or NULL) + * @param conststringfunc Function returning const char* (or NULL) + * @returns The Efunction pointer, or NULL on failure. + * @note Call this from MOD_TEST(). + * @note Only official (core) modules may add efunctions. + */ extern Efunction *EfunctionAddMain(Module *module, EfunctionType eftype, int (*intfunc)(), void (*voidfunc)(), void *(*pvoidfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)()); extern Efunction *EfunctionDel(Efunction *cb); @@ -1028,9 +1192,12 @@ extern int CommandExists(const char *name); extern CommandOverride *CommandOverrideAdd(Module *module, const char *name, int priority, OverrideCmdFunc func); extern void CommandOverrideDel(CommandOverride *ovr); extern void CallCommandOverride(CommandOverride *ovr, ClientContext *clictx, Client *client, MessageTag *mtags, int parc, const char *parv[]); -/** Call next command override function - easy way to do it. - * This way you don't have to call CallCommandOverride() with the right arguments. - * Which is nice because command (override) arguments may change in future UnrealIRCd versions. +/** Call the next command override handler in the chain. + * Use this macro instead of calling CallCommandOverride() directly. + * This way you don't have to pass all the arguments yourself, + * and your module will keep working if command parameters change + * in future UnrealIRCd versions. + * @note Can only be used inside a CMD_OVERRIDE_FUNC() function. */ #define CALL_NEXT_COMMAND_OVERRIDE() CallCommandOverride(ovr, clictx, client, recv_mtags, parc, parv) @@ -1047,23 +1214,69 @@ extern int moddata_local_client_set(Client *acptr, const char *varname, const ch extern const char *moddata_local_client_get(Client *acptr, const char *varname); extern void LoadPersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void **var, void (*free_variable)(ModData *m)); +/** Load a persistent pointer variable across module rehashes. + * This restores the value of a pointer variable that was previously saved + * with SavePersistentPointer(). Call this in MOD_INIT(). + * @param modinfo The module info (modinfo, as received in MOD_INIT) + * @param var The pointer variable to restore + * @param free_variable Callback function to free the data on module unload (or NULL) + */ #define LoadPersistentPointer(modinfo, var, free_variable) LoadPersistentPointerX(modinfo, #var, (void **)&var, free_variable) extern void SavePersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void *var); +/** Save a persistent pointer variable across module rehashes. + * This saves the value of a pointer variable so it can be restored + * after a rehash with LoadPersistentPointer(). Call this in MOD_UNLOAD(). + * @param modinfo The module info (modinfo, as received in MOD_UNLOAD) + * @param var The pointer variable to save + */ #define SavePersistentPointer(modinfo, var) SavePersistentPointerX(modinfo, #var, var) extern void LoadPersistentIntX(ModuleInfo *modinfo, const char *varshortname, int *var); +/** Load a persistent int variable across module rehashes. + * This restores the value of an int variable that was previously saved + * with SavePersistentInt(). Call this in MOD_INIT(). + * @param modinfo The module info (modinfo, as received in MOD_INIT) + * @param var The int variable to restore + */ #define LoadPersistentInt(modinfo, var) LoadPersistentIntX(modinfo, #var, &var) extern void SavePersistentIntX(ModuleInfo *modinfo, const char *varshortname, int var); +/** Save a persistent int variable across module rehashes. + * Call this in MOD_UNLOAD(). + * @param modinfo The module info (modinfo, as received in MOD_UNLOAD) + * @param var The int variable to save + */ #define SavePersistentInt(modinfo, var) SavePersistentIntX(modinfo, #var, var) extern void LoadPersistentLongX(ModuleInfo *modinfo, const char *varshortname, long *var); +/** Load a persistent long variable across module rehashes. + * This restores the value of a long variable that was previously saved + * with SavePersistentLong(). Call this in MOD_INIT(). + * @param modinfo The module info (modinfo, as received in MOD_INIT) + * @param var The long variable to restore + */ #define LoadPersistentLong(modinfo, var) LoadPersistentLongX(modinfo, #var, &var) extern void SavePersistentLongX(ModuleInfo *modinfo, const char *varshortname, long var); +/** Save a persistent long variable across module rehashes. + * Call this in MOD_UNLOAD(). + * @param modinfo The module info (modinfo, as received in MOD_UNLOAD) + * @param var The long variable to save + */ #define SavePersistentLong(modinfo, var) SavePersistentLongX(modinfo, #var, var) extern void LoadPersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long *var); +/** Load a persistent long long variable across module rehashes. + * This restores the value of a long long variable that was previously saved + * with SavePersistentLongLong(). Call this in MOD_INIT(). + * @param modinfo The module info (modinfo, as received in MOD_INIT) + * @param var The long long variable to restore + */ #define LoadPersistentLongLong(modinfo, var) LoadPersistentLongLongX(modinfo, #var, &var) extern void SavePersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long var); +/** Save a persistent long long variable across module rehashes. + * Call this in MOD_UNLOAD(). + * @param modinfo The module info (modinfo, as received in MOD_UNLOAD) + * @param var The long long variable to save + */ #define SavePersistentLongLong(modinfo, var) SavePersistentLongLongX(modinfo, #var, var) extern APICallback *APICallbackFind(const char *method, APICallbackType callback_type); diff --git a/src/api-apicallback.c b/src/api-apicallback.c index 368ef9a18..9acdf0827 100644 --- a/src/api-apicallback.c +++ b/src/api-apicallback.c @@ -104,9 +104,10 @@ APICallback *APICallbackFind(const char *name, APICallbackType callback_type) return NULL; } -/** Remove the specified API callback - modules should not call this. - * This is done automatically for modules on unload, so is only called internally. - * @param m The API Callback to remove. +/** Remove an API callback. + * @param m The API callback to remove. + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void APICallbackDel(APICallback *m) { diff --git a/src/api-channelmode.c b/src/api-channelmode.c index c80ba587e..c46de1b74 100644 --- a/src/api-channelmode.c +++ b/src/api-channelmode.c @@ -446,8 +446,9 @@ Cmode *CmodeAdd(Module *module, CmodeInfo req, Cmode_t *mode) return cm; } -/** Delete a previously registered channel mode - not called by modules. - * For modules this is done automatically on unload, no need to call this explicitly. +/** Delete a previously registered channel mode. + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void CmodeDel(Cmode *cmode) { diff --git a/src/api-clicap.c b/src/api-clicap.c index e00b5d2b3..bb6991c97 100644 --- a/src/api-clicap.c +++ b/src/api-clicap.c @@ -257,10 +257,10 @@ void unload_clicap_commit(ClientCapability *clicap) clicap_update_affecting(); } -/** - * Removes the specified clicap token. - * - * @param clicap The token to remove. +/** Remove a client capability. + * @param clicap The client capability to remove. + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void ClientCapabilityDel(ClientCapability *clicap) { diff --git a/src/api-command.c b/src/api-command.c index cd90aff94..b870a12ca 100644 --- a/src/api-command.c +++ b/src/api-command.c @@ -129,6 +129,8 @@ static Command *CommandAddInternal(Module *module, const char *cmd, CmdFunc func /** Delete a command - only used internally. * @param command The command (can be NULL) * @param cmd The "real" command + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void CommandDelX(Command *command, RealCommand *cmd) { @@ -159,8 +161,10 @@ void CommandDelX(Command *command, RealCommand *cmd) safe_free(command); } -/** De-register a command - not called by modules, only internally. - * For modules this is done automatically. +/** Delete a command. + * @param command The command to delete + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void CommandDel(Command *command) { diff --git a/src/api-efunctions.c b/src/api-efunctions.c index 3428b281d..359a775f4 100644 --- a/src/api-efunctions.c +++ b/src/api-efunctions.c @@ -245,6 +245,12 @@ Efunction *EfunctionAddMain(Module *module, EfunctionType eftype, int (*func)(), return p; } +/** Delete an efunction. + * @param cb The efunction to delete + * @returns The next Efunction in the list, or NULL. + * @note Modules do not need to call this function, + * it is done automatically on module unload. + */ Efunction *EfunctionDel(Efunction *cb) { Efunction *p, *q; diff --git a/src/api-event.c b/src/api-event.c index 1ad24f669..31fa23dfc 100644 --- a/src/api-event.c +++ b/src/api-event.c @@ -144,6 +144,10 @@ static void CleanupEvents(void) } } +/** Find an event by name. + * @param name The event name to search for + * @returns The Event pointer, or NULL if not found + */ Event *EventFind(const char *name) { Event *eventptr; diff --git a/src/api-extban.c b/src/api-extban.c index 76d7ac34e..6641739b4 100644 --- a/src/api-extban.c +++ b/src/api-extban.c @@ -125,6 +125,12 @@ static void extban_add_sorted(Extban *n) } } +/** Register an extended ban. + * @param module The module registering the extended ban + * @param req The ExtbanInfo request struct (name, callbacks, etc.) + * @returns The Extban pointer, or NULL on failure. + * @note Call this from MOD_INIT(). + */ Extban *ExtbanAdd(Module *module, ExtbanInfo req) { Extban *e; @@ -279,6 +285,11 @@ void unload_all_unused_extbans(void) } +/** Delete an extended ban. + * @param e The extended ban to delete + * @note Modules do not need to call this function, + * it is done automatically on module unload. + */ void ExtbanDel(Extban *e) { /* Always free the module object */ @@ -303,7 +314,15 @@ void ExtbanDel(Extban *e) unload_extban_commit(e); } -/** General is_ok for n!u@h stuff that also deals with recursive extbans. +/** is_ok handler that accepts nick!user@host patterns and stacked extbans. + * Use this as your extban's is_ok callback when your extban matches + * against nick!user@host masks and you want to allow stacking with + * other extbans (e.g. ~yourextban:~account:someone). + * + * Example usage: + * @code + * req.is_ok = extban_is_ok_nuh_extban; + * @endcode */ int extban_is_ok_nuh_extban(BanContext *b) { @@ -355,9 +374,15 @@ int extban_is_ok_nuh_extban(BanContext *b) return 1; /* Either not an extban, or extban has NULL is_ok. Good to go. */ } -/** Some kind of general conv_param routine, - * to ensure the parameter is nick!user@host. - * most of the code is just copied from clean_ban_mask. +/** conv_param handler that normalizes the parameter as nick!user@host. + * For example, "foo" becomes "foo!*@*". Does NOT allow stacking with + * other extbans. If you want to support stacking, use + * extban_conv_param_nuh_or_extban() instead. + * + * Example usage: + * @code + * req.conv_param = extban_conv_param_nuh; + * @endcode */ const char *extban_conv_param_nuh(BanContext *b, Extban *extban) { @@ -369,7 +394,17 @@ const char *extban_conv_param_nuh(BanContext *b, Extban *extban) return convert_regular_ban(tmpbuf, retbuf, sizeof(retbuf)); } -/** conv_param to deal with stacked extbans. +/** conv_param handler that normalizes nick!user@host and allows stacked extbans. + * If the parameter is a plain mask like "foo", it is normalized to "foo!*@*". + * If the parameter is another extban like "~account:someone", the inner + * extban's conv_param is called and the result is reassembled. + * This is the most commonly used conv_param handler. + * + * Example usage: + * @code + * req.is_ok = extban_is_ok_nuh_extban; + * req.conv_param = extban_conv_param_nuh_or_extban; + * @endcode */ const char *extban_conv_param_nuh_or_extban(BanContext *b, Extban *self_extban) { @@ -426,6 +461,26 @@ const char *extban_conv_param_nuh_or_extban(BanContext *b, Extban *self_extban) return ret; } +/** Reassemble an extban string by prepending the extban prefix to a parameter. + * This is used in custom conv_param handlers for extbans that support stacking. + * After calling the inner extban's conv_param to get the cleaned parameter, + * call this to reconstruct the full ban string (e.g. "~quiet:someone!*@*"). + * Automatically uses named or letter form based on server configuration. + * @param remainder The cleaned parameter from the inner conv_param (may be NULL) + * @param b The ban context + * @param extban The inner extban + * @param buf Buffer to store the result + * @param buflen Size of the buffer + * @returns The assembled ban string in buf, or NULL if remainder was NULL + * + * Example usage in a custom conv_param handler (from timedban): + * @code + * Extban *extban = findmod_by_bantype(mask, &nextbanstr); + * newb->banstr = nextbanstr; + * ret = extban->conv_param(newb, extban); + * ret = prefix_with_extban(ret, newb, extban, retbuf, sizeof(retbuf)); + * @endcode + */ char *prefix_with_extban(const char *remainder, BanContext *b, Extban *extban, char *buf, size_t buflen) { /* Yes, we support this because it makes code at the caller cleaner */ diff --git a/src/api-history-backend.c b/src/api-history-backend.c index 0d16c9419..9472bf119 100644 --- a/src/api-history-backend.c +++ b/src/api-history-backend.c @@ -117,10 +117,10 @@ void unload_history_backend_commit(HistoryBackend *m) safe_free(m); } -/** - * Removes the specified history backend. - * +/** Remove a history backend. * @param m The history backend to remove. + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void HistoryBackendDel(HistoryBackend *m) { diff --git a/src/api-isupport.c b/src/api-isupport.c index d78a99a84..e898cfe7e 100644 --- a/src/api-isupport.c +++ b/src/api-isupport.c @@ -235,10 +235,10 @@ ISupport *ISupportAdd(Module *module, const char *token, const char *value) return isupport; } -/** - * Removes the specified isupport token. - * - * @param isupport The token to remove. +/** Remove an ISUPPORT (005) token. + * @param isupport The ISUPPORT token to remove. + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void ISupportDel(ISupport *isupport) { diff --git a/src/api-messagetag.c b/src/api-messagetag.c index 074f8fc48..5f4dcc292 100644 --- a/src/api-messagetag.c +++ b/src/api-messagetag.c @@ -127,9 +127,10 @@ MessageTagHandler *MessageTagHandlerFind(const char *name) return NULL; } -/** Remove the specified message tag handler - modules should not call this. - * This is done automatically for modules on unload, so is only called internally. +/** Remove a message tag handler. * @param m The message tag handler to remove. + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void MessageTagHandlerDel(MessageTagHandler *m) { diff --git a/src/api-moddata.c b/src/api-moddata.c index 4dc8a8a42..3dbac2310 100644 --- a/src/api-moddata.c +++ b/src/api-moddata.c @@ -103,6 +103,14 @@ void moddatatype_dump(Client *client) } } +/** Register module data storage. + * This allows a module to attach custom data to clients, channels, + * memberships, members, or other objects. + * @param module The module registering the moddata + * @param req The ModDataInfo request struct (name, type, callbacks, etc.) + * @returns The ModDataInfo pointer, or NULL on failure. + * @note Call this from MOD_INIT(). + */ ModDataInfo *ModDataAdd(Module *module, ModDataInfo req) { int slotav = 0; /* highest available slot */ @@ -326,6 +334,11 @@ void unload_moddata_commit(ModDataInfo *md) safe_free(md); } +/** Delete module data storage. + * @param md The ModDataInfo to delete + * @note Modules do not need to call this function, + * it is done automatically on module unload. + */ void ModDataDel(ModDataInfo *md) { /* Delete the reference to us first */ diff --git a/src/api-rpc.c b/src/api-rpc.c index 946018387..10ea9fb7d 100644 --- a/src/api-rpc.c +++ b/src/api-rpc.c @@ -96,9 +96,10 @@ RPCHandler *RPCHandlerFind(const char *method) return NULL; } -/** Remove the specified RPC handler - modules should not call this. - * This is done automatically for modules on unload, so is only called internally. - * @param m The PRC handler to remove. +/** Remove an RPC handler. + * @param m The RPC handler to remove. + * @note Modules do not need to call this function, + * it is done automatically on module unload. */ void RPCHandlerDel(RPCHandler *m) { diff --git a/src/api-usermode.c b/src/api-usermode.c index 35608221c..5bb8b4229 100644 --- a/src/api-usermode.c +++ b/src/api-usermode.c @@ -161,9 +161,16 @@ void usermode_add_sorted(Umode *n) } -/* UmodeAdd: - * Add a usermode with character 'ch', if global is set to 1 the usermode is global - * (sent to other servers) otherwise it's a local usermode +/** Register a new user mode. + * @param module The module (usually modinfo->handle) + * @param ch The mode character (eg 'x') + * @param global UMODE_GLOBAL if the mode is sent to other servers, UMODE_LOCAL for local only + * @param unset_on_deoper 1 to automatically unset this mode when the user de-opers + * @param allowed Function to check if a user is allowed to set/unset this mode + * (eg umode_allow_all, umode_allow_opers, umode_allow_none) + * @param mode Pointer to a long that will receive the mode bit + * @returns The Umode pointer, or NULL on failure + * @note Call this from MOD_INIT(). */ Umode *UmodeAdd(Module *module, char ch, int global, int unset_on_deoper, int (*allowed)(Client *client, int what), long *mode) { @@ -243,6 +250,11 @@ Umode *UmodeAdd(Module *module, char ch, int global, int unset_on_deoper, int (* } +/** Delete a user mode. + * @param umode The user mode to delete + * @note Modules do not need to call this function, + * it is done automatically on module unload. + */ void UmodeDel(Umode *umode) { /* Always free the module object */ diff --git a/src/conf.c b/src/conf.c index 882a7f83d..8a2e0019a 100644 --- a/src/conf.c +++ b/src/conf.c @@ -309,7 +309,27 @@ const char *config_var(ConfigEntry *cep) return buf; } -/** Helper function for erroring on duplicate items. +/** Detect and report duplicate configuration directives. + * On first call (when *var is 0), sets *var to 1 and returns 0. + * On subsequent calls (when *var is already 1), reports a + * configuration error, increments the error counter, and returns 1. + * @param var Pointer to a tracking variable (initialize to 0) + * @param ce The configuration entry being checked + * @param errors Pointer to the error counter + * @returns 1 if this is a duplicate, 0 otherwise + * + * Example usage: + * @code + * int has_vhost = 0, has_password = 0; + * int errors = 0; + * for (cep = ce->items; cep; cep = cep->next) + * { + * if (!strcmp(cep->name, "vhost")) + * config_detect_duplicate(&has_vhost, cep, &errors); + * else if (!strcmp(cep->name, "password")) + * config_detect_duplicate(&has_password, cep, &errors); + * } + * @endcode */ int config_detect_duplicate(int *var, ConfigEntry *ce, int *errors) { @@ -501,6 +521,11 @@ int config_parse_flood_generic(const char *str, Configuration *conf, char *block return 1; } +/** Convert a configuration value string to a long, based on the type. + * @param orig The original string value + * @param flags The type of value: CFG_TIME, CFG_SIZE, or CFG_YESNO + * @returns The converted numeric value + */ long config_checkval(const char *orig, unsigned short flags) { char *value; @@ -1502,6 +1527,11 @@ ConfigEntry *config_find_entry(ConfigEntry *ce, const char *name) return cep; } +/** Report a configuration error. + * Used in HOOKTYPE_CONFIGTEST handlers to report issues. + * @param format printf-style format string + * @param ... Format arguments + */ void config_error(FORMAT_STRING(const char *format), ...) { va_list ap; @@ -1516,11 +1546,22 @@ void config_error(FORMAT_STRING(const char *format), ...) unreal_log_raw(ULOG_ERROR, "config", "CONFIG_ERROR_GENERIC", NULL, buffer); } +/** Report a missing required configuration entry. + * @param filename The configuration file name + * @param line The line number + * @param entry The missing entry (eg "set::something" or "deny link::reason") + */ void config_error_missing(const char *filename, int line, const char *entry) { config_error("%s:%d: %s is missing", filename, line, entry); } +/** Report an unknown configuration directive. + * @param filename The configuration file name + * @param line The line number + * @param block The configuration block name + * @param entry The unknown directive name + */ void config_error_unknown(const char *filename, int line, const char *block, const char *entry) { @@ -1570,6 +1611,10 @@ void config_status(FORMAT_STRING(const char *format), ...) unreal_log_raw(ULOG_INFO, "config", "CONFIG_INFO_GENERIC", NULL, buffer); } +/** Report a non-fatal configuration warning. + * @param format printf-style format string + * @param ... Format arguments + */ void config_warn(FORMAT_STRING(const char *format), ...) { va_list ap; @@ -1660,6 +1705,12 @@ int config_test_openfile(ConfigEntry *cep, int flags, mode_t mode, const char *e return 0; } +/** Check if a configuration entry has a blank or empty value. + * If so, report the error via config_error_empty(). + * @param cep The configuration entry to check + * @param block The configuration block name (for the error message) + * @returns 1 if the value is blank or empty, 0 otherwise + */ int config_is_blankorempty(ConfigEntry *cep, const char *block) { if (!cep->value) diff --git a/src/modules.c b/src/modules.c index 02e0374e5..eef6dae5d 100644 --- a/src/modules.c +++ b/src/modules.c @@ -937,6 +937,11 @@ Versionflag *VersionflagFind(char flag) return NULL; } +/** Add a version flag character. + * @param module The module adding the version flag + * @param flag The version flag character + * @returns The Versionflag pointer, or NULL on failure. + */ Versionflag *VersionflagAdd(Module *module, char flag) { Versionflag *vflag; @@ -983,6 +988,12 @@ Versionflag *VersionflagAdd(Module *module, char flag) return vflag; } +/** Delete a version flag. + * @param vflag The version flag to delete + * @param module The module that owns this version flag + * @note Modules do not need to call this function, + * it is done automatically on module unload. + */ void VersionflagDel(Versionflag *vflag, Module *module) { ModuleChild *owner; @@ -1047,6 +1058,12 @@ Hook *HookAddMain(Module *module, int hooktype, int priority, int (*func)(), voi return p; } +/** Delete a hook. + * @param hook The hook to delete + * @returns The next Hook in the list, or NULL. + * @note Modules do not need to call this function, + * it is done automatically on module unload. + */ Hook *HookDel(Hook *hook) { Hook *p, *q; @@ -1083,6 +1100,19 @@ int cnt = 0; return cnt; } +/** Add a callback - internal function. + * Use the CallbackAdd(), CallbackAddVoid(), CallbackAddPVoid(), + * CallbackAddString() or CallbackAddConstString() macros instead. + * @param module The module adding the callback + * @param cbtype The callback type (CALLBACKTYPE_*) + * @param func Function returning int (or NULL) + * @param vfunc Function returning void (or NULL) + * @param pvfunc Function returning void* (or NULL) + * @param stringfunc Function returning char* (or NULL) + * @param conststringfunc Function returning const char* (or NULL) + * @returns The Callback pointer, or NULL on failure. + * @note Only one callback per type can be registered. + */ Callback *CallbackAddMain(Module *module, int cbtype, int (*func)(), void (*vfunc)(), void *(*pvfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)()) { Callback *p; @@ -1118,6 +1148,12 @@ Callback *CallbackAddMain(Module *module, int cbtype, int (*func)(), void (*vfun return p; } +/** Delete a callback. + * @param cb The callback to delete + * @returns The next Callback in the list, or NULL. + * @note Modules do not need to call this function, + * it is done automatically on module unload. + */ Callback *CallbackDel(Callback *cb) { Callback *p, *q; @@ -1144,6 +1180,16 @@ Callback *CallbackDel(Callback *cb) return NULL; } +/** Add a command override handler. + * @param module The module adding the override + * @param name The command name to override (eg: "PRIVMSG") + * @param priority Priority for this override. Lower value = called first. Use 0 for normal. + * @param function The override function to call + * @returns The CommandOverride pointer, or NULL on failure. + * @note Call this from MOD_LOAD() or later, not from MOD_INIT(). + * The command to override may not exist yet during MOD_INIT() + * due to module load order. + */ CommandOverride *CommandOverrideAdd(Module *module, const char *name, int priority, OverrideCmdFunc function) { RealCommand *p; @@ -1195,6 +1241,11 @@ CommandOverride *CommandOverrideAdd(Module *module, const char *name, int priori return ovr; } +/** Delete a command override. + * @param cmd The command override to delete + * @note Modules do not need to call this function, + * it is done automatically on module unload. + */ void CommandOverrideDel(CommandOverride *cmd) { DelListItem(cmd, cmd->command->overriders); @@ -1220,6 +1271,18 @@ void CommandOverrideDel(CommandOverride *cmd) safe_free(cmd); } +/** Call the next command override handler in the chain. + * Call this from your override function to pass control to the + * next override or the original command handler. + * @param ovr The current command override + * @param clictx The client context + * @param client The client issuing the command + * @param mtags Message tags associated with the command + * @param parc Parameter count + * @param parv Parameter array + * @note It is recommended to use the CALL_NEXT_COMMAND_OVERRIDE() macro instead, + * which passes all arguments automatically and is future-proof. + */ void CallCommandOverride(CommandOverride *ovr, ClientContext *clictx, Client *client, MessageTag *mtags, int parc, const char *parv[]) { if (ovr->next)