This document serves to provide information regarding writing wonton modules. 1) Overview a) What is a module? 2) Minimum requirements 3) Examples a) A module that hooks the DCC chat function '.zoom'. b) A module that handles a special ioctl. c) A module that unloads itself inside wonLoad. ------------------------------------------------------------------------------- 1) Overview a) What is a module? A module with respect to wonton is simply something that extends the core functionality of the bot itself. The wonton loader itself does absolutely nothing. It simply waits for IRC and DCC connections to process as well as scheduled events to meet their time criteria. Other than that, it idles. In order to make wonton actually do stuff, one needs to create modules. A module can do anything from gathering statistics about how often upper case letters are used in messages to running an HTTP server internal to wonton that allows people to manage channels and users from the outside world. 2) Minimum requirements In order for something to be considered a wonton module it's required to implement a few functions. Now require is actually a bit of a harsh word. In actuality one could create a wonton module that implemented none of the 3 "required" functions. The module, however, would do absolutely nothing. The reason it would do nothing is because the core would have not interface by which to communicate with that module. Aside from this point, the module functions which should be implemented are: WON_STATUS wonLoad(WON_MODULE_CTX *modctx); This function is the entry point for the module. When this module is loaded this function will be called. Any handlers which need to be registered should be done here. This function is optional and should not be implemented in a "headless" design (where only the wonIoctl function is implemented). WON_STATUS wonIoctl(WON_MODULE_CTX *modctx, uint32 ioctl, WON_IC *wic); This function serves as a medium for other modules to communicate with this module. Other modules can send messages, called IOCTL's which will be passed down to this implemented function. This function is not required to be implemented. Aside from this module being the medium for modules to communicate, it also serves as a method for the core to communicate with the module. For instance, when an irc connection link comes up, the IOCTL WON_IOCTL_IRC_LINK_UP is broadcasted. When a module calls wonConfigurationSave() an ioctl is broadcasted that passes a file descriptor for the in buffer (WON_IOCTL_CONFIG_SAVE). WON_STATUS wonUnload(WON_MODULE_CTX *modctx); This function is the exit point of the module. When the module is to be unloaded from the core this function is called first. If this function returns WON_STATUS_FAILURE then the unload is aborted, otherwise all references to handlers which exist internal to this module are deleted. A well formed module should clean up all of their handlers inside this function. However, in order to make the core robust it has routines which will go through and verify that all references to a module are destroyed before continuing. 3) Examples a) A module that hooks the DCC chat function '.zoom'. #include "won.h" /* This is the callback function for .zoom */ uint32 dccZoom(WON_DCC_PACKET *wdp); WON_STATUS wonLoad(WON_MODULE_CTX *modctx) { /* We want to register our handler for .zoom in position 0 */ wonDccRegisterLayeredHandler(modctx->wonctx, modctx, WON_LAYER_FIRST, ".zoom", 0, dccZoom); /* Log that we've been loaded! */ wonLog(modctx->wonctx,modctx,"zoom module loaded!"); return WON_STATUS_SUCCESS; } WON_STATUS wonUnload(WON_MODULE_CTX *modctx) { /* Deregister our handler for .zoom */ wonDccDeregisterLayeredHandler(modctx->wonctx, modctx, ".zoom", 0, dccZoom); /* Log that we're unloading */ wonLog(modctx->wonctx,modctx,"zoom module unloaded!"); return WON_STATUS_SUCCESS; } /* Whenever someone types .zoom we want to send a message back saying 'Zoom!' */ uint32 dccZoom(WON_DCC_PACKET *wdp) { wonDccSend(wdp->ctx,wdp->dcc,"Zoom!\n"); return WON_STATUS_SUCCESS; } b) A module that handles a special ioctl. #include "won.h" /* Whenever someone sends the MY_PERSONAL_IOCTL to our module we want to set the outBuffer to 1234567. */ #define MY_PERSONAL_IOCTL 24 WON_STATUS wonIoctl(WON_MODULE_CTX *modctx,uint32 ioctl,WON_IC *wic) { switch (ioctl) { case MY_PERSONAL_IOCTL: /* Make sure we have enough storage space */ if ((!wic->outBuffer) || (wic->outLen < 4)) return WON_STATUS_FAILURE; (*((unsigned long *)wic->outBuffer)) = 1234567; break; } return WON_STATUS_SUCCESS; } c) A module that unloads itself inside wonLoad. #include "won.h" WON_STATUS wonLoad(WON_MODULE_CTX *modctx) { wonLog("We're inside wonLoad...let's unload ourselves.."); /* It is not correct to call wonModuleUnload from inside our own module, instead, we must defer the unloading until we're out of our modules context. */ wonModuleDeferredUnload(modctx->wonctx,modctx); return WON_STATUS_SUCCESS; }