unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

modules.h (121323B)

      1 /************************************************************************
      2  *   Unreal Internet Relay Chat Daemon, include/modules.h
      3  *   (C) Carsten V. Munk 2000 <stskeeps@tspre.org>
      4  *
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 1, or (at your option)
      8  *   any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *   GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program; if not, write to the Free Software
     17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18  *
     19  *   $Id$
     20  */
     21 #ifndef MODULES_H
     22 #define MODULES_H
     23 #include "types.h"
     24 #define MAXCUSTOMHOOKS  30
     25 #define MAXHOOKTYPES	200
     26 #define MAXCALLBACKS	30
     27 #define MAXEFUNCTIONS	128
     28 #if defined(_WIN32)
     29  #define MOD_EXTENSION "dll"
     30  #define DLLFUNC	_declspec(dllexport)
     31  #define irc_dlopen(x,y) LoadLibrary(x)
     32  #define irc_dlclose FreeLibrary
     33  #define irc_dlsym(x,y,z) z = (void *)GetProcAddress(x,y)
     34  #define irc_dlerror our_dlerror
     35 #else
     36  #define MOD_EXTENSION "so"
     37  #define irc_dlopen dlopen
     38  #define irc_dlclose dlclose
     39  #if defined(UNDERSCORE)
     40   #define irc_dlsym(x,y,z) z = obsd_dlsym(x,y)
     41  #else
     42   #define irc_dlsym(x,y,z) z = dlsym(x,y)
     43  #endif
     44  #define irc_dlerror dlerror
     45  #define DLLFUNC 
     46 #endif
     47 
     48 #define EVENT(x) void (x) (void *data)
     49 
     50 /* Casts to int, void, void *, and char * function pointers */
     51 #define TO_INTFUNC(x) (int (*)())(x)
     52 #define TO_VOIDFUNC(x) (void (*)())(x)
     53 #define TO_PVOIDFUNC(x) (void *(*)())(x)
     54 #define TO_PCHARFUNC(x) (char *(*)())(x)
     55 
     56 typedef struct Event Event;
     57 typedef struct EventInfo EventInfo;
     58 typedef struct Hook Hook;
     59 typedef struct Hooktype Hooktype;
     60 typedef struct Callback Callback;
     61 typedef struct Efunction Efunction;
     62 typedef enum EfunctionType EfunctionType;
     63 
     64 /*
     65  * Module header that every module must include, with the name of
     66  * mod_header
     67 */
     68 
     69 typedef struct ModuleHeader {
     70 	char *name;
     71 	char *version;
     72 	char *description;
     73 	char *author;
     74 	char *modversion;
     75 } ModuleHeader;
     76 
     77 typedef struct Module Module;
     78 
     79 typedef struct ModuleChild
     80 {
     81 	struct ModuleChild *prev, *next; 
     82 	Module *child; /* Aww. aint it cute? */
     83 } ModuleChild;
     84 
     85 typedef struct {
     86 	int size;
     87 	int module_load;
     88 	Module *handle;
     89 } ModuleInfo;
     90 
     91 
     92 typedef enum ModuleObjectType {
     93 	MOBJ_EVENT = 1,
     94 	MOBJ_HOOK = 2,
     95 	MOBJ_COMMAND = 3,
     96 	MOBJ_HOOKTYPE = 4,
     97 	MOBJ_VERSIONFLAG = 5,
     98 	MOBJ_UMODE = 7,
     99 	MOBJ_COMMANDOVERRIDE = 8,
    100 	MOBJ_EXTBAN = 9,
    101 	MOBJ_CALLBACK = 10,
    102 	MOBJ_ISUPPORT = 11,
    103 	MOBJ_EFUNCTION = 12,
    104 	MOBJ_CMODE = 13,
    105 	MOBJ_MODDATA = 14,
    106 	MOBJ_VALIDATOR = 15,
    107 	MOBJ_CLICAP = 16,
    108 	MOBJ_MTAG = 17,
    109 	MOBJ_HISTORY_BACKEND = 18,
    110 	MOBJ_RPC = 19,
    111 } ModuleObjectType;
    112 
    113 typedef struct Umode Umode;
    114 struct Umode {
    115 	Umode *prev, *next;
    116 	long mode; /**< Mode mask */
    117 	char letter; /**< Mode character */
    118 	int unset_on_deoper; /**< When set to 1 then this user mode will be unset on de-oper */
    119 	int (*allowed)(Client *client, int what); /**< The 'is this user allowed to set this mode?' routine */
    120 	char unloaded; /**< Internal flag to indicate module is being unloaded */
    121 	Module *owner; /**< Module that owns this user mode */
    122 };
    123 
    124 typedef enum ModDataType {
    125 	MODDATATYPE_LOCAL_VARIABLE	= 1,
    126 	MODDATATYPE_GLOBAL_VARIABLE	= 2,
    127 	MODDATATYPE_CLIENT		= 3,
    128 	MODDATATYPE_LOCAL_CLIENT	= 4,
    129 	MODDATATYPE_CHANNEL		= 5,
    130 	MODDATATYPE_MEMBER		= 6,
    131 	MODDATATYPE_MEMBERSHIP		= 7,
    132 } ModDataType;
    133 
    134 typedef enum ModDataSync {
    135 	MODDATA_SYNC_NORMAL		= 1, /**< Sync normally via MD command */
    136 	MODDATA_SYNC_EARLY		= 2, /**< Attempt to (also) sync early in the UID command */
    137 } ModDataSync;
    138 
    139 typedef struct ModDataInfo ModDataInfo;
    140 
    141 struct ModDataInfo {
    142 	ModDataInfo *prev, *next;
    143 	char *name; /**< Name for this moddata */
    144 	Module *owner; /**< Owner of this moddata */
    145 	ModDataType type; /**< Type of module data (eg: for client, channel, etc..) */
    146 	int slot; /**< Assigned slot */
    147 	char unloaded; /**< Module being unloaded? */
    148 	void (*free)(ModData *m); /**< Function will be called when the data needs to be freed (may be NULL if not using dynamic storage) */
    149 	const char *(*serialize)(ModData *m); /**< Function which converts the data to a string. May return NULL if 'm' contains no data (since for example m->ptr may be NULL). */
    150 	void (*unserialize)(const char *str, ModData *m); /**< Function which converts the string back to data */
    151 	ModDataSync sync; /**< Send in netsynch (when servers connect) */
    152 	int remote_write; /**< Allow remote servers to set/unset this moddata, even if it they target one of our own clients */
    153 	int self_write; /**< Allow remote servers to set/unset moddata of their own server object (irc1.example.net writing the MD object of irc1.example.net) */
    154 };
    155 
    156 #define moddata_client(acptr, md)    acptr->moddata[md->slot]
    157 #define moddata_local_client(acptr, md)    acptr->local->moddata[md->slot]
    158 #define moddata_channel(channel, md)   channel->moddata[md->slot]
    159 #define moddata_member(m, md)        m->moddata[md->slot]
    160 #define moddata_membership(m, md)    m->moddata[md->slot]
    161 #define moddata_local_variable(md)         local_variable_moddata[md->slot]
    162 #define moddata_global_variable(md)        global_variable_moddata[md->slot]
    163 
    164 /* Can bypass message restriction - Types */
    165 typedef enum BypassChannelMessageRestrictionType {
    166 	BYPASS_CHANMSG_EXTERNAL = 1,
    167 	BYPASS_CHANMSG_MODERATED = 2,
    168 	BYPASS_CHANMSG_COLOR = 3,
    169 	BYPASS_CHANMSG_CENSOR = 4,
    170 	BYPASS_CHANMSG_NOTICE = 5,
    171 } BypassChannelMessageRestrictionType;
    172 
    173 /** @defgroup ChannelModeAPI Channel mode API
    174  * @{
    175  */
    176 
    177 #define EXCHK_ACCESS		0 /**< Check user access */
    178 #define EXCHK_ACCESS_ERR	1 /**< Check user access and send error to user */
    179 #define EXCHK_PARAM		2 /**< Check parameter */
    180 
    181 /* return values for EXCHK_ACCESS*: */
    182 #define EX_DENY			0  /**< MODE change disallowed, except in case of operoverride */
    183 #define EX_ALLOW		1  /**< MODE change allowed */
    184 #define EX_ALWAYS_DENY		-1 /**< MODE change disallowed, even in case of operoverride */
    185 
    186 #define EXSJ_SAME		0 /**< SJOIN: Parameters are the same */
    187 #define EXSJ_WEWON		1 /**< SJOIN: We won! w00t */
    188 #define EXSJ_THEYWON		2 /**< SJOIN: They won :( */
    189 #define EXSJ_MERGE		3 /**< SJOIN: Merging of modes, neither won nor lost */
    190 
    191 /** Channel mode bit/value */
    192 typedef unsigned long Cmode_t;
    193 
    194 typedef enum CmodeType {
    195 	CMODE_NORMAL=0,
    196 	CMODE_MEMBER=1,
    197 } CmodeType;
    198 
    199 #define RANK_CHANOWNER  4000
    200 #define RANK_CHANADMIN  3000
    201 #define RANK_CHANOP     2000
    202 #define RANK_HALFOP     1000
    203 #define RANK_VOICE        -1
    204 
    205 /** Channel mode handler.
    206  * This struct contains all extended channel mode information,
    207  * like the flag, mode, their handler functions, etc.
    208  *
    209  * @note For a channel mode without parameters you only need to set 'flag'
    210  * and set the 'is_ok' function. All the rest is for parameter modes
    211  * or is optional.
    212  */
    213 typedef struct Cmode Cmode;
    214 struct Cmode {
    215 	Cmode *prev, *next;
    216 
    217 	/** mode character (like 'Z') */
    218 	char		letter;
    219 
    220 	CmodeType	type;
    221 
    222 	/** If type is CMODE_NORMAL, then bitmask (eg: 0x10) that
    223 	 * is used in channel->mode.mode
    224 	 */
    225 	Cmode_t		mode;
    226 
    227 	/** If type is CMODE_MEMBER, then the prefix used in NAMES etc (eg @) */
    228 	char		prefix;
    229 
    230 	/** If type is CMODE_MEMBER, then the prefix used in SJOIN (eg @) */
    231 	char		sjoin_prefix;
    232 
    233 	/** If type is CMODE_MEMBER, then the rank of this prefix.
    234 	 * Higher ranking = more rights.
    235 	 * This is used, for example, in NAMES without NAMESX when we can only
    236 	 * show one symbol but not all.
    237 	 * For the shipped modules vhoaq we use the RANK_* values.
    238 	 */
    239 	int		rank;
    240 
    241 	/** Number of parameters (1 or 0) */
    242 	int		paracount;
    243 
    244 	/** Check access or parameter of the channel mode.
    245 	 * @param client	The client
    246 	 * @param channel	The channel
    247 	 * @param para		The parameter (NULL for paramless modes)
    248 	 * @param checkt	Check type, see EXCHK_* macros
    249 	 * @param what		MODE_ADD or MODE_DEL
    250 	 * @returns EX_DENY, EX_ALLOW or EX_ALWAYS_DENY
    251 	 */
    252 	int (*is_ok)(Client *client, Channel *channel, char mode, const char *para, int checkt, int what);
    253 
    254 	/** Store parameter in memory for channel.
    255 	 * This function pointer is NULL (unused) for modes without parameters.
    256 	 * @param list		The list, this usually points to channel->mode.mode_params.
    257 	 * @param para		The parameter to store.
    258 	 * @returns the head of the list, RTFS if you wonder why.
    259 	 * @note IMPORTANT: only allocate a new paramstruct if you need to.
    260 	 *       Search for any current one first! Eg: in case of mode +y 5 and then +y 6 later without -y.
    261 	 */
    262 	void *(*put_param)(void *list, const char *para);
    263 
    264 	/** Get the stored parameter as a readable/printable string.
    265 	 * This function pointer is NULL (unused) for modes without parameters.
    266 	 * @param parastruct	The parameter struct
    267 	 * @returns a pointer to the string (temporary storage)
    268 	 */
    269 	const char *(*get_param)(void *parastruct);
    270 
    271 	/** Convert input parameter to output.
    272 	 * This converts stuff like where a MODE +l "1aaa" becomes "1".
    273 	 *
    274 	 * This function pointer is NULL (unused) for modes without parameters.
    275 	 * @param para		The input parameter.
    276 	 * @param client	The client that the mode request came from (can be NULL!)
    277 	 * @param channel	The channel that the mode request came from (can be NULL!)
    278 	 * @returns pointer to output string (temporary storage)
    279 	 * @note The 'client' field will be NULL if for example called for set::modes-on-join.
    280 	 * @note You should probably not use 'client' or 'channel' in most cases.
    281 	 *       In particular you MUST NOT SEND ERRORS to the client.
    282 	 *       This should be done in is_ok() and not in conv_param().
    283 	 */
    284 	const char *(*conv_param)(const char *para, Client *client, Channel *channel);
    285 
    286 	/** Free and remove parameter from list.
    287 	 * This function pointer is NULL (unused) for modes without parameters.
    288 	 * @param parastruct	The parameter struct
    289 	 * @param soft		This is set to 1 if you may 'resist freeing'
    290 	 *			(used by floodprot module to have active F profile even if -F).
    291 	 * @returns Normally return 0, must return 1 if it 'resisted' freeing.
    292 	 * @note In most cases you will just call safe_free() on 'list'
    293 	 */
    294 	int (*free_param)(void *parastruct, int soft);
    295 
    296 	/** duplicate a struct and return a pointer to duplicate.
    297 	 * This function pointer is NULL (unused) for modes without parameters.
    298 	 * @param parastruct		The parameter struct
    299 	 * @returns pointer to newly allocated struct.
    300 	 * @note In most cases you will simply safe_alloc() and memcpy()
    301 	 */
    302 	void *(*dup_struct)(void *parastruct);
    303 
    304 	/** Compares two parameters and decides who wins the SJOIN fight.
    305 	 * When syncing channel modes (cmd_sjoin) a parameter conflict may occur, things like
    306 	 * "+l 5" vs "+l 10". This function should determinate who wins the fight.
    307 	 * This decision should, of course, not be random. It needs to decide according to
    308 	 * the same principles on all servers on the IRC network. Examples of such
    309 	 * comparisons are "highest wins" (+l) and a strcmp() check (+k/+L).
    310 	 * 
    311 	 * This function pointer is NULL (unused) for modes without parameters.
    312 	 * @param channel	The channel that the fight is about
    313 	 * @param our		Our parameter struct
    314 	 * @param their		Their parameter struct
    315 	 */
    316 	int (*sjoin_check)(Channel *channel, void *our, void *their);
    317 
    318 	/** Local channel mode? Prevents remote servers from setting/unsetting this */
    319 	char local;
    320 	
    321 	/** Unsetting also eats/requires a parameter. Unusual, but possible. */
    322 	char unset_with_param;
    323 
    324 	/** Is this mode available for chanmode +f, and if so for which flood type?
    325 	 * eg 'j' for join flood.
    326 	 */
    327 	char flood_type_action;
    328 
    329 	/** Is this mode being unloaded?
    330 	 * This is set to 1 if the chanmode module providing this mode is unloaded
    331 	 * and we are waiting to see if in our new round of loads a "new" chanmode
    332 	 * module will popup to take this mode. This only happens during a rehash,
    333 	 * should never be 0 outside an internal rehash.
    334 	 */
    335 	char unloaded;
    336 
    337 	/** Slot number - Can be used instead of GETPARAMSLOT() */
    338 	int param_slot;
    339 	
    340 	/** Module owner */
    341         Module *owner;
    342 };
    343 
    344 /** The struct used to register a channel mode handler.
    345  * For documentation, see Cmode struct.
    346  */
    347 typedef struct {
    348 	char		letter;
    349 	CmodeType	type;
    350 	char		prefix;
    351 	char		sjoin_prefix;
    352 	int		rank;
    353 	int		paracount;
    354 	int		(*is_ok)(Client *,Channel *, char mode, const char *para, int, int);
    355 	void *		(*put_param)(void *, const char *);
    356 	const char *	(*get_param)(void *);
    357 	const char *	(*conv_param)(const char *, Client *, Channel *);
    358 	int		(*free_param)(void *, int);
    359 	void *		(*dup_struct)(void *);
    360 	int		(*sjoin_check)(Channel *, void *, void *);
    361 	char		local;
    362 	char		unset_with_param;
    363 	char		flood_type_action;
    364 } CmodeInfo;
    365 
    366 /** Get a slot number for a param - eg GETPARAMSLOT('k') */
    367 #define GETPARAMSLOT(x)	param_to_slot_mapping[x]
    368 
    369 /** Get a cmode handler by slot - for example for [dont use this]: GETPARAMHANDLERBYSLOT(5)->get_param(channel) */
    370 #define GETPARAMHANDLERBYSLOT(slotid)	ParamTable[slotid]
    371 
    372 /** Same as GETPARAMHANDLERBYSLOT but then by letter - like [dont use this]: GETPARAMHANDLERBYSLOT('k')->get_param(channel) */
    373 #define GETPARAMHANDLERBYLETTER(x)	ParamTable[GETPARAMSLOT(x)]
    374 
    375 /** Get paramter data struct - for like: ((aModejEntry *)GETPARASTRUCT(channel, 'j'))->t */
    376 #define GETPARASTRUCT(mychannel, mychar)	channel->mode.mode_params[GETPARAMSLOT(mychar)]
    377 
    378 #define GETPARASTRUCTEX(v, mychar)	v[GETPARAMSLOT(mychar)]
    379 
    380 /** @} */
    381 
    382 #define CMP_GETSLOT(x) GETPARAMSLOT(x)
    383 #define CMP_GETHANDLERBYSLOT(x) GETPARAMHANDLERBYSLOT(x)
    384 #define CMP_GETHANDLERBYLETTER(x) GETPARAMHANDLERBYLETTER(x)
    385 #define CMP_GETSTRUCT(x,y) GETPARASTRUCT(x,y)
    386 
    387 /*** Extended bans ***/
    388 
    389 typedef enum ExtbanCheck {
    390 	EXBCHK_ACCESS=0,	/**< Check access */
    391 	EXBCHK_ACCESS_ERR=1,	/**< Check access and send error */
    392 	EXBCHK_PARAM=2		/**< Check if the parameter is valid */
    393 } ExtbanCheck;
    394 
    395 typedef enum ExtbanType {
    396 	EXBTYPE_BAN=0,		/**< Ban (channel mode +b) */
    397 	EXBTYPE_EXCEPT=1,	/**< Ban exception (channel mode +e) */
    398 	EXBTYPE_INVEX=2,	/**< Invite exception (channel mode +I) */
    399 	EXBTYPE_TKL=3		/**< TKL or other generic matcher outside banning routines */
    400 } ExtbanType;
    401 
    402 #define BCTX_CONV_OPTION_WRITE_LETTER_BANS	1 /* Always write letter extbans in output of conv_param */
    403 
    404 #define EXTBANTABLESZ		32
    405 
    406 typedef enum ExtbanOptions {
    407         EXTBOPT_CHSVSMODE=0x1,		/**< SVSMODE -b/-e/-I will clear this ban (UNUSED as of 6.0.1+) */
    408         EXTBOPT_ACTMODIFIER=0x2,	/**< Action modifier (not a matcher). These are extended bans like ~q/~n/~j. */
    409         EXTBOPT_NOSTACKCHILD=0x4,	/**< Disallow prefixing with another extban. Eg disallow ~n:~T:censor:xyz */
    410         EXTBOPT_INVEX=0x8,		/**< Available for use with +I too */
    411         EXTBOPT_TKL=0x10		/**< Available for use in TKL's too (eg: /GLINE ~a:account) */
    412 } ExtbanOptions;
    413 
    414 typedef struct {
    415 	Client *client;		/**< Client to check, can be a remote client */
    416 	Channel *channel;	/**< Channel to check */
    417 	const char *banstr;	/**< Mask string (ban) */
    418 	int ban_check_types;	/**< Ban types to check for, one or more of BANCHK_* OR'd together */
    419 	const char *msg;	/**< Message, only for some BANCHK_* types (for censoring text) */
    420 	const char *error_msg;	/**< Error message, can be NULL */
    421 	int no_extbans;		/**< Set to 1 to disable extended bans checking - only nick!user@host allowed */
    422 	int what;		/**< MODE_ADD or MODE_DEL (for is_ok) */
    423 	ExtbanType ban_type;	/**< EXBTYPE_BAN or EXBTYPE_EXCEPT (for is_ok) */
    424 	ExtbanCheck is_ok_check;/**< One of EXBCHK_* (for is_ok) */
    425 	int conv_options;	/**< One of BCTX_CONV_OPTION_* (for conv_param) */
    426 } BanContext;
    427 
    428 typedef struct Extban Extban;
    429 
    430 struct Extban {
    431 	Extban *prev, *next;
    432 
    433 	/** extended ban character */
    434 	char letter;
    435 
    436 	/** extended ban name */
    437 	char *name;
    438 
    439 	/** extban options */
    440 	ExtbanOptions options;
    441 
    442 	unsigned int is_banned_events;	/**< Which BANCHK_* events to listen on */
    443 
    444 	int (*is_ok)(BanContext *b);
    445 
    446 	/** Convert input parameter to output.
    447 	 * like with normal bans '+b blah' gets '+b blah!*@*', and it allows
    448 	 * you to limit the length of the ban too.
    449 	 * return value: pointer to output string (temp. storage)
    450 	 */
    451 	const char *(*conv_param)(BanContext *b, Extban *handler);
    452 
    453 	/** Checks if the user is affected by this ban [optional].
    454 	 * This may be set to NULL if you have is_banned_events set to 0 (zero),
    455 	 * this can be useful if you don't actually ban a user, eg for text bans.
    456 	 * This function is called from is_banned() and two other places.
    457 	 */
    458 	int (*is_banned)(BanContext *b);
    459 
    460 	/** extbans module */
    461 	Module *owner;
    462 
    463 	/** Set to 1 during rehash when module is unloading (which may be re-used, and then set to 0) */
    464 	char unloaded;
    465 
    466 	/** Set to 1 when it is preregistered in MOD_TEST already */
    467 	char preregistered;
    468 };
    469 
    470 typedef struct {
    471 	char letter;
    472 	char *name;
    473 	ExtbanOptions options;
    474 	int (*is_ok)(BanContext *b);
    475 	const char *(*conv_param)(BanContext *b, Extban *handler);
    476 	int (*is_banned)(BanContext *b);
    477 	unsigned int is_banned_events;
    478 } ExtbanInfo;
    479 
    480 
    481 typedef struct Command Command;
    482 struct Command {
    483 	Command *prev, *next;
    484 	RealCommand *cmd;
    485 };
    486 
    487 typedef struct Versionflag Versionflag;
    488 struct Versionflag {
    489 	Versionflag *prev, *next;
    490 	char flag;
    491 	ModuleChild *parents;
    492 };
    493 
    494 /* This type needs a forward declaration: */
    495 typedef struct MessageTagHandler MessageTagHandler;
    496 
    497 #define CLICAP_FLAGS_NONE               0x0
    498 #define CLICAP_FLAGS_ADVERTISE_ONLY     0x4
    499 
    500 typedef struct ClientCapability ClientCapability;
    501 struct ClientCapability {
    502 	ClientCapability *prev, *next;
    503 	char *name;                              /**< The name of the CAP */
    504 	long cap;                                /**< The acptr->user->proto we should set (if any, can be 0, like for sts) */
    505 	int flags;                               /**< A flag from CLICAP_FLAGS_* */
    506 	int (*visible)(Client *);                /**< Should the capability be visible? Note: parameter may be NULL. [optional] */
    507 	const char *(*parameter)(Client *);      /**< CAP parameters. Note: parameter may be NULL. [optional] */
    508 	MessageTagHandler *mtag_handler;         /**< For reverse dependency */
    509 	Module *owner;                           /**< Module introducing this CAP. */
    510 	char unloaded;                           /**< Internal flag to indicate module is being unloaded */
    511 };
    512 
    513 typedef struct {
    514 	char *name;
    515 	int flags;
    516 	int (*visible)(Client *);
    517 	const char *(*parameter)(Client *);
    518 } ClientCapabilityInfo;
    519 
    520 /** @defgroup MessagetagAPI Message tag API
    521  * @{
    522  */
    523 
    524 /** No special message-tag handler flags */
    525 #define MTAG_HANDLER_FLAGS_NONE			0x0
    526 /** This message-tag does not have a CAP REQ xx (eg: for "msgid") */
    527 #define MTAG_HANDLER_FLAGS_NO_CAP_NEEDED	0x1
    528 
    529 /** Message Tag Handler */
    530 struct MessageTagHandler {
    531 	MessageTagHandler *prev, *next;
    532 	char *name;                                             /**< The name of the message-tag */
    533 	int flags;                                              /**< A flag of MTAG_HANDLER_FLAGS_* */
    534 	int (*is_ok)(Client *, const char *, const char *);     /**< Verify syntax and access rights */
    535 	int (*should_send_to_client)(Client *);                 /**< Tag may be sent to this client (normally NULL!) */
    536 	Module *owner;                                          /**< Module introducing this CAP. */
    537 	ClientCapability *clicap_handler;                       /**< Client capability handler associated with this */
    538 	char unloaded;                                          /**< Internal flag to indicate module is being unloaded */
    539 };
    540 
    541 /** The struct used to register a message tag handler.
    542  * For documentation, see the MessageTagHandler struct.
    543  */
    544 typedef struct {
    545 	char *name;
    546 	int flags;
    547 	int (*is_ok)(Client *, const char *, const char *);
    548 	int (*should_send_to_client)(Client *);
    549 	ClientCapability *clicap_handler;
    550 } MessageTagHandlerInfo;
    551 
    552 /** @} */
    553 
    554 /** Filter for history: the command / type of the request */
    555 typedef enum HistoryFilterCommand {
    556         HFC_SIMPLE=1,		/**< Simple history request for lines / unixtime */
    557         HFC_BEFORE=2,		/**< CHATHISTORY BEFORE */
    558         HFC_AFTER=3,		/**< CHATHISTORY AFTER */
    559         HFC_LATEST=4,		/**< CHATHISTORY LATEST */
    560         HFC_AROUND=5,		/**< CHATHISTORY AROUND */
    561         HFC_BETWEEN=6		/**< CHATHISTORY BETWEEN */
    562 } HistoryFilterCommand;
    563 
    564 /** Filter for history get requests */
    565 typedef struct HistoryFilter HistoryFilter;
    566 struct HistoryFilter {
    567         HistoryFilterCommand cmd;	/**< Filter command, one of HistoryFilterCommand */
    568         int last_lines;			/**< Used by HFC_SIMPLE */
    569         int last_seconds;		/**< Used by HFC_SIMPLE */
    570         char *timestamp_a;		/**< First parameter of HFC_* (either this or msgid_a) */
    571         char *msgid_a;			/**< First parameter of HFC_* (either this or timestamp_a) */
    572         char *timestamp_b;		/**< Second parameter of HFC_BETWEEN (either this or msgid_b) */
    573         char *msgid_b;			/**< Second parameter of HFC_BETWEEN (either this or timestamp_b) */
    574         int limit;			/**< Maximum number of lines to return */
    575 };
    576 
    577 /** History log lines, used by HistoryResult among others */
    578 typedef struct HistoryLogLine HistoryLogLine;
    579 struct HistoryLogLine {
    580 	HistoryLogLine *prev, *next;
    581 	time_t t;
    582 	MessageTag *mtags;
    583 	char line[1];
    584 };
    585 
    586 typedef struct HistoryResult HistoryResult;
    587 struct HistoryResult {
    588         char *object;					/**< Name of the history object, eg '#test' */
    589         HistoryLogLine *log;				/**< The resulting log lines */
    590         HistoryLogLine *log_tail;			/**< Last entry in the log lines */
    591 };
    592 
    593 /** History Backend */
    594 typedef struct HistoryBackend HistoryBackend;
    595 struct HistoryBackend {
    596 	HistoryBackend *prev, *next;
    597 	char *name;                                   /**< The name of the history backend (eg: "mem") */
    598 	int (*history_set_limit)(const char *object, int max_lines, long max_time); /**< Impose a limit on a history object */
    599 	int (*history_add)(const char *object, MessageTag *mtags, const char *line); /**< Add to history */
    600 	HistoryResult *(*history_request)(const char *object, HistoryFilter *filter);  /**< Request history */
    601 	int (*history_destroy)(const char *object);  /**< Destroy history of this object completely */
    602 	Module *owner;                                /**< Module introducing this */
    603 	char unloaded;                                /**< Internal flag to indicate module is being unloaded */
    604 };
    605 
    606 /** The struct used to register a history backend.
    607  * For documentation, see the History Backend struct above.
    608  */
    609 typedef struct {
    610 	char *name;
    611 	int (*history_set_limit)(const char *object, int max_lines, long max_time);
    612 	int (*history_add)(const char *object, MessageTag *mtags, const char *line);
    613 	HistoryResult *(*history_request)(const char *object, HistoryFilter *filter);
    614 	int (*history_destroy)(const char *object);
    615 } HistoryBackendInfo;
    616 
    617 /** @defgroup RPCAPI RPC API
    618  * @{
    619  */
    620 
    621 /** No special flags set */
    622 #define RPC_HANDLER_FLAGS_NONE			0x0
    623 #define RPC_HANDLER_FLAGS_UNFILTERED		0x1	/**< Don't filter input (don't reject strings bigger than 510 in length or containing \r or \n) */
    624 
    625 /** RPC Tag Handler */
    626 typedef struct RPCHandler RPCHandler;
    627 struct RPCHandler {
    628 	RPCHandler *prev, *next;
    629 	char *method;                                             /**< Name of the method handler, eg "client.get" */
    630 	int flags;                                                /**< A flag of RPC_HANDLER_FLAG_* */
    631 	LogLevel loglevel;                                        /**< Log level to use for this call: for example ULOG_DEBUG for .list calls, leave 0 for default */
    632 	void (*call)(Client *, json_t *request, json_t *params);  /**< RPC call: use RPC_CALL_FUNC() ! */
    633 	Module *owner;                                            /**< Module introducing this. */
    634 	char unloaded;                                            /**< Internal flag to indicate module is being unloaded */
    635 };
    636 
    637 /** The struct used to register a RPC handler.
    638  * For documentation, see the RPCHandler struct.
    639  */
    640 typedef struct {
    641 	char *method;
    642 	int flags;
    643 	LogLevel loglevel;
    644 	void (*call)(Client *, json_t *request, json_t *params);
    645 } RPCHandlerInfo;
    646 
    647 /** RPC function - used by all RPC call functions.
    648  * This is used in the code like <pre>RPC_CALL_FUNC(rpc_call_xyz)</pre> as a function definition.
    649  * It allows the UnrealIRCd devs to add or change parameters to the function without
    650  * (necessarily) breaking your code.
    651  * @param client      The client issueing the request
    652  * @param request     The full JSON-RPC request
    653  * @param params      Parameters of the JSON-RPC call
    654  * @note You are expected to call rpc_response() or rpc_error() on the request.
    655  */
    656 #define RPC_CALL_FUNC(x) void (x) (Client *client, json_t *request, json_t *params)
    657 
    658 /** @} */
    659 
    660 struct Hook {
    661 	Hook *prev, *next;
    662 	int priority;
    663 	int type;
    664 	union {
    665 		int (*intfunc)();
    666 		void (*voidfunc)();
    667 		char *(*stringfunc)();
    668 		const char *(*conststringfunc)();
    669 	} func;
    670 	Module *owner;
    671 };
    672 
    673 struct Callback {
    674 	Callback *prev, *next;
    675 	short type;
    676 	union {
    677 		int (*intfunc)();
    678 		void (*voidfunc)();
    679 		void *(*pvoidfunc)();
    680 		char *(*stringfunc)();
    681 		const char *(*conststringfunc)();
    682 	} func;
    683 	Module *owner;
    684 	char willberemoved; /* will be removed on next rehash? (eg the 'old'/'current' one) */
    685 };
    686 
    687 /* Definition of an efunction: a MANDATORY Extern Function (in a module),
    688  * for things like do_join, join_channel, etc.
    689  * The difference between callbacks and efunctions are:
    690  * - efunctions are (usually) mandatory, while callbacks can be optional
    691  * - efunctions are meant for internal usage, so 3rd party modules are
    692  *   not allowed to add them.
    693  * - all efunctions are declared as function pointers in modules.c
    694  */
    695 struct Efunction {
    696 	Efunction *prev, *next;
    697 	short type;
    698 	union {
    699 		int (*intfunc)();
    700 		void (*voidfunc)();
    701 		void *(*pvoidfunc)();
    702 		char *(*stringfunc)();
    703 		const char *(*conststringfunc)();
    704 	} func;
    705 	Module *owner;
    706 	char willberemoved; /* will be removed on next rehash? (eg the 'old'/'current' one) */
    707 };
    708 
    709 struct Hooktype {
    710 	short id;
    711 	char *string;
    712 	ModuleChild *parents;
    713 };
    714 
    715 typedef struct ISupport ISupport;
    716 struct ISupport {
    717 	ISupport *prev, *next;
    718 	char *token;
    719 	char *value;
    720 	Module *owner;
    721 };
    722 
    723 typedef struct ModuleObject {
    724 	struct ModuleObject *prev, *next;
    725 	ModuleObjectType type;
    726 	union {
    727 		Event *event;
    728 		Hook *hook;
    729 		Command *command;
    730 		Hooktype *hooktype;
    731 		Versionflag *versionflag;
    732 		Umode *umode;
    733 		CommandOverride *cmdoverride;
    734 		Extban *extban;
    735 		Callback *callback;
    736 		Efunction *efunction;
    737 		ISupport *isupport;
    738 		Cmode *cmode;
    739 		ModDataInfo *moddata;
    740 		OperClassValidator *validator;
    741 		ClientCapability *clicap;
    742 		MessageTagHandler *mtag;
    743 		HistoryBackend *history_backend;
    744 		RPCHandler *rpc;
    745 	} object;
    746 } ModuleObject;
    747 
    748 /*
    749  * What we use to keep track internally of the modules
    750 */
    751 
    752 #define MODERR_NOERROR 0
    753 #define MODERR_EXISTS  1
    754 #define MODERR_NOSPACE 2
    755 #define MODERR_INVALID 3
    756 #define MODERR_NOTFOUND 4
    757 
    758 extern unsigned int ModuleGetError(Module *module);
    759 extern const char *ModuleGetErrorStr(Module *module);
    760 extern unsigned int ModuleGetOptions(Module *module);
    761 extern void ModuleSetOptions(Module *module, unsigned int options, int action);
    762 
    763 struct Module
    764 {
    765 	struct Module *prev, *next;
    766 	int priority;
    767 	ModuleHeader    *header; /* The module's header */
    768 #ifdef _WIN32
    769 	HMODULE dll;		/* Return value of LoadLibrary */
    770 #else
    771 	void	*dll;		/* Return value of dlopen */
    772 #endif	
    773 	unsigned char flags;    /* 8-bits for flags .. [<- this is misleading, there's mod->flags = .. everywhere] */
    774 	ModuleChild *children;
    775 	ModuleObject *objects;
    776 	ModuleInfo modinfo; /* Used to store handle info for module */
    777 	unsigned char options;
    778 	unsigned char errorcode;
    779 	char *tmp_file;
    780 	char *relpath;
    781 	unsigned long mod_sys_version;
    782 	unsigned int compiler_version;
    783 };
    784 /*
    785  * Symbol table
    786 */
    787 
    788 #define MOD_OPT_PERM		0x0001 /* Permanent module (not unloadable) */
    789 #define MOD_OPT_OFFICIAL	0x0002 /* Official module, do not set "tainted" */
    790 #define MOD_OPT_PERM_RELOADABLE	0x0004 /* Module is semi-permanent: it can be re-loaded but not un-loaded */
    791 #define MOD_OPT_GLOBAL		0x0008 /* Module is required to be loaded globally (i.e. across the entire network) */
    792 #define MOD_OPT_PRIORITY	0x1000 /* Module wants a higher or lower priority for unloading, init, load, etc */
    793 #define MOD_OPT_UNLOAD_PRIORITY	0x1000 /* Alias for MOD_OPT_PRIORITY */
    794 #define MOD_Dep(name, container,module) {#name, (vFP *) &container, module}
    795 
    796 /** Websocket module should init 'first' because it handles sockets */
    797 #define WEBSOCKET_MODULE_PRIORITY_INIT		-1000000000
    798 /** Websocket module should unload 'last' because it handles sockets */
    799 #define WEBSOCKET_MODULE_PRIORITY_UNLOAD	1000000000
    800 
    801 /** Event structs */
    802 struct Event {
    803 	Event		*prev;		/**< Previous event (linked list) */
    804 	Event		*next;		/**< Next event (linked list) */
    805 	char		*name;		/**< Name of the event */
    806 	long		every_msec;	/**< How often we should run this event */
    807 	long		count;		/**< How many times this event should run (0 = infinite) */
    808 	vFP		event;		/**< Actual function to call */
    809 	void		*data;		/**< The data to pass in the function call */
    810 	struct timeval	last_run;	/**< Last time this event ran */
    811 	char		deleted;	/**< Set to 1 if this event is marked for deletion */
    812 	Module		*owner;		/**< To which module this event belongs */
    813 };
    814 
    815 #define EMOD_EVERY 0x0001
    816 #define EMOD_HOWMANY 0x0002
    817 #define EMOD_NAME 0x0004
    818 #define EMOD_EVENT 0x0008
    819 #define EMOD_DATA 0x0010
    820 
    821 /** event struct information, for EventMod() only - see Event for documentation */
    822 struct EventInfo {
    823 	int flags;
    824 	long count;
    825 	time_t every_msec;
    826 	char *name;
    827 	vFP event;
    828 	void *data;
    829 };
    830 
    831 
    832 extern MODVAR Hook		*Hooks[MAXHOOKTYPES];
    833 extern MODVAR Hooktype		Hooktypes[MAXCUSTOMHOOKS];
    834 extern MODVAR Callback *Callbacks[MAXCALLBACKS], *RCallbacks[MAXCALLBACKS];
    835 extern MODVAR ClientCapability *clicaps;
    836 
    837 extern Event *EventAdd(Module *module, const char *name, vFP event, void *data, long every_msec, int count);
    838 extern void   EventDel(Event *event);
    839 extern Event *EventMarkDel(Event *event);
    840 extern Event *EventFind(const char *name);
    841 extern int EventMod(Event *event, EventInfo *mods);
    842 extern void DoEvents(void);
    843 extern void EventStatus(Client *client);
    844 extern void SetupEvents(void);
    845 
    846 
    847 extern void Module_Init(void);
    848 extern const char *Module_Create(const char *path);
    849 extern const char *Module_TransformPath(const char *path_);
    850 extern void Init_all_testing_modules(void);
    851 extern void Unload_all_loaded_modules(void);
    852 extern void Unload_all_testing_modules(void);
    853 extern int Module_Unload(const char *name);
    854 extern vFP Module_Sym(const char *name);
    855 extern vFP Module_SymX(const char *name, Module **mptr);
    856 extern int Module_free(Module *mod);
    857 #ifdef __OpenBSD__
    858 extern void *obsd_dlsym(void *handle, const char *symbol);
    859 #endif
    860 #ifdef _WIN32
    861 extern const char *our_dlerror(void);
    862 #endif
    863 
    864 extern Versionflag *VersionflagAdd(Module *module, char flag);
    865 extern void VersionflagDel(Versionflag *vflag, Module *module);
    866 
    867 extern ISupport *ISupportAdd(Module *module, const char *token, const char *value);
    868 extern void ISupportSetValue(ISupport *isupport, const char *value);
    869 extern void ISupportDel(ISupport *isupport);
    870 extern ISupport *ISupportFind(const char *token);
    871 extern void ISupportSet(Module *module, const char *name, const char *value);
    872 extern void ISupportSetFmt(Module *module, const char *name, FORMAT_STRING(const char *pattern), ...) __attribute__((format(printf,3,4)));
    873 extern void ISupportDelByName(const char *name);
    874 
    875 extern ClientCapability *ClientCapabilityFind(const char *token, Client *client);
    876 extern ClientCapability *ClientCapabilityFindReal(const char *token);
    877 extern ClientCapability *ClientCapabilityAdd(Module *module, ClientCapabilityInfo *clicap_request, long *cap);
    878 extern void ClientCapabilityDel(ClientCapability *clicap);
    879 
    880 extern MessageTagHandler *MessageTagHandlerFind(const char *token);
    881 extern MessageTagHandler *MessageTagHandlerAdd(Module *module, MessageTagHandlerInfo *mreq);
    882 extern void MessageTagHandlerDel(MessageTagHandler *m);
    883 
    884 extern HistoryBackend *HistoryBackendFind(const char *name);
    885 extern HistoryBackend *HistoryBackendAdd(Module *module, HistoryBackendInfo *mreq);
    886 extern void HistoryBackendDel(HistoryBackend *m);
    887 
    888 extern RPCHandler *RPCHandlerFind(const char *method);
    889 extern RPCHandler *RPCHandlerAdd(Module *module, RPCHandlerInfo *mreq);
    890 extern void RPCHandlerDel(RPCHandler *m);
    891 
    892 #ifndef GCC_TYPECHECKING
    893 #define HookAdd(module, hooktype, priority, func) HookAddMain(module, hooktype, priority, func, NULL, NULL, NULL)
    894 #define HookAddVoid(module, hooktype, priority, func) HookAddMain(module, hooktype, priority, NULL, func, NULL, NULL)
    895 #define HookAddString(module, hooktype, priority, func) HookAddMain(module, hooktype, priority, NULL, NULL, func, NULL)
    896 #define HookAddConstString(module, hooktype, priority, func) HookAddMain(module, hooktype, priority, NULL, NULL, NULL, func)
    897 #else
    898 #define HookAdd(module, hooktype, priority, func) \
    899 __extension__ ({ \
    900 	ValidateHooks(hooktype, func); \
    901     HookAddMain(module, hooktype, priority, func, NULL, NULL, NULL); \
    902 })
    903 
    904 #define HookAddVoid(module, hooktype, priority, func) \
    905 __extension__ ({ \
    906 	ValidateHooks(hooktype, func); \
    907     HookAddMain(module, hooktype, priority, NULL, func, NULL, NULL); \
    908 })
    909 
    910 #define HookAddString(module, hooktype, priority, func) \
    911 __extension__ ({ \
    912 	ValidateHooks(hooktype, func); \
    913     HookAddMain(module, hooktype, priority, NULL, NULL, func, NULL); \
    914 })
    915 #define HookAddConstString(module, hooktype, priority, func) \
    916 __extension__ ({ \
    917 	ValidateHooks(hooktype, func); \
    918     HookAddMain(module, hooktype, priority, NULL, NULL, NULL, func); \
    919 })
    920 #endif /* GCC_TYPCHECKING */
    921 
    922 extern Hook	*HookAddMain(Module *module, int hooktype, int priority, int (*intfunc)(), void (*voidfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)());
    923 extern Hook	*HookDel(Hook *hook);
    924 
    925 extern Hooktype *HooktypeAdd(Module *module, const char *string, int *type);
    926 extern void HooktypeDel(Hooktype *hooktype, Module *module);
    927 
    928 #define RunHook(hooktype,...) do { Hook *h; for (h = Hooks[hooktype]; h; h = h->next) (*(h->func.intfunc))(__VA_ARGS__); } while(0)
    929 #define RunHookReturn(hooktype,retchk,...) \
    930 { \
    931  int retval; \
    932  Hook *h; \
    933  for (h = Hooks[hooktype]; h; h = h->next) \
    934  { \
    935   retval = (*(h->func.intfunc))(__VA_ARGS__); \
    936   if (retval retchk) return; \
    937  } \
    938 }
    939 #define RunHookReturnInt(hooktype,retchk,...) \
    940 { \
    941  int retval; \
    942  Hook *h; \
    943  for (h = Hooks[hooktype]; h; h = h->next) \
    944  { \
    945   retval = (*(h->func.intfunc))(__VA_ARGS__); \
    946   if (retval retchk) return retval; \
    947  } \
    948 }
    949 
    950 #define CallbackAdd(module, cbtype, func) CallbackAddMain(module, cbtype, func, NULL, NULL, NULL, NULL)
    951 #define CallbackAddVoid(module, cbtype, func) CallbackAddMain(module, cbtype, NULL, func, NULL, NULL, NULL)
    952 #define CallbackAddPVoid(module, cbtype, func) CallbackAddMain(module, cbtype, NULL, NULL, func, NULL, NULL)
    953 #define CallbackAddString(module, cbtype, func) CallbackAddMain(module, cbtype, NULL, NULL, NULL, func, NULL)
    954 #define CallbackAddConstString(module, cbtype, func) CallbackAddMain(module, cbtype, NULL, NULL, NULL, NULL, func)
    955 
    956 extern Callback *CallbackAddMain(Module *module, int cbtype, int (*func)(), void (*vfunc)(), void *(*pvfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)());
    957 extern Callback	*CallbackDel(Callback *cb);
    958 
    959 #define EfunctionAdd(module, cbtype, func) EfunctionAddMain(module, cbtype, func, NULL, NULL, NULL, NULL)
    960 #define EfunctionAddVoid(module, cbtype, func) EfunctionAddMain(module, cbtype, NULL, func, NULL, NULL, NULL)
    961 #define EfunctionAddPVoid(module, cbtype, func) EfunctionAddMain(module, cbtype, NULL, NULL, func, NULL, NULL)
    962 #define EfunctionAddString(module, cbtype, func) EfunctionAddMain(module, cbtype, NULL, NULL, NULL, func, NULL)
    963 #define EfunctionAddConstString(module, cbtype, func) EfunctionAddMain(module, cbtype, NULL, NULL, NULL, NULL, func)
    964 
    965 extern Efunction *EfunctionAddMain(Module *module, EfunctionType eftype, int (*intfunc)(), void (*voidfunc)(), void *(*pvoidfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)());
    966 extern Efunction *EfunctionDel(Efunction *cb);
    967 
    968 extern Command *CommandAdd(Module *module, const char *cmd, CmdFunc func, unsigned char params, int flags);
    969 extern Command *AliasAdd(Module *module, const char *cmd, AliasCmdFunc aliasfunc, unsigned char params, int flags);
    970 extern void CommandDel(Command *command);
    971 extern void CommandDelX(Command *command, RealCommand *cmd);
    972 extern int CommandExists(const char *name);
    973 extern CommandOverride *CommandOverrideAdd(Module *module, const char *name, int priority, OverrideCmdFunc func);
    974 extern void CommandOverrideDel(CommandOverride *ovr);
    975 extern void CallCommandOverride(CommandOverride *ovr, Client *client, MessageTag *mtags, int parc, const char *parv[]);
    976 /** Call next command override function - easy way to do it.
    977  * This way you don't have to call CallCommandOverride() with the right arguments.
    978  * Which is nice because command (override) arguments may change in future UnrealIRCd versions.
    979  */
    980 #define CALL_NEXT_COMMAND_OVERRIDE()	CallCommandOverride(ovr, client, recv_mtags, parc, parv)
    981 
    982 extern void moddata_free_client(Client *acptr);
    983 extern void moddata_free_local_client(Client *acptr);
    984 extern void moddata_free_channel(Channel *channel);
    985 extern void moddata_free_member(Member *m);
    986 extern void moddata_free_membership(Membership *m);
    987 extern ModDataInfo *findmoddata_byname(const char *name, ModDataType type);
    988 extern int moddata_client_set(Client *acptr, const char *varname, const char *value);
    989 extern const char *moddata_client_get(Client *acptr, const char *varname);
    990 extern ModData *moddata_client_get_raw(Client *client, const char *varname);
    991 extern int moddata_local_client_set(Client *acptr, const char *varname, const char *value);
    992 extern const char *moddata_local_client_get(Client *acptr, const char *varname);
    993 
    994 extern int LoadPersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void **var, void (*free_variable)(ModData *m));
    995 #define LoadPersistentPointer(modinfo, var, free_variable) LoadPersistentPointerX(modinfo, #var, (void **)&var, free_variable)
    996 extern void SavePersistentPointerX(ModuleInfo *modinfo, const char *varshortname, void *var);
    997 #define SavePersistentPointer(modinfo, var) SavePersistentPointerX(modinfo, #var, var)
    998 
    999 extern int LoadPersistentIntX(ModuleInfo *modinfo, const char *varshortname, int *var);
   1000 #define LoadPersistentInt(modinfo, var) LoadPersistentIntX(modinfo, #var, &var)
   1001 extern void SavePersistentIntX(ModuleInfo *modinfo, const char *varshortname, int var);
   1002 #define SavePersistentInt(modinfo, var) SavePersistentIntX(modinfo, #var, var)
   1003 
   1004 extern int LoadPersistentLongX(ModuleInfo *modinfo, const char *varshortname, long *var);
   1005 #define LoadPersistentLong(modinfo, var) LoadPersistentLongX(modinfo, #var, &var)
   1006 extern void SavePersistentLongX(ModuleInfo *modinfo, const char *varshortname, long var);
   1007 #define SavePersistentLong(modinfo, var) SavePersistentLongX(modinfo, #var, var)
   1008 
   1009 extern int LoadPersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long *var);
   1010 #define LoadPersistentLongLong(modinfo, var) LoadPersistentLongLongX(modinfo, #var, &var)
   1011 extern void SavePersistentLongLongX(ModuleInfo *modinfo, const char *varshortname, long long var);
   1012 #define SavePersistentLongLong(modinfo, var) SavePersistentLongLongX(modinfo, #var, var)
   1013 
   1014 /** Hooks trigger on "events", such as a new user connecting or joining a channel,
   1015  * see https://www.unrealircd.org/docs/Dev:Hook_API for background info.
   1016  * You are suggested to use CTRL+F on this page to search for any useful hook,
   1017  * see also the example session on how to find and use a hook at
   1018  * https://www.unrealircd.org/docs/Dev:Hook_API#Example_session_finding_and_using_a_hook
   1019  *
   1020  * @defgroup HookAPI Hook API
   1021  * @{
   1022  */
   1023 
   1024 /* Hook types */
   1025 /** See hooktype_pre_local_connect() */
   1026 #define HOOKTYPE_PRE_LOCAL_CONNECT	1
   1027 /** See hooktype_local_connect() */
   1028 #define HOOKTYPE_LOCAL_CONNECT	2
   1029 /** See hooktype_remote_connect() */
   1030 #define HOOKTYPE_REMOTE_CONNECT	3
   1031 /** See hooktype_pre_local_quit() */
   1032 #define HOOKTYPE_PRE_LOCAL_QUIT	4
   1033 /** See hooktype_local_quit() */
   1034 #define HOOKTYPE_LOCAL_QUIT	5
   1035 /** See hooktype_remote_quit() */
   1036 #define HOOKTYPE_REMOTE_QUIT	6
   1037 /** See hooktype_unkuser_quit() */
   1038 #define HOOKTYPE_UNKUSER_QUIT	7
   1039 /** See hooktype_server_connect() */
   1040 #define HOOKTYPE_SERVER_CONNECT	8
   1041 /** See hooktype_server_handshake_out() */
   1042 #define HOOKTYPE_SERVER_HANDSHAKE_OUT	9
   1043 /** See hooktype_server_sync() */
   1044 #define HOOKTYPE_SERVER_SYNC	10
   1045 /** See hooktype_post_server_connect() */
   1046 #define HOOKTYPE_POST_SERVER_CONNECT	11
   1047 /** See hooktype_server_synced() */
   1048 #define HOOKTYPE_SERVER_SYNCED	12
   1049 /** See hooktype_server_quit() */
   1050 #define HOOKTYPE_SERVER_QUIT	13
   1051 /** See hooktype_local_nickchange() */
   1052 #define HOOKTYPE_LOCAL_NICKCHANGE	14
   1053 /** See hooktype_remote_nickchange() */
   1054 #define HOOKTYPE_REMOTE_NICKCHANGE	15
   1055 /** See hooktype_can_join() */
   1056 #define HOOKTYPE_CAN_JOIN	16
   1057 /** See hooktype_pre_local_join() */
   1058 #define HOOKTYPE_PRE_LOCAL_JOIN	17
   1059 /** See hooktype_local_join() */
   1060 #define HOOKTYPE_LOCAL_JOIN	18
   1061 /** See hooktype_remote_join() */
   1062 #define HOOKTYPE_REMOTE_JOIN	19
   1063 /** See hooktype_pre_local_part() */
   1064 #define HOOKTYPE_PRE_LOCAL_PART	20
   1065 /** See hooktype_local_part() */
   1066 #define HOOKTYPE_LOCAL_PART	21
   1067 /** See hooktype_remote_part() */
   1068 #define HOOKTYPE_REMOTE_PART	22
   1069 /** See hooktype_pre_local_kick() */
   1070 #define HOOKTYPE_PRE_LOCAL_KICK	23
   1071 /** See hooktype_can_kick() */
   1072 #define HOOKTYPE_CAN_KICK	24
   1073 /** See hooktype_local_kick() */
   1074 #define HOOKTYPE_LOCAL_KICK	25
   1075 /** See hooktype_remote_kick() */
   1076 #define HOOKTYPE_REMOTE_KICK	26
   1077 /** See hooktype_pre_chanmsg() */
   1078 #define HOOKTYPE_PRE_CHANMSG	28
   1079 /** See hooktype_can_send_to_user() */
   1080 #define HOOKTYPE_CAN_SEND_TO_USER	29
   1081 /** See hooktype_can_send_to_channel() */
   1082 #define HOOKTYPE_CAN_SEND_TO_CHANNEL	30
   1083 /** See hooktype_usermsg() */
   1084 #define HOOKTYPE_USERMSG	31
   1085 /** See hooktype_chanmsg() */
   1086 #define HOOKTYPE_CHANMSG	32
   1087 /** See hooktype_pre_local_topic() */
   1088 #define HOOKTYPE_PRE_LOCAL_TOPIC	33
   1089 /** See hooktype_topic() */
   1090 #define HOOKTYPE_TOPIC	35
   1091 /** See hooktype_pre_local_chanmode() */
   1092 #define HOOKTYPE_PRE_LOCAL_CHANMODE	36
   1093 /** See hooktype_pre_remote_chanmode() */
   1094 #define HOOKTYPE_PRE_REMOTE_CHANMODE	37
   1095 /** See hooktype_local_chanmode() */
   1096 #define HOOKTYPE_LOCAL_CHANMODE	38
   1097 /** See hooktype_remote_chanmode() */
   1098 #define HOOKTYPE_REMOTE_CHANMODE	39
   1099 /** See hooktype_modechar_del() */
   1100 #define HOOKTYPE_MODECHAR_DEL	40
   1101 /** See hooktype_modechar_add() */
   1102 #define HOOKTYPE_MODECHAR_ADD	41
   1103 /** See hooktype_away() */
   1104 #define HOOKTYPE_AWAY	42
   1105 /** See hooktype_pre_invite() */
   1106 #define HOOKTYPE_PRE_INVITE	43
   1107 /** See hooktype_invite() */
   1108 #define HOOKTYPE_INVITE	44
   1109 /** See hooktype_pre_knock() */
   1110 #define HOOKTYPE_PRE_KNOCK	45
   1111 /** See hooktype_knock() */
   1112 #define HOOKTYPE_KNOCK	46
   1113 /** See hooktype_whois() */
   1114 #define HOOKTYPE_WHOIS	47
   1115 /** See hooktype_who_status() */
   1116 #define HOOKTYPE_WHO_STATUS	48
   1117 /** See hooktype_pre_kill() */
   1118 #define HOOKTYPE_PRE_KILL	49
   1119 /** See hooktype_local_kill() */
   1120 #define HOOKTYPE_LOCAL_KILL	50
   1121 /** See hooktype_rehashflag() */
   1122 #define HOOKTYPE_REHASHFLAG	51
   1123 /** See hooktype_configposttest() */
   1124 #define HOOKTYPE_CONFIGPOSTTEST	52
   1125 /** See hooktype_rehash() */
   1126 #define HOOKTYPE_REHASH	53
   1127 /** See hooktype_rehash_complete() */
   1128 #define HOOKTYPE_REHASH_COMPLETE	54
   1129 /** See hooktype_configtest() */
   1130 #define HOOKTYPE_CONFIGTEST	55
   1131 /** See hooktype_configrun() */
   1132 #define HOOKTYPE_CONFIGRUN	56
   1133 /** See hooktype_configrun_ex() */
   1134 #define HOOKTYPE_CONFIGRUN_EX	57
   1135 /** See hooktype_stats() */
   1136 #define HOOKTYPE_STATS	58
   1137 /** See hooktype_local_oper() */
   1138 #define HOOKTYPE_LOCAL_OPER	59
   1139 /** See hooktype_local_pass() */
   1140 #define HOOKTYPE_LOCAL_PASS	60
   1141 /** See hooktype_channel_create() */
   1142 #define HOOKTYPE_CHANNEL_CREATE	61
   1143 /** See hooktype_channel_destroy() */
   1144 #define HOOKTYPE_CHANNEL_DESTROY	62
   1145 /** See hooktype_tkl_except() */
   1146 #define HOOKTYPE_TKL_EXCEPT	63
   1147 /** See hooktype_umode_change() */
   1148 #define HOOKTYPE_UMODE_CHANGE	64
   1149 /** See hooktype_tkl_add() */
   1150 #define HOOKTYPE_TKL_ADD	65
   1151 /** See hooktype_tkl_del() */
   1152 #define HOOKTYPE_TKL_DEL	66
   1153 /** See hooktype_log() */
   1154 #define HOOKTYPE_LOG	67
   1155 /** See hooktype_local_spamfilter() */
   1156 #define HOOKTYPE_LOCAL_SPAMFILTER	68
   1157 /** See hooktype_silenced() */
   1158 #define HOOKTYPE_SILENCED	69
   1159 /** See hooktype_rawpacket_in() */
   1160 #define HOOKTYPE_RAWPACKET_IN	70
   1161 /** See hooktype_packet() */
   1162 #define HOOKTYPE_PACKET	71
   1163 /** See hooktype_handshake() */
   1164 #define HOOKTYPE_HANDSHAKE	72
   1165 /** See hooktype_free_client() */
   1166 #define HOOKTYPE_FREE_CLIENT	73
   1167 /** See hooktype_free_user() */
   1168 #define HOOKTYPE_FREE_USER	74
   1169 /** See hooktype_can_join_limitexceeded() */
   1170 #define HOOKTYPE_CAN_JOIN_LIMITEXCEEDED	75
   1171 /** See hooktype_visible_in_channel() */
   1172 #define HOOKTYPE_VISIBLE_IN_CHANNEL	76
   1173 /** See hooktype_see_channel_in_whois() */
   1174 #define HOOKTYPE_SEE_CHANNEL_IN_WHOIS	77
   1175 /** See hooktype_join_data() */
   1176 #define HOOKTYPE_JOIN_DATA	78
   1177 /** See hooktype_invite_bypass() */
   1178 #define HOOKTYPE_INVITE_BYPASS	79
   1179 /** See hooktype_view_topic_outside_channel() */
   1180 #define HOOKTYPE_VIEW_TOPIC_OUTSIDE_CHANNEL	80
   1181 /** See hooktype_chan_permit_nick_change() */
   1182 #define HOOKTYPE_CHAN_PERMIT_NICK_CHANGE	81
   1183 /** See hooktype_is_channel_secure() */
   1184 #define HOOKTYPE_IS_CHANNEL_SECURE	82
   1185 /** See hooktype_channel_synced() */
   1186 #define HOOKTYPE_CHANNEL_SYNCED	83
   1187 /** See hooktype_can_sajoin() */
   1188 #define HOOKTYPE_CAN_SAJOIN	84
   1189 /** See hooktype_mode_deop() */
   1190 #define HOOKTYPE_MODE_DEOP	86
   1191 /** See hooktype_dcc_denied() */
   1192 #define HOOKTYPE_DCC_DENIED	87
   1193 /** See hooktype_secure_connect() */
   1194 #define HOOKTYPE_SECURE_CONNECT	88
   1195 /** See hooktype_can_bypass_channel_message_restriction() */
   1196 #define HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION	89
   1197 /** See hooktype_sasl_continuation() */
   1198 #define HOOKTYPE_SASL_CONTINUATION	91
   1199 /** See hooktype_sasl_result() */
   1200 #define HOOKTYPE_SASL_RESULT	92
   1201 /** See hooktype_place_host_ban() */
   1202 #define HOOKTYPE_PLACE_HOST_BAN	93
   1203 /** See hooktype_find_tkline_match() */
   1204 #define HOOKTYPE_FIND_TKLINE_MATCH	94
   1205 /** See hooktype_welcome() */
   1206 #define HOOKTYPE_WELCOME	95
   1207 /** See hooktype_pre_command() */
   1208 #define HOOKTYPE_PRE_COMMAND	96
   1209 /** See hooktype_post_command() */
   1210 #define HOOKTYPE_POST_COMMAND	97
   1211 /** See hooktype_new_message() */
   1212 #define HOOKTYPE_NEW_MESSAGE	98
   1213 /** See hooktype_is_handshake_finished() */
   1214 #define HOOKTYPE_IS_HANDSHAKE_FINISHED	99
   1215 /** See hooktype_pre_local_quit_chan() */
   1216 #define HOOKTYPE_PRE_LOCAL_QUIT_CHAN	100
   1217 /** See hooktype_ident_lookup() */
   1218 #define HOOKTYPE_IDENT_LOOKUP	101
   1219 /** See hooktype_account_login() */
   1220 #define HOOKTYPE_ACCOUNT_LOGIN	102
   1221 /** See hooktype_close_connection() */
   1222 #define HOOKTYPE_CLOSE_CONNECTION	103
   1223 /** See hooktype_connect_extinfo() */
   1224 #define HOOKTYPE_CONNECT_EXTINFO	104
   1225 /** See hooktype_is_invited() */
   1226 #define HOOKTYPE_IS_INVITED	105
   1227 /** See hooktype_post_local_nickchange() */
   1228 #define HOOKTYPE_POST_LOCAL_NICKCHANGE	106
   1229 /** See hooktype_post_remote_nickchange() */
   1230 #define HOOKTYPE_POST_REMOTE_NICKCHANGE	107
   1231 /** See hooktype_userhost_change() */
   1232 #define HOOKTYPE_USERHOST_CHANGE 108
   1233 /** See hooktype_realname_change() */
   1234 #define HOOKTYPE_REALNAME_CHANGE 109
   1235 /** See hooktype_can_set_topic() */
   1236 #define HOOKTYPE_CAN_SET_TOPIC	110
   1237 /** See hooktype_ip_change() */
   1238 #define HOOKTYPE_IP_CHANGE	111
   1239 /** See hooktype_json_expand_client() */
   1240 #define HOOKTYPE_JSON_EXPAND_CLIENT	112
   1241 /** See hooktype_json_expand_client() */
   1242 #define HOOKTYPE_JSON_EXPAND_CLIENT_USER	113
   1243 /** See hooktype_json_expand_client() */
   1244 #define HOOKTYPE_JSON_EXPAND_CLIENT_SERVER	114
   1245 /** See hooktype_json_expand_channel() */
   1246 #define HOOKTYPE_JSON_EXPAND_CHANNEL	115
   1247 /** See hooktype_accept() */
   1248 #define HOOKTYPE_ACCEPT		116
   1249 /** See hooktype_pre_local_handshake_timeout */
   1250 #define HOOKTYPE_PRE_LOCAL_HANDSHAKE_TIMEOUT	117
   1251 /** See hooktype_rehash_log */
   1252 #define HOOKTYPE_REHASH_LOG	118
   1253 
   1254 /* Adding a new hook here?
   1255  * 1) Add the #define HOOKTYPE_.... with a new number
   1256  * 2) Add a hook prototype (see below)
   1257  * 3) Add type checking (even more below)
   1258  */
   1259 
   1260 /* Hook prototypes */
   1261 /** Called when a local user connects, allows pausing or rejecting the user (function prototype for HOOKTYPE_PRE_LOCAL_CONNECT).
   1262  * @param client		The client
   1263  * @retval HOOK_DENY		Stop the connection (hold/pause it).
   1264  * @retval HOOK_ALLOW		Allow the connection (stop processing other modules)
   1265  * @retval HOOK_CONTINUE	Allow the connection, unless another module blocks it.
   1266  */
   1267 int hooktype_pre_local_connect(Client *client);
   1268 
   1269 /** Called when a local user connects (function prototype for HOOKTYPE_LOCAL_CONNECT).
   1270  * @param client		The client
   1271  * @return The return value is ignored (use return 0)
   1272  */
   1273 int hooktype_local_connect(Client *client);
   1274 
   1275 /** Called when a remote user connects (function prototype for HOOKTYPE_REMOTE_CONNECT).
   1276  * @param client		The client
   1277  * @return The return value is ignored (use return 0)
   1278  */
   1279 int hooktype_remote_connect(Client *client);
   1280 
   1281 /** Called when a local user disconnects, allows changing the quit/disconnect reason (function prototype for HOOKTYPE_PRE_LOCAL_QUIT).
   1282  * @param client		The client
   1283  * @param client		The quit/disconnect reason
   1284  * @return The quit reason (you may also return 'comment' if it should be unchanged) or NULL for an empty reason.
   1285  */
   1286 const char *hooktype_pre_local_quit(Client *client, const char *comment);
   1287 
   1288 /** Called when a local user quits or otherwise disconnects (function prototype for HOOKTYPE_PRE_LOCAL_QUIT).
   1289  * @param client		The client
   1290  * @param mtags         	Message tags associated with the quit
   1291  * @param comment       	The quit/exit reason
   1292  * @return The return value is ignored (use return 0)
   1293  */
   1294 int hooktype_local_quit(Client *client, MessageTag *mtags, const char *comment);
   1295 
   1296 /** Called when a remote user qutis or otherwise disconnects (function prototype for HOOKTYPE_REMOTE_QUIT).
   1297  * @param client		The client
   1298  * @param mtags         	Message tags associated with the quit
   1299  * @param comment       	The quit/exit reason
   1300  * @return The return value is ignored (use return 0)
   1301  */
   1302 int hooktype_remote_quit(Client *client, MessageTag *mtags, const char *comment);
   1303 
   1304 /** Called when an unregistered user disconnects, so before the user was fully online (function prototype for HOOKTYPE_UNKUSER_QUIT).
   1305  * @param client		The client
   1306  * @param mtags         	Message tags associated with the quit
   1307  * @param comment       	The quit/exit reason
   1308  * @return The return value is ignored (use return 0)
   1309  */
   1310 int hooktype_unkuser_quit(Client *client, MessageTag *mtags, const char *comment);
   1311 
   1312 /** Called when a local or remote server connects / links in (function prototype for HOOKTYPE_SERVER_CONNECT).
   1313  * @param client		The client
   1314  * @return The return value is ignored (use return 0)
   1315  */
   1316 int hooktype_server_connect(Client *client);
   1317 
   1318 /** Called very early when doing an outgoing server connect (function prototype for HOOKTYPE_SERVER_HANDSHAKE_OUT).
   1319  * @param client		The client
   1320  * @return The return value is ignored (use return 0)
   1321  */
   1322 int hooktype_server_handshake_out(Client *client);
   1323 
   1324 /** Called on new locally connected server, in or out, after all users/channels/TKLs/etc have been synced, but before EOS (function prototype for HOOKTYPE_SERVER_SYNC).
   1325  * @param client		The client
   1326  * @return The return value is ignored (use return 0)
   1327  */
   1328 int hooktype_server_sync(Client *client);
   1329 
   1330 /** Called when a local or remote server connects / links in, but only after EOS (End Of Sync) has been received or sent (function prototype for HOOKTYPE_POST_SERVER_CONNECT).
   1331  * @param client		The client
   1332  * @return The return value is ignored (use return 0)
   1333  */
   1334 int hooktype_post_server_connect(Client *client);
   1335 
   1336 /** Called when a local or remote server is linked in and fully synced, after EOS / End Of Sync (function prototype for HOOKTYPE_SERVER_SYNCED).
   1337  * @param client		The client
   1338  * @return The return value is ignored (use return 0)
   1339  */
   1340 int hooktype_server_synced(Client *client);
   1341 
   1342 /** Called when a local or remote server disconnects (function prototype for HOOKTYPE_SERVER_QUIT).
   1343  * @param client		The client
   1344  * @param mtags         	Message tags associated with the disconnect
   1345  * @return The return value is ignored (use return 0)
   1346  */
   1347 int hooktype_server_quit(Client *client, MessageTag *mtags);
   1348 
   1349 /** Called when a local user changes the nick name (function prototype for HOOKTYPE_LOCAL_NICKCHANGE).
   1350  * @param client		The client
   1351  * @param mtags         	Message tags associated with the event
   1352  * @param newnick		The new nick name
   1353  * @return The return value is ignored (use return 0)
   1354  */
   1355 int hooktype_local_nickchange(Client *client, MessageTag *mtags, const char *newnick);
   1356 
   1357 /** Called when a remote user changes the nick name (function prototype for HOOKTYPE_REMOTE_NICKCHANGE).
   1358  * @param client		The client
   1359  * @param mtags         	Message tags associated with the event
   1360  * @param newnick		The new nick name
   1361  * @return The return value is ignored (use return 0)
   1362  */
   1363 int hooktype_remote_nickchange(Client *client, MessageTag *mtags, const char *newnick);
   1364 
   1365 /** Called when a user wants to join a channel, may the user join? (function prototype for HOOKTYPE_CAN_JOIN).
   1366  * @param client		The client
   1367  * @param channel		The channel the user wants to join
   1368  * @param key			The key supplied by the client
   1369  * @return Return 0 to allow the user, any other value should be an IRC numeric (eg: ERR_BANNEDFROMCHAN).
   1370  */
   1371 int hooktype_can_join(Client *client, Channel *channel, const char *key, char **errmsg);
   1372 
   1373 /** Called when a user wants to join a channel (function prototype for HOOKTYPE_PRE_LOCAL_JOIN).
   1374  * IMPORTANT: Generally you want to use HOOKTYPE_CAN_JOIN / hooktype_can_join() instead!!
   1375  * @param client		The client
   1376  * @param channel		The channel the user wants to join
   1377  * @param key			Channel key (can be NULL)
   1378  * @retval HOOK_DENY		Deny the join.
   1379  * @retval HOOK_ALLOW		Allow the join (stop processing other modules)
   1380  * @retval HOOK_CONTINUE	Allow the join, unless another module blocks it.
   1381  */
   1382 int hooktype_pre_local_join(Client *client, Channel *channel, const char *key);
   1383 
   1384 /** Called when a local user joins a channel (function prototype for HOOKTYPE_LOCAL_JOIN).
   1385  * @param client		The client
   1386  * @param channel		The channel the user wants to join
   1387  * @param mtags         	Message tags associated with the event
   1388  * @return The return value is ignored (use return 0)
   1389  */
   1390 int hooktype_local_join(Client *client, Channel *channel, MessageTag *mtags);
   1391 
   1392 /** Called when a remote user joins a channel (function prototype for HOOKTYPE_REMOTE_JOIN).
   1393  * @param client		The client
   1394  * @param channel		The channel the user wants to join
   1395  * @param mtags         	Message tags associated with the event
   1396  * @return The return value is ignored (use return 0)
   1397  */
   1398 int hooktype_remote_join(Client *client, Channel *channel, MessageTag *mtags);
   1399 
   1400 /** Called when a local user wants to part a channel (function prototype for HOOKTYPE_PRE_LOCAL_PART).
   1401  * @param client		The client
   1402  * @param channel		The channel the user wants to part
   1403  * @param comment		The PART reason, this may be NULL.
   1404  * @return The part reason (you may also return 'comment' if it should be unchanged) or NULL for an empty reason.
   1405  */
   1406 const char *hooktype_pre_local_part(Client *client, Channel *channel, const char *comment);
   1407 
   1408 /** Called when a local user parts a channel (function prototype for HOOKTYPE_LOCAL_PART).
   1409  * @param client		The client
   1410  * @param channel		The channel the user is leaving
   1411  * @param mtags         	Message tags associated with the event
   1412  * @param comment		The PART reason, this may be NULL.
   1413  * @return The return value is ignored (use return 0)
   1414  */
   1415 int hooktype_local_part(Client *client, Channel *channel, MessageTag *mtags, const char *comment);
   1416 
   1417 /** Called when a remote user parts a channel (function prototype for HOOKTYPE_REMOTE_PART).
   1418  * @param client		The client
   1419  * @param channel		The channel the user is leaving
   1420  * @param mtags         	Message tags associated with the event
   1421  * @param comment		The PART reason, this may be NULL.
   1422  * @return The return value is ignored (use return 0)
   1423  */
   1424 int hooktype_remote_part(Client *client, Channel *channel, MessageTag *mtags, const char *comment);
   1425 
   1426 /** Do not use this function, use hooktype_can_kick() instead!
   1427  */
   1428 const char *hooktype_pre_local_kick(Client *client, Client *victim, Channel *channel, const char *comment);
   1429 
   1430 /** Called when a local user wants to kick another user from a channel (function prototype for HOOKTYPE_CAN_KICK).
   1431  * @param client		The client issuing the command
   1432  * @param victim		The victim that should be kicked
   1433  * @param channel		The channel the user should be kicked from
   1434  * @param comment		The KICK reason, this may be NULL.
   1435  * @param client_member_modes	The member modes of 'client' (eg "o"), never NULL but can be empty.
   1436  * @param victim_member_modes	The member modes of 'victim' (eg "v"), never NULL but can be empty.
   1437  * @param errmsg		The error message that should be shown to the user (full IRC protocol line).
   1438  * @retval EX_DENY		Deny the KICK (unless IRCOp with sufficient override rights).
   1439  * @retval EX_ALWAYS_DENY	Deny the KICK always (even if IRCOp).
   1440  * @retval EX_ALLOW		Allow the kick, unless another module blocks it.
   1441  */
   1442 int hooktype_can_kick(Client *client, Client *victim, Channel *channel, const char *comment, const char *client_member_modes, const char *victim_member_modes, const char **errmsg);
   1443 
   1444 /** Called when a local user is kicked (function prototype for HOOKTYPE_LOCAL_KICK).
   1445  * @param client		The client issuing the command
   1446  * @param victim		The victim that should be kicked
   1447  * @param channel		The channel the user should be kicked from
   1448  * @param mtags         	Message tags associated with the event
   1449  * @param comment		The KICK reason, this may be NULL.
   1450  * @return The return value is ignored (use return 0)
   1451  */
   1452 int hooktype_local_kick(Client *client, Client *victim, Channel *channel, MessageTag *mtags, const char *comment);
   1453 
   1454 /** Called when a remote user is kicked (function prototype for HOOKTYPE_REMOTE_KICK).
   1455  * @param client		The client issuing the command
   1456  * @param victim		The victim that should be kicked
   1457  * @param channel		The channel the user should be kicked from
   1458  * @param mtags         	Message tags associated with the event
   1459  * @param comment		The KICK reason, this may be NULL.
   1460  * @return The return value is ignored (use return 0)
   1461  */
   1462 int hooktype_remote_kick(Client *client, Client *victim, Channel *channel, MessageTag *mtags, const char *comment);
   1463 
   1464 /** Called right before a message is sent to the channel (function prototype for HOOKTYPE_PRE_CHANMSG).
   1465  * This function is only used by delayjoin. It cannot block a message. See hooktype_can_send_to_user() instead!
   1466  * @param client		The client
   1467  * @param channel		The channel
   1468  * @param mtags         	Message tags associated with the event
   1469  * @param text			The text that will be sent
   1470  * @return The return value is ignored (use return 0)
   1471  */
   1472 int hooktype_pre_chanmsg(Client *client, Channel *channel, MessageTag *mtags, const char *text, SendType sendtype);
   1473 
   1474 /** Called when a user wants to send a message to another user (function prototype for HOOKTYPE_CAN_SEND_TO_USER).
   1475  * @param client		The sender
   1476  * @param target		The recipient
   1477  * @param text			The text to be sent (double pointer!)
   1478  * @param errmsg		The error message. If you block the message (HOOK_DENY) then you MUST set this!
   1479  * @param sendtype		The message type, for example SEND_TYPE_PRIVMSG.
   1480  * @retval HOOK_DENY		Deny the message. The 'errmsg' will be sent to the user.
   1481  * @retval HOOK_CONTINUE	Allow the message, unless other modules block it.
   1482  */
   1483 int hooktype_can_send_to_user(Client *client, Client *target, const char **text, const char **errmsg, SendType sendtype);
   1484 
   1485 /** Called when a user wants to send a message to a channel (function prototype for HOOKTYPE_CAN_SEND_TO_CHANNEL).
   1486  * @param client		The sender
   1487  * @param channel		The channel to send to
   1488  * @param member		The membership struct, so you can see for example op status.
   1489  * @param text			The text to be sent (double pointer!)
   1490  * @param errmsg		The error message. If you block the message (HOOK_DENY) then you MUST set this!
   1491  * @param sendtype		The message type, for example SEND_TYPE_PRIVMSG.
   1492  * @retval HOOK_DENY		Deny the message. The 'errmsg' will be sent to the user.
   1493  * @retval HOOK_CONTINUE	Allow the message, unless other modules block it.
   1494  */
   1495 int hooktype_can_send_to_channel(Client *client, Channel *channel, Membership *member, const char **text, const char **errmsg, SendType sendtype);
   1496 
   1497 /** Called when a message is sent from one user to another user (function prototype for HOOKTYPE_USERMSG).
   1498  * @param client		The sender
   1499  * @param to			The recipient
   1500  * @param mtags         	Message tags associated with the event
   1501  * @param text			The text
   1502  * @param sendtype		The message type, for example SEND_TYPE_PRIVMSG.
   1503  * @return The return value is ignored (use return 0)
   1504  */
   1505 int hooktype_usermsg(Client *client, Client *to, MessageTag *mtags, const char *text, SendType sendtype);
   1506 
   1507 /** Called when a message is sent to a channel (function prototype for HOOKTYPE_CHANMSG).
   1508  * @param client		The sender
   1509  * @param channel		The channel
   1510  * @param sendflags		One of SEND_* (eg SEND_ALL, SKIP_DEAF).
   1511  * @param member_modes		Either NULL, or a member mode like "h", "o", etc.
   1512  * @param target		Target string, usually this is "#channel", but it can also contain prefixes like "@#channel"
   1513  * @param mtags         	Message tags associated with the event
   1514  * @param text			The text
   1515  * @param sendtype		The message type, for example SEND_TYPE_PRIVMSG.
   1516  * @return The return value is ignored (use return 0)
   1517  */
   1518 int hooktype_chanmsg(Client *client, Channel *channel, int sendflags, const char *member_modes, const char *target, MessageTag *mtags, const char *text, SendType sendtype);
   1519 
   1520 /** Called when a user wants to set the topic (function prototype for HOOKTYPE_CAN_SET_TOPIC).
   1521  * @param client		The client issuing the command
   1522  * @param channel		The channel the topic should be set for
   1523  * @param topic			The topic that should be set, this may be NULL for unset.
   1524  * @param errmsg		The error message that should be shown to the user (full IRC protocol line).
   1525  * @retval EX_DENY		Deny the TOPIC (unless IRCOp with sufficient override rights).
   1526  * @retval EX_ALWAYS_DENY	Deny the TOPIC always (even if IRCOp).
   1527  * @retval EX_ALLOW		Allow the TOPIC, unless another module blocks it.
   1528  */
   1529 int hooktype_can_set_topic(Client *client, Channel *channel, const char *topic, const char **errmsg);
   1530 
   1531 /** Called when a local user wants to change the channel topic (function prototype for HOOKTYPE_PRE_LOCAL_TOPIC).
   1532  * @param client		The client
   1533  * @param channel		The channel
   1534  * @param topic			The new requested topic
   1535  * @return The new topic (you may also return 'topic'), or NULL if the topic change request should be rejected.
   1536  */
   1537 const char *hooktype_pre_local_topic(Client *client, Channel *channel, const char *topic);
   1538 
   1539 /** Called when the channel topic is changed (function prototype for HOOKTYPE_TOPIC).
   1540  * @param client		The client
   1541  * @param channel		The channel
   1542  * @param mtags         	Message tags associated with the event
   1543  * @param topic			The new topic
   1544  * @return The return value is ignored (use return 0)
   1545  */
   1546 int hooktype_topic(Client *client, Channel *channel, MessageTag *mtags, const char *topic);
   1547 
   1548 /** Called when a local user changes channel modes, called early (function prototype for HOOKTYPE_PRE_LOCAL_CHANMODE).
   1549  * WARNING: This does not allow you to stop or reject the channel modes. It only allows you to do stuff -before- the
   1550  * mode is changed. It is currently only used by the delayjoin module.
   1551  * @param client		The client
   1552  * @param channel		The channel
   1553  * @param mtags         	Message tags associated with the event
   1554  * @param modebuf		The mode buffer, for example "+o"
   1555  * @param parabuf		The parameter buffer, for example "NiceOp"
   1556  * @param sendts		Send timestamp
   1557  * @param samode		Is this an SAMODE?
   1558  * @return The return value is ignored (use return 0)
   1559  */
   1560 int hooktype_pre_local_chanmode(Client *client, Channel *channel, MessageTag *mtags, const char *modebuf, const char *parabuf, time_t sendts, int samode);
   1561 
   1562 /** Called when a remote user changes channel modes, called early (function prototype for HOOKTYPE_PRE_REMOTE_CHANMODE).
   1563  * WARNING: This does not allow you to stop or reject the channel modes. It only allows you to do stuff -before- the
   1564  * mode is changed. It is currently only used by the delayjoin module.
   1565  * @param client		The client
   1566  * @param channel		The channel
   1567  * @param mtags         	Message tags associated with the event
   1568  * @param modebuf		The mode buffer, for example "+o"
   1569  * @param parabuf		The parameter buffer, for example "NiceOp"
   1570  * @param sendts		Send timestamp
   1571  * @param samode		Is this an SAMODE?
   1572  * @return The return value is ignored (use return 0)
   1573  */
   1574 int hooktype_pre_remote_chanmode(Client *client, Channel *channel, MessageTag *mtags, const char *modebuf, const char *parabuf, time_t sendts, int samode);
   1575 
   1576 /** Called when a local user changes channel modes (function prototype for HOOKTYPE_LOCAL_CHANMODE).
   1577  * @param client		The client
   1578  * @param channel		The channel
   1579  * @param mtags         	Message tags associated with the event
   1580  * @param modebuf		The mode buffer, for example "+o"
   1581  * @param parabuf		The parameter buffer, for example "NiceOp"
   1582  * @param sendts		Send timestamp
   1583  * @param samode		Is this an SAMODE?
   1584  * @param destroy_channel	Module can set this to 1 to indicate 'channel' was destroyed
   1585  * @return The return value is ignored (use return 0)
   1586  */
   1587 int hooktype_local_chanmode(Client *client, Channel *channel, MessageTag *mtags, const char *modebuf, const char *parabuf, time_t sendts, int samode, int *destroy_channel);
   1588 
   1589 /** Called when a remote user changes channel modes (function prototype for HOOKTYPE_REMOTE_CHANMODE).
   1590  * @param client		The client
   1591  * @param channel		The channel
   1592  * @param mtags         	Message tags associated with the event
   1593  * @param modebuf		The mode buffer, for example "+o"
   1594  * @param parabuf		The parameter buffer, for example "NiceOp"
   1595  * @param sendts		Send timestamp
   1596  * @param samode		Is this an SAMODE?
   1597  * @param destroy_channel	Module can set this to 1 to indicate 'channel' was destroyed
   1598  * @return The return value is ignored (use return 0)
   1599  */
   1600 int hooktype_remote_chanmode(Client *client, Channel *channel, MessageTag *mtags, const char *modebuf, const char *parabuf, time_t sendts, int samode, int *destroy_channel);
   1601 
   1602 /** Called when a channel mode is removed by a local or remote user (function prototype for HOOKTYPE_MODECHAR_DEL).
   1603  * NOTE: This is currently not terribly useful for most modules. It is used by by the floodprot and noknock modules.
   1604  * @param channel		The channel
   1605  * @param modechar		The mode character, eg 'k'
   1606  * @return The return value is ignored (use return 0)
   1607  */
   1608 int hooktype_modechar_del(Channel *channel, int modechar);
   1609 
   1610 /** Called when a channel mode is set by a local or remote user (function prototype for HOOKTYPE_MODECHAR_ADD).
   1611  * NOTE: This is currently not terribly useful for most modules. It is used by by the floodprot and noknock modules.
   1612  * @param channel		The channel
   1613  * @param modechar		The mode character, eg 'k'
   1614  * @return The return value is ignored (use return 0)
   1615  */
   1616 int hooktype_modechar_add(Channel *channel, int modechar);
   1617 
   1618 /** Called when a user sets away status or unsets away status (function prototype for HOOKTYPE_AWAY).
   1619  * @param client		The client
   1620  * @param mtags         	Message tags associated with the event
   1621  * @param reason		The away reason, or NULL if away is unset.
   1622  * @param already_as_away	Set to 1 if the user only changed their away reason.
   1623  * @return The return value is ignored (use return 0)
   1624  */
   1625 int hooktype_away(Client *client, MessageTag *mtags, const char *reason, int already_as_away);
   1626 
   1627 /** Called when a user wants to invite another user to a channel (function prototype for HOOKTYPE_PRE_INVITE).
   1628  * @param client		The client
   1629  * @param acptr			The user who is invited (victim)
   1630  * @param channel		The channel the user is invited to
   1631  * @param override		If this was an override (1) or not. Note: pointer to an int!
   1632  * @retval HOOK_DENY		Deny the invite.
   1633  * @retval HOOK_ALLOW		Allow the invite (stop processing other modules)
   1634  * @retval HOOK_CONTINUE	Allow the invite, unless another module blocks it.
   1635  */
   1636 int hooktype_pre_invite(Client *client, Client *acptr, Channel *channel, int *override);
   1637 
   1638 /** Called when a user invites another user to a channel (function prototype for HOOKTYPE_INVITE).
   1639  * @param client		The client
   1640  * @param acptr			The user who is invited (victim)
   1641  * @param channel		The channel the user is invited to
   1642  * @param mtags			Message tags associated with the event
   1643  * @return The return value is ignored (use return 0)
   1644  */
   1645 int hooktype_invite(Client *client, Client *acptr, Channel *channel, MessageTag *mtags);
   1646 
   1647 /** Called when a user wants to knock on a channel (function prototype for HOOKTYPE_PRE_KNOCK).
   1648  * @param client		The client
   1649  * @param channel		The channel to knock on
   1650  * @param reason		Knock reason (can be replaced if needed)
   1651  * @retval HOOK_DENY		Deny the knock.
   1652  * @retval HOOK_ALLOW		Allow the knock (stop processing other modules)
   1653  * @retval HOOK_CONTINUE	Allow the knock, unless another module blocks it.
   1654  */
   1655 int hooktype_pre_knock(Client *client, Channel *channel, const char **reason);
   1656 
   1657 /** Called when a user knocks on a channel (function prototype for HOOKTYPE_KNOCK).
   1658  * @param client		The client
   1659  * @param channel		The channel to knock on
   1660  * @param mtags			Message tags associated with the event
   1661  * @param comment		The knock reason
   1662  * @return The return value is ignored (use return 0)
   1663  */
   1664 int hooktype_knock(Client *client, Channel *channel, MessageTag *mtags, const char *comment);
   1665 
   1666 /** Called when a user whoises someone (function prototype for HOOKTYPE_WHOIS).
   1667  * @param client		The client issuing the command
   1668  * @param target		The user who is the target of the /WHOIS.
   1669  * @param list			The name/value/prio list that you can add information to
   1670  *				that will be sent to the user as the WHOIS response.
   1671  * @return The return value is ignored (use return 0)
   1672  */
   1673 int hooktype_whois(Client *client, Client *target, NameValuePrioList **list);
   1674 
   1675 /** Called to add letters to the WHO status column (function prototype for HOOKTYPE_WHO_STATUS).
   1676  * If a user does a /WHO request, then WHO will show a number of status flags
   1677  * such as B to show the user is a bot (see "HELPOP WHO" for the full list).
   1678  * @param client		The client
   1679  * @param target		The target, the user for which we should display WHO status flags
   1680  * @param channel		The channel if a channel WHO, or NULL
   1681  * @param member		The membership information, or NULL
   1682  * @param status		The current status flags, so far
   1683  * @param cansee		If 'client' can see 'target' (eg: in same channel or -i)
   1684  * @return Return 0 if no WHO status flags need to be added, otherwise return the ascii character (eg: return 'B').
   1685  */
   1686 int hooktype_who_status(Client *client, Client *target, Channel *channel, Member *member, const char *status, int cansee);
   1687 
   1688 /** Called when an IRCOp wants to kill another user (function prototype for HOOKTYPE_PRE_KILL).
   1689  * @param client		The client
   1690  * @param victim		The user who should be killed
   1691  * @param reason		The kill reason
   1692  * @retval EX_DENY		Deny the KICK (unless IRCOp with sufficient override rights).
   1693  * @retval EX_ALWAYS_DENY	Deny the KICK always (even if IRCOp).
   1694  * @retval EX_ALLOW		Allow the kick, unless another module blocks it.
   1695  */
   1696 int hooktype_pre_kill(Client *client, Client *victim, const char *reason);
   1697 
   1698 /** Called when a local user kills another user (function prototype for HOOKTYPE_LOCAL_KILL).
   1699  * Note that kills from remote IRCOps will show up as regular quits, so use hooktype_remote_quit() and hooktype_local_quit().
   1700  * @param client		The client
   1701  * @param victim		The victim
   1702  * @param comment		The kill reason
   1703  * @return The return value is ignored (use return 0)
   1704  */
   1705 int hooktype_local_kill(Client *client, Client *victim, const char *comment);
   1706 
   1707 /** Called when an IRCOp calls /REHASH with a -parameter (function prototype for HOOKTYPE_REHASHFLAG).
   1708  * @param client		The client issuing the command, or NULL if rehashing due to system signal.
   1709  * @param str			The rehash flag (eg: "-all")
   1710  * @return The return value is ignored (use return 0)
   1711  */
   1712 int hooktype_rehashflag(Client *client, const char *str);
   1713 
   1714 /** Called when the server is rehashing (function prototype for HOOKTYPE_REHASH).
   1715  * @return The return value is ignored (use return 0)
   1716  */
   1717 int hooktype_rehash(void);
   1718 
   1719 /** Called when the server has completed rehashing (function prototype for HOOKTYPE_REHASH_COMPLETE).
   1720  * @return The return value is ignored (use return 0)
   1721  */
   1722 int hooktype_rehash_complete(void);
   1723 
   1724 /** Called when searching for a test function for a specific configuration item (function prototype for HOOKTYPE_CONFIGTEST).
   1725  * This is part of the configuration API, which is better documented at the
   1726  * wiki at https://www.unrealircd.org/docs/Dev:Configuration_API
   1727  * @param cfptr			Configuration file
   1728  * @param ce			Configuration entry
   1729  * @param section		One of CONFIG_*, eg: CONFIG_MAIN.
   1730  * @param errors		Counter for errors
   1731  * @retval 0			This entry is not for us, we don't know anything about it.
   1732  * @retval -1			Errors encountered (the number of errors is stored in *errors)
   1733  * @retval 1			This entry is handled and is without any errors.
   1734  */
   1735 int hooktype_configtest(ConfigFile *cfptr, ConfigEntry *ce, int section, int *errors);
   1736 
   1737 /** Called after all hooktype_configtest() have run, to check for missing config items (function prototype for HOOKTYPE_CONFIGPOSTTEST).
   1738  * @param errors		The number of errors
   1739  * @returns In case of errors, return -1.
   1740  */
   1741 int hooktype_configposttest(int *errors);
   1742 
   1743 /** Called to run/do the active configuration for this configuration item (function prototype for HOOKTYPE_CONFIGRUN).
   1744  * This is part of the configuration API, which is better documented at the
   1745  * wiki at https://www.unrealircd.org/docs/Dev:Configuration_API
   1746  * @param cfptr			Configuration file
   1747  * @param ce			Configuration entry
   1748  * @param section		One of CONFIG_*, eg: CONFIG_MAIN.
   1749  * @retval 0			This entry is not for us, we don't know anything about it.
   1750  * @retval 1			This entry is for us, it is now handled, don't call any other modules for it anymore.
   1751  */
   1752 int hooktype_configrun(ConfigFile *cfptr, ConfigEntry *ce, int section);
   1753 
   1754 /** Called to run/do the active configuration for this configuration item - extended version (function prototype for HOOKTYPE_CONFIGRUN_EX).
   1755  * This particular "extended version" is only used for extending listen { } options, so you probably don't need this one.
   1756  * Use hooktype_configrun() instead!
   1757  * @param cfptr			Configuration file
   1758  * @param ce			Configuration entry
   1759  * @param section		One of CONFIG_*, eg: CONFIG_MAIN.
   1760  * @param ptr			Pointer to something
   1761  * @retval 0			This entry is not for us, we don't know anything about it.
   1762  * @retval 1			This entry is for us, it is now handled, don't call any other modules for it anymore.
   1763  */
   1764 int hooktype_configrun_ex(ConfigFile *cfptr, ConfigEntry *ce, int section, void *ptr);
   1765 
   1766 /** Called when a user types /STATS <something> (function prototype for HOOKTYPE_STATS).
   1767  * This way a module can add a new STATS item, eg 'STATS something'
   1768  * @param client		The client issuing the command
   1769  * @param str			The parameter to the STATS command, eg 'something'.
   1770  * @return The return value is ignored (use return 0)
   1771  */
   1772 int hooktype_stats(Client *client, const char *str);
   1773 
   1774 /** Called when a user becomes IRCOp or is no longer an IRCOp (function prototype for HOOKTYPE_LOCAL_OPER).
   1775  * @param client		The client
   1776  * @param add			1 if the user becomes IRCOp, 0 if the user is no longer IRCOp
   1777  * @param oper_block		The name of the oper block used to oper up
   1778  * @param operclass		The name of the operclass
   1779  * @return The return value is ignored (use return 0)
   1780  */
   1781 int hooktype_local_oper(Client *client, int add, const char *oper_block, const char *operclass);
   1782 
   1783 /** Called when a client sends a PASS command (function prototype for HOOKTYPE_LOCAL_PASS).
   1784  * @param client		The client
   1785  * @param password		The password supplied by the client
   1786  * @return The return value is ignored (use return 0)
   1787  */
   1788 int hooktype_local_pass(Client *client, const char *password);
   1789 
   1790 /** Called when a channel is created (function prototype for HOOKTYPE_CHANNEL_CREATE).
   1791  * @param channel		The channel that just got created
   1792  * @note This function is not used much, use hooktype_local_join() and hooktype_remote_join() instead.
   1793  * @return The return value is ignored (use return 0)
   1794  */
   1795 int hooktype_channel_create(Channel *channel);
   1796 
   1797 /** Called when a channel is completely destroyed (function prototype for HOOKTYPE_CHANNEL_DESTROY).
   1798  * @param channel		The channel that is about to be destroyed
   1799  * @param should_destroy	Module can set this to 1 to prevent destriction
   1800  * @note A channel is usually destroyed due to the last user leaving. But in some cases
   1801  *       a channel is created and then immediately destroyed within nanoseconds. Just so you know.
   1802  * @return The return value is ignored (use return 0)
   1803  */
   1804 int hooktype_channel_destroy(Channel *channel, int *should_destroy);
   1805 
   1806 /** Called when a user matches a TKL and is pending to be killed (function prototype for HOOKTYPE_TKL_EXCEPT).
   1807  * @param client		The client
   1808  * @param ban_type		The TKL type, one of TKL_*. For example TKL_GLOBAL|TKL_KILL for a gline.
   1809  * @retval 0 Ban/kill the user.
   1810  * @retval 1 User is exempt, do NOT kill or ban.
   1811  */
   1812 int hooktype_tkl_except(Client *client, int ban_type);
   1813 
   1814 /** Called when the user modes of a user change (function prototype for HOOKTYPE_UMODE_CHANGE).
   1815  * @param client		The client
   1816  * @param setflags		The current user modes
   1817  * @param newflags		The new user modes
   1818  * @note The user mode can be changed due to a MODE by the user itself, by a server, or by SVSMODE/SVS2MODE from Services.
   1819  * @return The return value is ignored (use return 0)
   1820  */
   1821 int hooktype_umode_change(Client *client, long setflags, long newflags);
   1822 
   1823 /** Called when a new TKL is added (function prototype for HOOKTYPE_TKL_ADD).
   1824  * @param client		The client adding the TKL (this can be &me)
   1825  * @param tkl			The TKL entry
   1826  * @return The return value is ignored (use return 0)
   1827  */
   1828 int hooktype_tkl_add(Client *client, TKL *tkl);
   1829 
   1830 /** Called when removing an existing TKL (function prototype for HOOKTYPE_TKL_DEL).
   1831  * @param client		The client removing the TKL (this can be &me)
   1832  * @param tkl			The TKL entry
   1833  * @return The return value is ignored (use return 0)
   1834  */
   1835 int hooktype_tkl_del(Client *client, TKL *tkl);
   1836 
   1837 /** Called when something is logged via the unreal_log() function (function prototype for HOOKTYPE_LOG).
   1838  * @param loglevel		Loglevel (eg ULOG_INFO)
   1839  * @param subsystem		Subsystem (eg "operoverride")
   1840  * @param event_id		Event ID (eg "SAJOIN_COMMAND")
   1841  * @param msg			Message(s) in text form
   1842  * @param json			The JSON log entry
   1843  * @param json_serialized	The serialized JSON log entry (as a string)
   1844  * @param timebuf		The [xxxx] time buffer, for convenience
   1845  * @return The return value is ignored (use return 0)
   1846  */
   1847 int hooktype_log(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, json_t *json, const char *json_serialized, const char *timebuf);
   1848 
   1849 /** Called when a local user matches a spamfilter (function prototype for HOOKTYPE_LOCAL_SPAMFILTER).
   1850  * @param client		The client
   1851  * @param str			The text that matched, this may be stripped from color and control codes.
   1852  * @param str_in		The original text
   1853  * @param target		The spamfilter type, one of SPAMF_*, such as SPAMF_CHANMSG.
   1854  * @param destination		The destination, such as the name of another client or channel
   1855  * @param tkl			The spamfilter TKL entry that matched
   1856  * @return The return value is ignored (use return 0)
   1857  */
   1858 int hooktype_local_spamfilter(Client *client, const char *str, const char *str_in, int type, const char *target, TKL *tkl);
   1859 
   1860 /** Called when a user sends something to a user that has the sender silenced (function prototype for HOOKTYPE_SILENCED).
   1861  * UnrealIRCd support a SILENCE list. If the target user has added someone on the silence list, eg via SILENCE +BadUser,
   1862  * and then 'BadUser' tries to send a message to this user, this hook will be triggered.
   1863  * @param client		The client trying to send a message/notice
   1864  * @param target		The intended recipient of the message
   1865  * @param sendtype		Indicating if it is a PRIVMSG, NOTICE or something else.
   1866  * @note This function is rarely used.
   1867  * @return The return value is ignored (use return 0)
   1868  */
   1869 int hooktype_silenced(Client *client, Client *target, SendType sendtype);
   1870 
   1871 /** Called on every incoming packet (function prototype for HOOKTYPE_RAWPACKET_IN).
   1872  * This is quite invasive, so only use this if you cannot do the same via some other means (eg overrides or hooks).
   1873  * The typical use cases are things like: handling an entirely different protocol (eg: websocket module),
   1874  * or old stuff like codepage conversions, basically: things that work on entire packets.
   1875  * @param client		The client
   1876  * @param readbuf		The buffer
   1877  * @param length		The length of the buffer
   1878  * @note If you want to alter the buffer contents then replace 'readbuf' with your own buffer and set 'length' appropriately.
   1879  * @return The return value is ignored (use return 0)
   1880  */
   1881 int hooktype_rawpacket_in(Client *client, const char *readbuf, int *length);
   1882 
   1883 /** Called when a packet is received or sent (function prototype for HOOKTYPE_PACKET).
   1884  * @param client		The locally connected sender, this can be &me
   1885  * @param to			The locally connected recipient, this can be &me
   1886  * @param intended_to		The originally intended recipient, this could be a remote user
   1887  * @param msg			The buffer
   1888  * @param length		The length of the buffer
   1889  * @note When reading a packet, 'client' will indicate the locally connected user and 'to' will be &me.
   1890  *       When sending a pcket, 'client' will be &me and 'to' will be the locally connected user.
   1891  *       If you want to alter the buffer contents then replace 'msg' with your own buffer and set 'length' appropriately.
   1892  * @return The return value is ignored (use return 0)
   1893  */
   1894 int hooktype_packet(Client *from, Client *to, Client *intended_to, char **msg, int *length);
   1895 
   1896 /** Called very early when a client connects (function prototype for HOOKTYPE_HANDSHAKE).
   1897  * This is called as soon as the socket is connected and the client is being set up,
   1898  * so before the client has sent any application data, and certainly before it is
   1899  * known whether this client will become a user or a server.
   1900  * @param client		The client
   1901  * @return The return value is ignored (use return 0)
   1902  */
   1903 int hooktype_handshake(Client *client);
   1904 
   1905 /** Called very early when a client connects (function prototype for HOOKTYPE_ACCEPT).
   1906  * Module coders: have a look at hooktype_handshake() instead of this one!
   1907  * HOOKTYPE_ACCEPT is called even before HOOKTYPE_HANDSHAKE, as soon as the socket
   1908  * is connected and during the client is being set up, before the SSL/TLS handshake.
   1909  * It is only used for connection flood detection and checking (G)Z-lines.
   1910  * Note that this connection is also called for *NIX domain socket connections,
   1911  * HTTP(S) requests, and so on.
   1912  * @param client		The client
   1913  * @return One of HOOK_*. Use HOOK_DENY to reject the client.
   1914  */
   1915 int hooktype_accept(Client *client);
   1916 
   1917 /** Called when a client structure is freed (function prototype for HOOKTYPE_FREE_CLIENT).
   1918  * @param client		The client
   1919  * @note Normally you use hooktype_local_quit(), hooktype_remote_quit() and hooktype_unkuser_quit() for this.
   1920  * @return The return value is ignored (use return 0)
   1921  */
   1922 int hooktype_free_client(Client *client);
   1923 
   1924 /** Called when the user structure, client->user, is being freed (function prototype for HOOKTYPE_FREE_USER).
   1925  * @param client		The client
   1926  * @return The return value is ignored (use return 0)
   1927  */
   1928 int hooktype_free_user(Client *client);
   1929 
   1930 /** Called when +l limit is exceeded when joining (function prototype for HOOKTYPE_CAN_JOIN_LIMITEXCEEDED).
   1931  * @param client		The client
   1932  * @param channel		The channel
   1933  * @param key			The channel key
   1934  * @note I don't think this works?
   1935  * @return Unclear..
   1936  */
   1937 int hooktype_can_join_limitexceeded(Client *client, Channel *channel, const char *key, char **errmsg);
   1938 
   1939 /** Called to check if the user is visible in the channel (function prototype for HOOKTYPE_VISIBLE_IN_CHANNEL).
   1940  * For example, the delayjoin module (+d/+D) will 'return 0' here if the user is hidden due to delayed join.
   1941  * @param client		The client
   1942  * @param channel		The channel
   1943  * @retval 0 The user is NOT visible
   1944  * @retval 1 The user is visible
   1945  */
   1946 int hooktype_visible_in_channel(Client *client, Channel *channel);
   1947 
   1948 /** Called to check if the channel of a user should be shown in WHOIS/WHO (function prototype for HOOKTYPE_SEE_CHANNEL_IN_WHOIS).
   1949  * @param client		The client ASKING, eg doing the /WHOIS.
   1950  * @param target		The client who is being interrogated
   1951  * @param channel		The channel that 'client' is in
   1952  * @retval 0 The channel should NOT be visible
   1953  * @retval 1 Show the channel
   1954  */
   1955 int hooktype_see_channel_in_whois(Client *client, Client *target, Channel *channel);
   1956 
   1957 /** Called when a user is added to a channel (function prototype for HOOKTYPE_JOIN_DATA).
   1958  * Note that normally you use hooktype_local_join() and hooktype_remote_join() for this.
   1959  * This function only exists so it is easy to work with dynamic data, and even
   1960  * that is an old idea now that we have the moddata system.
   1961  * @param client		The client joining
   1962  * @param channel		The channel the client joined to
   1963  * @return The return value is ignored (use return 0)
   1964  */
   1965 int hooktype_join_data(Client *who, Channel *channel);
   1966 
   1967 /** Should the user be able to bypass channel restrictions because they are invited? (function prototype for HOOKTYPE_INVITE_BYPASS).
   1968  * @param client		The client
   1969  * @param channel		The channel
   1970  * @retval HOOK_DENY		Don't allow the user to bypass channel restrictions when they are invited
   1971  * @retval HOOK_CONTINUE	Obey the normal rules
   1972  * @note Usually you want a user to be able to bypass channel restrictions such as +l or +b when they are /INVITEd by another user
   1973  *       or have invited themselves (OperOverride). But, there may be special cases where you don't want this.
   1974  *       For example, this hook is used by +O to still not allow ircops to join +O channels even if they have OperOverride capability.
   1975  */
   1976 int hooktype_invite_bypass(Client *client, Channel *channel);
   1977 
   1978 /** Should a user be able to view the topic when not in the channel? (function prototype for HOOKTYPE_VIEW_TOPIC_OUTSIDE_CHANNEL).
   1979  * @param client		The client requesting the topic
   1980  * @param channel		The channel
   1981  * @note This visibility check is only partially implemented. Do not count on it.
   1982  * @retval HOOK_DENY		Deny the topic request
   1983  * @retval HOOK_CONTINUE	Obey the normal rules
   1984  */
   1985 int hooktype_view_topic_outside_channel(Client *client, Channel *channel);
   1986 
   1987 /** Is a user permitted to change its nickname? (function prototype for HOOKTYPE_CHAN_PERMIT_NICK_CHANGE).
   1988  * This is called for each channel the user is in. This is used by the +N (nonickchange) channel mode.
   1989  * @param client		The client
   1990  * @param channel		The channel the user is in
   1991  * @retval HOOK_DENY		Deny the nick change
   1992  * @retval HOOK_CONTINUE	Obey the normal rules (allow it, unless denied by something else)
   1993  */
   1994 int hooktype_chan_permit_nick_change(Client *client, Channel *channel);
   1995 
   1996 /** Is the channel considered "secure"? (function prototype for HOOKTYPE_IS_CHANNEL_SECURE).
   1997  * This is used by the +z/+Z modules.
   1998  * @param channel		The channel
   1999  * @retval 0			No, the channel is not secure
   2000  * @retval 1			Yes, the channel is secure
   2001  */
   2002 int hooktype_is_channel_secure(Channel *channel);
   2003 
   2004 /** Called after a channel is synced due to netmerge (function prototype for HOOKTYPE_CHANNEL_SYNCED).
   2005  * When a server connects channel status is exchanged in order to synchronize the two sides of channels.
   2006  * After each SJOIN command this function is called to check if anything special
   2007  * needs to be join. At the moment this function is only used by channel mode +z
   2008  * which will kick out any insecure users if we are the "loosing" side of a split.
   2009  * @param channel		The channel
   2010  * @param merge			Set to 1 if merging due to equal timestamps on both sides, 0 otherwise
   2011  * @param removetheirs		Set to 1 if the other side is the loosing side and we are the winning side.
   2012  * @param nomode		Set to 1 if this is a SJOIN without modes (rare? services?)
   2013  * @retval HOOK_DENY		Deny the channel merge. Important: only return this after you have destroyed the channel!
   2014  * @retval HOOK_CONTINUE	Continue normally
   2015  */
   2016 int hooktype_channel_synced(Channel *channel, int merge, int removetheirs, int nomode);
   2017 
   2018 /** Can the target client be SAJOIN'ed to a particular channel? (function prototype for HOOKTYPE_CAN_SAJOIN).
   2019  * @param target		The client that should be joined
   2020  * @param channel		The channel that the client should be joined to
   2021  * @param client		The client issuing the request (usually IRCOp)
   2022  * @retval HOOK_DENY		Deny the SAJOIN
   2023  * @retval HOOK_CONTINUE	Allow the SAJOIN, unless blocked by something else
   2024  */
   2025 int hooktype_can_sajoin(Client *target, Channel *channel, Client *client);
   2026 
   2027 /** May the target user be deoped? (function prototype for HOOKTYPE_MODE_DEOP).
   2028  * This is for example used by the +S (Services bot) user mode to block deop requests to services bots.
   2029  * @param client		The client issuing the command
   2030  * @param victim		The victim that should be deoped (MODE -o)
   2031  * @param channel		The channel
   2032  * @param what			Always MODE_DEL at the moment
   2033  * @param modechar		The mode character: q/a/o/h/v
   2034  * @param client_access		Channel member modes of 'client', eg "o", never NULL but can be empty.
   2035  * @param target_access		Channel member modes of 'client', eg "h", never NULL but can be empty.
   2036  * @param reject_reason		The error string that should be sent to the client
   2037  * @retval HOOK_CONTINUE	Proceed normally (allow it)
   2038  * @retval HOOK_DENY		Reject the mode change
   2039  * @retval HOOK_ALWAYS_DENY	Reject the mode change, even if IRCOp/Services/..
   2040  */
   2041 int hooktype_mode_deop(Client *client, Client *victim, Channel *channel, u_int what, int modechar, const char *client_access, const char *target_access, const char **reject_reason);
   2042 
   2043 /** Called when a DCC request was denied by the IRCd (function prototype for HOOKTYPE_DCC_DENIED).
   2044  * @param client		The client who tried to send a file
   2045  * @param target		The intended recipient
   2046  * @param realfile		The original file name, may contain strange characters or be very long
   2047  * @param displayfile		The file name for displaying purposes, properly filtered.
   2048  * @param denydcc		The deny dcc { ] rule that triggered.
   2049  * @return The return value is ignored (use return 0)
   2050  */
   2051 int hooktype_dcc_denied(Client *client, const char *target, const char *realfile, const char *displayfile, ConfigItem_deny_dcc *denydcc);
   2052 
   2053 /** Called in the user accept procedure, when setting the +z user mode (function prototype for HOOKTYPE_SECURE_CONNECT).
   2054  * This is only meant to be used by the WEBIRC module, so it can do -z for fake secure users.
   2055  * @param client		The client
   2056  * @return The return value is ignored (use return 0)
   2057  */
   2058 int hooktype_secure_connect(Client *client);
   2059 
   2060 /** Can the user bypass a particular channel message restriction? (function prototype for HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION).
   2061  * This is for example used to bypass +S (stripcolor) via ~m:color:*!*@a.b.c.d if the user matches that extban.
   2062  * @param client		The client (sender)
   2063  * @param channel		The channel
   2064  * @param bypass_type		The restriction to bypass, for example BYPASS_CHANMSG_COLOR
   2065  * @retval HOOK_ALLOW		Allow to bypass the restriction
   2066  * @retval HOOK_CONTINUE	Continue as normal, obey normal rules, deny bypassing the restriction.
   2067  */
   2068 int hooktype_can_bypass_channel_message_restriction(Client *client, Channel *channel, BypassChannelMessageRestrictionType bypass_type);
   2069 
   2070 /** Called when a SASL continuation response is received (function prototype for HOOKTYPE_SASL_CONTINUATION).
   2071  * This is only used by the authprompt module, it unlikely that you need it.
   2072  * @param client		The client for which the SASL authentication is taking place
   2073  * @param buf			The AUTHENTICATE buffer
   2074  * @retval HOOK_CONTINUE	Continue as normal
   2075  * @retval HOOK_DENY		Do not handle the SASL request, or at least don't show the response to the client.
   2076  */
   2077 int hooktype_sasl_continuation(Client *client, const char *buf);
   2078 
   2079 /** Called when a SASL result response is received (function prototype for HOOKTYPE_SASL_RESULT).
   2080  * This is only used by the authprompt module.
   2081  * @param client		The client for which the SASL authentication is taking place
   2082  * @param successs		Whether the SASL authentication was successful (1) or not (0)
   2083  * @retval HOOK_CONTINUE	Continue as normal
   2084  * @retval HOOK_DENY		Do not handle the SASL response, or at least don't show the response to the client.
   2085  */
   2086 int hooktype_sasl_result(Client *client, int success);
   2087 
   2088 /** Called when a TKL ban should be added on the host (function prototype for HOOKTYPE_PLACE_HOST_BAN).
   2089  * This is called for automated bans such as spamfilter hits, flooding, etc.
   2090  * This hook can be used to prevent the ban, or as used by the authprompt to delay it.
   2091  * @param client		The client that should be banned
   2092  * @param action		The TKL type, such as BAN_ACT_GLINE
   2093  * @param reason		The ban reason
   2094  * @param duration		The duration of the ban, 0 for permanent ban
   2095  * @return The magic value 99 is used to exempt the user (=do not ban!), otherwise the ban is added.
   2096  */
   2097 int hooktype_place_host_ban(Client *client, int action, const char *reason, long duration);
   2098 
   2099 /** Called when a TKL ban is hit by this user (function prototype for HOOKTYPE_FIND_TKLINE_MATCH).
   2100  * This is called when an existing TKL entry is hit by the user.
   2101  * To prevent an automated ban to be added on a host/ip, see hooktype_place_host_ban().
   2102  * @param client		The client
   2103  * @param tkl			The TKL entry
   2104  * @return The magic value 99 is used to exempt the user (=do not kill!), otherwise the ban is executed.
   2105  */
   2106 int hooktype_find_tkline_match(Client *client, TKL *tk);
   2107 
   2108 /** Called when the user connects for each welcome numeric (function prototype for HOOKTYPE_WELCOME).
   2109  * This can be used to send some additional notice or data to the user at a step of your choosing.
   2110  * This is called before all numerics with 'after_numeric' set to 0, and then after numeric
   2111  * 001, 002, 003, 005, 396, 266, 376. In the last call, 'after_numeric' is 999 when all initial
   2112  * numerics have been sent but before the user is auto-joined to channels (if any).
   2113  * @param client		The client
   2114  * @param after_numeric		Which numeric has just been sent
   2115  * @return The return value is ignored (use return 0)
   2116  */
   2117 int hooktype_welcome(Client *client, int after_numeric);
   2118 
   2119 /** Called right before parsing a line and client command (function prototype for HOOKTYPE_PRE_COMMAND).
   2120  * This is only used by labeled-reponse. If you think this hook is useful then you
   2121  * should probably use the CommandOverride API instead!
   2122  * @param client		The direct local client connection from which the line is received.
   2123  * @param mtags			Message tags, if any.
   2124  * @param buf			The buffer (without message tags)
   2125  * @return The return value is ignored (use return 0)
   2126  */
   2127 int hooktype_pre_command(Client *from, MessageTag *mtags, const char *buf);
   2128 
   2129 /** Called right after finishing a client command (function prototype for HOOKTYPE_POST_COMMAND).
   2130  * This is only used by labeled-reponse. If you think this hook is useful then you
   2131  * should probably use the CommandOverride API instead!
   2132  * @param client		The direct local client connection from which the line is received.
   2133  * @param mtags			Message tags, if any.
   2134  * @param buf			The buffer (without message tags)
   2135  * @return The return value is ignored (use return 0)
   2136  */
   2137 int hooktype_post_command(Client *from, MessageTag *mtags, const char *buf);
   2138 
   2139 /** Called when new_message() is executed (function prototype for HOOKTYPE_NEW_MESSAGE).
   2140  * When a new message with message tags is prepared, code in UnrealIRCd
   2141  * and in modules will call new_message(). From that function this hook
   2142  * is also called. The purpose of this hook is so you can add additional
   2143  * message tags that belong the user. For example it is used
   2144  * by the account-tag module to add account=xyz information, see that module for a good example.
   2145  * @param sender		The client from which the message will be sent
   2146  * @param recv_mtags		The message tags as originally received before, or NULL if completely new.
   2147  * @param mtag_list		The newly created message tag list that we are building
   2148  * @param signature		Special signature when used through new_message_special()
   2149  * @return The return value is ignored (use return 0)
   2150  */
   2151 void hooktype_new_message(Client *sender, MessageTag *recv_mtags, MessageTag **mtag_list, const char *signature);
   2152 
   2153 /** Is the client handshake finished? (function prototype for HOOKTYPE_IS_HANDSHAKE_FINISHED).
   2154  * This is called by the is_handshake_finished() function to check if the user
   2155  * can be accepted on IRC, or if there are still other checks/input pending.
   2156  * This can be used to "hold" a user temporarily until something happens, such
   2157  * as the user typing a password or waiting for a remote access check to return a result.
   2158  * For an example usage, see the cap module, which uses it to "hold" the connection
   2159  * if a "CAP LS" has been sent and no "CAP END" has been received yet.
   2160  * @param client		The client
   2161  * @retval 1			Yes, the handshake is finished, as far as we are concerned.
   2162  * @retval 0			No, the handshake is not yet finished, do not allow the user in yet.
   2163  */
   2164 int hooktype_is_handshake_finished(Client *client);
   2165 
   2166 /** Called upon a local client quit, allows altering the quit message on a per-channel basis (function prototype for HOOKTYPE_PRE_LOCAL_QUIT_CHAN).
   2167  * If you don't need to change the quit message on a per-channel basis, but want to change it regardless of channels, then use hooktype_pre_local_quit().
   2168  * If you don't need to change the quit message at all, then use hooktype_local_quit() and hooktype_remote_quit() instead.
   2169  * @param client		The client
   2170  * @param channel		The channel
   2171  * @param comment		The quit message
   2172  * @return The original quit message (comment), the new quit message (pointing to your own static buffer), or NULL (no quit message)
   2173  */
   2174 const char *hooktype_pre_local_quit_chan(Client *client, Channel *channel, const char *comment);
   2175 
   2176 /** Called when an ident lookup should be made (function prototype for HOOKTYPE_IDENT_LOOKUP).
   2177  * This is used by the ident_lookup module.
   2178  * @param client		The client
   2179  * @return The return value is ignored (use return 0)
   2180  */
   2181 int hooktype_ident_lookup(Client *client);
   2182 
   2183 /** Called when someone logs in/out a services account (function prototype for HOOKTYPE_ACCOUNT_LOGIN).
   2184  * The account name can be found in client->user->account. It will be the string "0" if the user is logged out.
   2185  * @param client		The client
   2186  * @param mtags         	Message tags associated with the event
   2187  * @return The return value is ignored (use return 0)
   2188  */
   2189 int hooktype_account_login(Client *client, MessageTag *mtags);
   2190 
   2191 /** Called when closing the connection of a local user (function prototype for HOOKTYPE_CLOSE_CONNECTION).
   2192  * This is called from close_connection(). Note that a lot of client information
   2193  * has already been freed, so normally you should use the quit/exit functions instead:
   2194  * hooktype_local_quit(), hooktype_remote_quit() and hooktype_unkuser_quit().
   2195  * @param client		The client
   2196  * @return The return value is ignored (use return 0)
   2197  */
   2198 int hooktype_close_connection(Client *client);
   2199 
   2200 /** Called when a user connects to add extra information (function prototype for HOOKTYPE_CONNECT_EXTINFO).
   2201  * If you want to use this, then use the nvplist_add() or nvplist_add_fmt() function
   2202  * to add the information to the list. See also get_connect_extinfo() for inspiration.
   2203  * @param client		The client
   2204  * @param list			The name/value/prio list that you can add information to
   2205  * @return The return value is ignored (use return 0)
   2206  */
   2207 int hooktype_connect_extinfo(Client *client, NameValuePrioList **list);
   2208 
   2209 /** Called when a user wants to join a channel that require invitation.
   2210  * Use hook priorities to enforce a specific policy, especially denying the invitation.
   2211  * @param client		The client
   2212  * @param channel		The channel client is willing to join
   2213  * @param invited		Set to 0 for user who should not be invited, set to 1 if the user is invited.
   2214  * @return The return value is ignored (use return 0)
   2215  */
   2216 int hooktype_is_invited(Client *client, Channel *channel, int *invited);
   2217 
   2218 /** Called after a local user has changed the nick name (function prototype for HOOKTYPE_POST_LOCAL_NICKCHANGE).
   2219  * @param client		The client
   2220  * @param mtags         	Message tags associated with the event
   2221  * @param oldnick		The nick name before the nick change
   2222  * @return The return value is ignored (use return 0)
   2223  */
   2224 int hooktype_post_local_nickchange(Client *client, MessageTag *mtags, const char *oldnick);
   2225 
   2226 /** Called after a remote user has changed the nick name (function prototype for HOOKTYPE_POST_REMOTE_NICKCHANGE).
   2227  * @param client		The client
   2228  * @param mtags         	Message tags associated with the event
   2229  * @param oldnick		The nick name before the nick change
   2230  * @return The return value is ignored (use return 0)
   2231  */
   2232 int hooktype_post_remote_nickchange(Client *client, MessageTag *mtags, const char *oldnick);
   2233 
   2234 /** Called when user name or user host has changed.
   2235  * @param client		The client whose user@host has changed
   2236  * @param olduser		Old username of the client
   2237  * @param oldhost		Old hostname of the client
   2238  * @return The return value is ignored (use return 0)
   2239  */
   2240 int hooktype_userhost_change(Client *client, const char *olduser, const char *oldhost);
   2241 
   2242 /** Called when user realname has changed.
   2243  * @param client		The client whose realname has changed
   2244  * @param oldinfo		Old realname of the client
   2245  * @return The return value is ignored (use return 0)
   2246  */
   2247 int hooktype_realname_change(Client *client, const char *oldinfo);
   2248 
   2249 /** Called when changing IP (eg due to PROXY/WEBIRC/etc).
   2250  * @param client		The client whose IP has changed
   2251  * @param oldip			Old IP of the client
   2252  * @return The return value is ignored (use return 0)
   2253  */
   2254 int hooktype_ip_change(Client *client, const char *oldip);
   2255 
   2256 /** Called when json_expand_client() is called.
   2257  * Used for expanding information about 'client' in logging routines.
   2258  * @param client		The client that should be expanded
   2259  * @param detail		The amount of detail to provide (always 0 at the moment)
   2260  * @param j			The JSON object
   2261  * @return The return value is ignored (use return 0)
   2262  */
   2263 int hooktype_json_expand_client(Client *client, int detail, json_t *j);
   2264 
   2265 /** Called when json_expand_client_user() is called.
   2266  * Used for expanding information about 'client' in logging routines
   2267  * when the client is a USER.
   2268  * @param client		The client that should be expanded
   2269  * @param detail		The amount of detail to provide (always 0 at the moment)
   2270  * @param j			The JSON object - root
   2271  * @param child			The JSON object - "user" child item
   2272  * @return The return value is ignored (use return 0)
   2273  */
   2274 int hooktype_json_expand_client_user(Client *client, int detail, json_t *j, json_t *child);
   2275 
   2276 /** Called when json_expand_client_server() is called.
   2277  * Used for expanding information about 'client' in logging routines
   2278  * when the client is a SERVER.
   2279  * @param client		The client that should be expanded
   2280  * @param detail		The amount of detail to provide (always 0 at the moment)
   2281  * @param j			The JSON object - root
   2282  * @param child			The JSON object - "server" child item
   2283  * @return The return value is ignored (use return 0)
   2284  */
   2285 int hooktype_json_expand_client_server(Client *client, int detail, json_t *j, json_t *child);
   2286 
   2287 /** Called when json_expand_channel() is called.
   2288  * Used for expanding information about 'channel' in logging routines.
   2289  * @param channel		The channel that should be expanded
   2290  * @param detail		The amount of detail to provide (always 0 at the moment)
   2291  * @param j			The JSON object
   2292  * @return The return value is ignored (use return 0)
   2293  */
   2294 int hooktype_json_expand_channel(Channel *channel, int detail, json_t *j);
   2295 
   2296 /** Called when a local user is about to be disconnected due to a registration timeout,
   2297  * allows changing the disconnect reason (function prototype for HOOKTYPE_PRE_LOCAL_HANDSHAKE_TIMEOUT).
   2298  * This is used by the authprompt module.
   2299  * @param client		The client
   2300  * @param comment		The quit/disconnect reason (can be changed by you)
   2301  * @retval HOOK_CONTINUE	Continue as normal
   2302  * @retval HOOK_ALLOW		Do not exit the user due to a handshake timeout
   2303  */
   2304 int hooktype_pre_local_handshake_timeout(Client *client, const char **comment);
   2305 
   2306 /** Called when a REHASH completed (either succesfully or with a failure).
   2307  * This gives the full rehash log. Used by the JSON-RPC interface.
   2308  * @param failure		Set to 1 if the rehash failed, otherwise 0.
   2309  * @param t			The JSON object containing the rehash log and other information.
   2310  * @return The return value is ignored (use return 0)
   2311  */
   2312 int hooktype_rehash_log(int failure, json_t *rehash_log);
   2313 
   2314 /** @} */
   2315 
   2316 #ifdef GCC_TYPECHECKING
   2317 #define ValidateHook(validatefunc, func) __builtin_types_compatible_p(__typeof__(func), __typeof__(validatefunc))
   2318 
   2319 _UNREAL_ERROR(_hook_error_incompatible, "Incompatible hook function. Check arguments and return type of function.")
   2320 
   2321 #define ValidateHooks(hooktype, func) \
   2322     if (((hooktype == HOOKTYPE_LOCAL_QUIT) && !ValidateHook(hooktype_local_quit, func)) || \
   2323         ((hooktype == HOOKTYPE_LOCAL_NICKCHANGE) && !ValidateHook(hooktype_local_nickchange, func)) || \
   2324         ((hooktype == HOOKTYPE_LOCAL_CONNECT) && !ValidateHook(hooktype_local_connect, func)) || \
   2325         ((hooktype == HOOKTYPE_REHASHFLAG) && !ValidateHook(hooktype_rehashflag, func)) || \
   2326         ((hooktype == HOOKTYPE_PRE_LOCAL_PART) && !ValidateHook(hooktype_pre_local_part, func)) || \
   2327         ((hooktype == HOOKTYPE_CONFIGPOSTTEST) && !ValidateHook(hooktype_configposttest, func)) || \
   2328         ((hooktype == HOOKTYPE_REHASH) && !ValidateHook(hooktype_rehash, func)) || \
   2329         ((hooktype == HOOKTYPE_PRE_LOCAL_CONNECT) && !ValidateHook(hooktype_pre_local_connect, func)) || \
   2330         ((hooktype == HOOKTYPE_PRE_LOCAL_QUIT) && !ValidateHook(hooktype_pre_local_quit, func)) || \
   2331         ((hooktype == HOOKTYPE_SERVER_CONNECT) && !ValidateHook(hooktype_server_connect, func)) || \
   2332         ((hooktype == HOOKTYPE_SERVER_SYNC) && !ValidateHook(hooktype_server_sync, func)) || \
   2333         ((hooktype == HOOKTYPE_SERVER_QUIT) && !ValidateHook(hooktype_server_quit, func)) || \
   2334         ((hooktype == HOOKTYPE_STATS) && !ValidateHook(hooktype_stats, func)) || \
   2335         ((hooktype == HOOKTYPE_LOCAL_JOIN) && !ValidateHook(hooktype_local_join, func)) || \
   2336         ((hooktype == HOOKTYPE_CONFIGTEST) && !ValidateHook(hooktype_configtest, func)) || \
   2337         ((hooktype == HOOKTYPE_CONFIGRUN) && !ValidateHook(hooktype_configrun, func)) || \
   2338         ((hooktype == HOOKTYPE_USERMSG) && !ValidateHook(hooktype_usermsg, func)) || \
   2339         ((hooktype == HOOKTYPE_CHANMSG) && !ValidateHook(hooktype_chanmsg, func)) || \
   2340         ((hooktype == HOOKTYPE_LOCAL_PART) && !ValidateHook(hooktype_local_part, func)) || \
   2341         ((hooktype == HOOKTYPE_LOCAL_KICK) && !ValidateHook(hooktype_local_kick, func)) || \
   2342         ((hooktype == HOOKTYPE_LOCAL_CHANMODE) && !ValidateHook(hooktype_local_chanmode, func)) || \
   2343         ((hooktype == HOOKTYPE_LOCAL_OPER) && !ValidateHook(hooktype_local_oper, func)) || \
   2344         ((hooktype == HOOKTYPE_UNKUSER_QUIT) && !ValidateHook(hooktype_unkuser_quit, func)) || \
   2345         ((hooktype == HOOKTYPE_LOCAL_PASS) && !ValidateHook(hooktype_local_pass, func)) || \
   2346         ((hooktype == HOOKTYPE_REMOTE_CONNECT) && !ValidateHook(hooktype_remote_connect, func)) || \
   2347         ((hooktype == HOOKTYPE_REMOTE_QUIT) && !ValidateHook(hooktype_remote_quit, func)) || \
   2348         ((hooktype == HOOKTYPE_PRE_LOCAL_JOIN) && !ValidateHook(hooktype_pre_local_join, func)) || \
   2349         ((hooktype == HOOKTYPE_PRE_LOCAL_KICK) && !ValidateHook(hooktype_pre_local_kick, func)) || \
   2350         ((hooktype == HOOKTYPE_CAN_SET_TOPIC) && !ValidateHook(hooktype_can_set_topic, func)) || \
   2351         ((hooktype == HOOKTYPE_PRE_LOCAL_TOPIC) && !ValidateHook(hooktype_pre_local_topic, func)) || \
   2352         ((hooktype == HOOKTYPE_REMOTE_NICKCHANGE) && !ValidateHook(hooktype_remote_nickchange, func)) || \
   2353         ((hooktype == HOOKTYPE_CHANNEL_CREATE) && !ValidateHook(hooktype_channel_create, func)) || \
   2354         ((hooktype == HOOKTYPE_CHANNEL_DESTROY) && !ValidateHook(hooktype_channel_destroy, func)) || \
   2355         ((hooktype == HOOKTYPE_REMOTE_CHANMODE) && !ValidateHook(hooktype_remote_chanmode, func)) || \
   2356         ((hooktype == HOOKTYPE_TKL_EXCEPT) && !ValidateHook(hooktype_tkl_except, func)) || \
   2357         ((hooktype == HOOKTYPE_UMODE_CHANGE) && !ValidateHook(hooktype_umode_change, func)) || \
   2358         ((hooktype == HOOKTYPE_TOPIC) && !ValidateHook(hooktype_topic, func)) || \
   2359         ((hooktype == HOOKTYPE_REHASH_COMPLETE) && !ValidateHook(hooktype_rehash_complete, func)) || \
   2360         ((hooktype == HOOKTYPE_TKL_ADD) && !ValidateHook(hooktype_tkl_add, func)) || \
   2361         ((hooktype == HOOKTYPE_TKL_DEL) && !ValidateHook(hooktype_tkl_del, func)) || \
   2362         ((hooktype == HOOKTYPE_LOCAL_KILL) && !ValidateHook(hooktype_local_kill, func)) || \
   2363         ((hooktype == HOOKTYPE_LOG) && !ValidateHook(hooktype_log, func)) || \
   2364         ((hooktype == HOOKTYPE_REMOTE_JOIN) && !ValidateHook(hooktype_remote_join, func)) || \
   2365         ((hooktype == HOOKTYPE_REMOTE_PART) && !ValidateHook(hooktype_remote_part, func)) || \
   2366         ((hooktype == HOOKTYPE_REMOTE_KICK) && !ValidateHook(hooktype_remote_kick, func)) || \
   2367         ((hooktype == HOOKTYPE_LOCAL_SPAMFILTER) && !ValidateHook(hooktype_local_spamfilter, func)) || \
   2368         ((hooktype == HOOKTYPE_SILENCED) && !ValidateHook(hooktype_silenced, func)) || \
   2369         ((hooktype == HOOKTYPE_POST_SERVER_CONNECT) && !ValidateHook(hooktype_post_server_connect, func)) || \
   2370         ((hooktype == HOOKTYPE_RAWPACKET_IN) && !ValidateHook(hooktype_rawpacket_in, func)) || \
   2371         ((hooktype == HOOKTYPE_PACKET) && !ValidateHook(hooktype_packet, func)) || \
   2372         ((hooktype == HOOKTYPE_HANDSHAKE) && !ValidateHook(hooktype_handshake, func)) || \
   2373         ((hooktype == HOOKTYPE_AWAY) && !ValidateHook(hooktype_away, func)) || \
   2374         ((hooktype == HOOKTYPE_INVITE) && !ValidateHook(hooktype_invite, func)) || \
   2375         ((hooktype == HOOKTYPE_CAN_JOIN) && !ValidateHook(hooktype_can_join, func)) || \
   2376         ((hooktype == HOOKTYPE_CAN_SEND_TO_CHANNEL) && !ValidateHook(hooktype_can_send_to_channel, func)) || \
   2377         ((hooktype == HOOKTYPE_CAN_SEND_TO_USER) && !ValidateHook(hooktype_can_send_to_user, func)) || \
   2378         ((hooktype == HOOKTYPE_CAN_KICK) && !ValidateHook(hooktype_can_kick, func)) || \
   2379         ((hooktype == HOOKTYPE_FREE_CLIENT) && !ValidateHook(hooktype_free_client, func)) || \
   2380         ((hooktype == HOOKTYPE_FREE_USER) && !ValidateHook(hooktype_free_user, func)) || \
   2381         ((hooktype == HOOKTYPE_PRE_CHANMSG) && !ValidateHook(hooktype_pre_chanmsg, func)) || \
   2382         ((hooktype == HOOKTYPE_KNOCK) && !ValidateHook(hooktype_knock, func)) || \
   2383         ((hooktype == HOOKTYPE_MODECHAR_ADD) && !ValidateHook(hooktype_modechar_add, func)) || \
   2384         ((hooktype == HOOKTYPE_MODECHAR_DEL) && !ValidateHook(hooktype_modechar_del, func)) || \
   2385         ((hooktype == HOOKTYPE_CAN_JOIN_LIMITEXCEEDED) && !ValidateHook(hooktype_can_join_limitexceeded, func)) || \
   2386         ((hooktype == HOOKTYPE_VISIBLE_IN_CHANNEL) && !ValidateHook(hooktype_visible_in_channel, func)) || \
   2387         ((hooktype == HOOKTYPE_PRE_LOCAL_CHANMODE) && !ValidateHook(hooktype_pre_local_chanmode, func)) || \
   2388         ((hooktype == HOOKTYPE_PRE_REMOTE_CHANMODE) && !ValidateHook(hooktype_pre_remote_chanmode, func)) || \
   2389         ((hooktype == HOOKTYPE_JOIN_DATA) && !ValidateHook(hooktype_join_data, func)) || \
   2390         ((hooktype == HOOKTYPE_PRE_KNOCK) && !ValidateHook(hooktype_pre_knock, func)) || \
   2391         ((hooktype == HOOKTYPE_PRE_INVITE) && !ValidateHook(hooktype_pre_invite, func)) || \
   2392         ((hooktype == HOOKTYPE_INVITE_BYPASS) && !ValidateHook(hooktype_invite_bypass, func)) || \
   2393         ((hooktype == HOOKTYPE_VIEW_TOPIC_OUTSIDE_CHANNEL) && !ValidateHook(hooktype_view_topic_outside_channel, func)) || \
   2394         ((hooktype == HOOKTYPE_CHAN_PERMIT_NICK_CHANGE) && !ValidateHook(hooktype_chan_permit_nick_change, func)) || \
   2395         ((hooktype == HOOKTYPE_IS_CHANNEL_SECURE) && !ValidateHook(hooktype_is_channel_secure, func)) || \
   2396         ((hooktype == HOOKTYPE_CHANNEL_SYNCED) && !ValidateHook(hooktype_channel_synced, func)) || \
   2397         ((hooktype == HOOKTYPE_CAN_SAJOIN) && !ValidateHook(hooktype_can_sajoin, func)) || \
   2398         ((hooktype == HOOKTYPE_WHOIS) && !ValidateHook(hooktype_whois, func)) || \
   2399         ((hooktype == HOOKTYPE_WHO_STATUS) && !ValidateHook(hooktype_who_status, func)) || \
   2400         ((hooktype == HOOKTYPE_MODE_DEOP) && !ValidateHook(hooktype_mode_deop, func)) || \
   2401         ((hooktype == HOOKTYPE_PRE_KILL) && !ValidateHook(hooktype_pre_kill, func)) || \
   2402         ((hooktype == HOOKTYPE_SEE_CHANNEL_IN_WHOIS) && !ValidateHook(hooktype_see_channel_in_whois, func)) || \
   2403         ((hooktype == HOOKTYPE_DCC_DENIED) && !ValidateHook(hooktype_dcc_denied, func)) || \
   2404         ((hooktype == HOOKTYPE_SERVER_HANDSHAKE_OUT) && !ValidateHook(hooktype_server_handshake_out, func)) || \
   2405         ((hooktype == HOOKTYPE_SERVER_SYNCED) && !ValidateHook(hooktype_server_synced, func)) || \
   2406         ((hooktype == HOOKTYPE_SECURE_CONNECT) && !ValidateHook(hooktype_secure_connect, func)) || \
   2407         ((hooktype == HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION) && !ValidateHook(hooktype_can_bypass_channel_message_restriction, func)) || \
   2408         ((hooktype == HOOKTYPE_SASL_CONTINUATION) && !ValidateHook(hooktype_sasl_continuation, func)) || \
   2409         ((hooktype == HOOKTYPE_SASL_RESULT) && !ValidateHook(hooktype_sasl_result, func)) || \
   2410         ((hooktype == HOOKTYPE_PLACE_HOST_BAN) && !ValidateHook(hooktype_place_host_ban, func)) || \
   2411         ((hooktype == HOOKTYPE_FIND_TKLINE_MATCH) && !ValidateHook(hooktype_find_tkline_match, func)) || \
   2412         ((hooktype == HOOKTYPE_WELCOME) && !ValidateHook(hooktype_welcome, func)) || \
   2413         ((hooktype == HOOKTYPE_PRE_COMMAND) && !ValidateHook(hooktype_pre_command, func)) || \
   2414         ((hooktype == HOOKTYPE_POST_COMMAND) && !ValidateHook(hooktype_post_command, func)) || \
   2415         ((hooktype == HOOKTYPE_NEW_MESSAGE) && !ValidateHook(hooktype_new_message, func)) || \
   2416         ((hooktype == HOOKTYPE_IS_HANDSHAKE_FINISHED) && !ValidateHook(hooktype_is_handshake_finished, func)) || \
   2417         ((hooktype == HOOKTYPE_PRE_LOCAL_QUIT_CHAN) && !ValidateHook(hooktype_pre_local_quit_chan, func)) || \
   2418         ((hooktype == HOOKTYPE_IDENT_LOOKUP) && !ValidateHook(hooktype_ident_lookup, func)) || \
   2419         ((hooktype == HOOKTYPE_CONFIGRUN_EX) && !ValidateHook(hooktype_configrun_ex, func)) || \
   2420         ((hooktype == HOOKTYPE_ACCOUNT_LOGIN) && !ValidateHook(hooktype_account_login, func)) || \
   2421         ((hooktype == HOOKTYPE_CLOSE_CONNECTION) && !ValidateHook(hooktype_close_connection, func)) || \
   2422         ((hooktype == HOOKTYPE_CONNECT_EXTINFO) && !ValidateHook(hooktype_connect_extinfo, func)) || \
   2423         ((hooktype == HOOKTYPE_IS_INVITED) && !ValidateHook(hooktype_is_invited, func)) || \
   2424         ((hooktype == HOOKTYPE_POST_LOCAL_NICKCHANGE) && !ValidateHook(hooktype_post_local_nickchange, func)) || \
   2425         ((hooktype == HOOKTYPE_POST_REMOTE_NICKCHANGE) && !ValidateHook(hooktype_post_remote_nickchange, func)) || \
   2426         ((hooktype == HOOKTYPE_USERHOST_CHANGE) && !ValidateHook(hooktype_userhost_change, func)) || \
   2427         ((hooktype == HOOKTYPE_REALNAME_CHANGE) && !ValidateHook(hooktype_realname_change, func)) || \
   2428         ((hooktype == HOOKTYPE_IP_CHANGE) && !ValidateHook(hooktype_ip_change, func)) || \
   2429         ((hooktype == HOOKTYPE_JSON_EXPAND_CLIENT) && !ValidateHook(hooktype_json_expand_client, func)) || \
   2430         ((hooktype == HOOKTYPE_JSON_EXPAND_CLIENT_USER) && !ValidateHook(hooktype_json_expand_client_user, func)) || \
   2431         ((hooktype == HOOKTYPE_JSON_EXPAND_CLIENT_SERVER) && !ValidateHook(hooktype_json_expand_client_server, func)) || \
   2432         ((hooktype == HOOKTYPE_JSON_EXPAND_CHANNEL) && !ValidateHook(hooktype_json_expand_channel, func)) || \
   2433         ((hooktype == HOOKTYPE_PRE_LOCAL_HANDSHAKE_TIMEOUT) && !ValidateHook(hooktype_pre_local_handshake_timeout, func)) || \
   2434         ((hooktype == HOOKTYPE_REHASH_LOG) && !ValidateHook(hooktype_rehash_log, func)) ) \
   2435         _hook_error_incompatible();
   2436 #endif /* GCC_TYPECHECKING */
   2437 
   2438 /* Hook return values */
   2439 #define HOOK_CONTINUE 0
   2440 #define HOOK_ALLOW -1
   2441 #define HOOK_DENY 1
   2442 
   2443 /* Callback types */
   2444 #define CALLBACKTYPE_CLOAK 1
   2445 #define CALLBACKTYPE_CLOAK_KEY_CHECKSUM 2
   2446 #define CALLBACKTYPE_CLOAK_EX 3
   2447 #define CALLBACKTYPE_BLACKLIST_CHECK 4
   2448 #define CALLBACKTYPE_REPUTATION_STARTTIME 5
   2449 #define CALLBACKTYPE_GEOIP_LOOKUP 6
   2450 
   2451 /* To add a new efunction, only if you are an UnrealIRCd coder:
   2452  * 1) Add a new entry here
   2453  * 2) Add the function in src/api-efunctions.c
   2454  * 3) Add the initalization in src/api-efunctions.c
   2455  * 4) Add the extern entry in include/h.h in the
   2456  *    section marked "Efuncs"
   2457  */
   2458 /** Efunction types. */
   2459 enum EfunctionType {
   2460 	EFUNC_DO_JOIN=1,
   2461 	EFUNC_JOIN_CHANNEL,
   2462 	EFUNC_CAN_JOIN,
   2463 	EFUNC_DO_MODE,
   2464 	EFUNC_SET_MODE,
   2465 	EFUNC_SET_CHANNEL_MODE,
   2466 	EFUNC_SET_CHANNEL_TOPIC,
   2467 	EFUNC_CMD_UMODE,
   2468 	EFUNC_REGISTER_USER,
   2469 	EFUNC_TKL_HASH,
   2470 	EFUNC_TKL_TYPETOCHAR,
   2471 	EFUNC_TKL_ADD_SERVERBAN,
   2472 	EFUNC_TKL_DEL_LINE,
   2473 	EFUNC_TKL_CHECK_LOCAL_REMOVE_SHUN,
   2474 	EFUNC_TKL_EXPIRE,
   2475 	EFUNC_TKL_CHECK_EXPIRE,
   2476 	EFUNC_FIND_TKLINE_MATCH,
   2477 	EFUNC_FIND_SHUN,
   2478 	EFUNC_FIND_SPAMFILTER_USER,
   2479 	EFUNC_FIND_QLINE,
   2480 	EFUNC_FIND_TKLINE_MATCH_ZAP,
   2481 	EFUNC_TKL_STATS,
   2482 	EFUNC_TKL_SYNCH,
   2483 	EFUNC_CMD_TKL,
   2484 	EFUNC_PLACE_HOST_BAN,
   2485 	EFUNC_MATCH_SPAMFILTER,
   2486 	EFUNC_MATCH_SPAMFILTER_MTAGS,
   2487 	EFUNC_JOIN_VIRUSCHAN,
   2488 	EFUNC_FIND_TKLINE_MATCH_ZAP_EX,
   2489 	EFUNC_SEND_LIST,
   2490 	EFUNC_STRIPCOLORS,
   2491 	EFUNC_SPAMFILTER_BUILD_USER_STRING,
   2492 	EFUNC_SEND_PROTOCTL_SERVERS,
   2493 	EFUNC_VERIFY_LINK,
   2494 	EFUNC_SEND_SERVER_MESSAGE,
   2495 	EFUNC_BROADCAST_MD_CLIENT,
   2496 	EFUNC_BROADCAST_MD_CHANNEL,
   2497 	EFUNC_BROADCAST_MD_MEMBER,
   2498 	EFUNC_BROADCAST_MD_MEMBERSHIP,
   2499 	EFUNC_INTRODUCE_USER,
   2500 	EFUNC_CHECK_DENY_VERSION,
   2501 	EFUNC_BROADCAST_MD_CLIENT_CMD,
   2502 	EFUNC_BROADCAST_MD_CHANNEL_CMD,
   2503 	EFUNC_BROADCAST_MD_MEMBER_CMD,
   2504 	EFUNC_BROADCAST_MD_MEMBERSHIP_CMD,
   2505 	EFUNC_MODDATA_ADD_S2S_MTAGS,
   2506 	EFUNC_MODDATA_EXTRACT_S2S_MTAGS,
   2507 	EFUNC_SEND_MODDATA_CLIENT,
   2508 	EFUNC_SEND_MODDATA_CHANNEL,
   2509 	EFUNC_SEND_MODDATA_MEMBERS,
   2510 	EFUNC_BROADCAST_MODDATA_CLIENT,
   2511 	EFUNC_MATCH_USER,
   2512 	EFUNC_USERHOST_SAVE_CURRENT,
   2513 	EFUNC_USERHOST_CHANGED,
   2514 	EFUNC_SEND_JOIN_TO_LOCAL_USERS,
   2515 	EFUNC_DO_NICK_NAME,
   2516 	EFUNC_DO_REMOTE_NICK_NAME,
   2517 	EFUNC_CHARSYS_GET_CURRENT_LANGUAGES,
   2518 	EFUNC_BROADCAST_SINFO,
   2519 	EFUNC_CONNECT_SERVER,
   2520 	EFUNC_IS_SERVICES_BUT_NOT_ULINED,
   2521 	EFUNC_PARSE_MESSAGE_TAGS,
   2522 	EFUNC_MTAGS_TO_STRING,
   2523 	EFUNC_TKL_CHARTOTYPE,
   2524 	EFUNC_TKL_CONFIGTYPETOCHAR,
   2525 	EFUNC_TKL_TYPE_STRING,
   2526 	EFUNC_TKL_TYPE_CONFIG_STRING,
   2527 	EFUNC_CAN_SEND_TO_CHANNEL,
   2528 	EFUNC_CAN_SEND_TO_USER,
   2529 	EFUNC_BROADCAST_MD_GLOBALVAR,
   2530 	EFUNC_BROADCAST_MD_GLOBALVAR_CMD,
   2531 	EFUNC_TKL_IP_HASH,
   2532 	EFUNC_TKL_IP_HASH_TYPE,
   2533 	EFUNC_TKL_ADD_BANEXCEPTION,
   2534 	EFUNC_TKL_ADD_NAMEBAN,
   2535 	EFUNC_TKL_ADD_SPAMFILTER,
   2536 	EFUNC_SENDNOTICE_TKL_ADD,
   2537 	EFUNC_SENDNOTICE_TKL_DEL,
   2538 	EFUNC_FREE_TKL,
   2539 	EFUNC_FIND_TKL_SERVERBAN,
   2540 	EFUNC_FIND_TKL_BANEXCEPTION,
   2541 	EFUNC_FIND_TKL_NAMEBAN,
   2542 	EFUNC_FIND_TKL_SPAMFILTER,
   2543 	EFUNC_FIND_TKL_EXCEPTION,
   2544 	EFUNC_SERVER_BAN_PARSE_MASK,
   2545 	EFUNC_SERVER_BAN_EXCEPTION_PARSE_MASK,
   2546 	EFUNC_TKL_ADDED,
   2547 	EFUNC_ADD_SILENCE,
   2548 	EFUNC_DEL_SILENCE,
   2549 	EFUNC_IS_SILENCED,
   2550 	EFUNC_LABELED_RESPONSE_SAVE_CONTEXT,
   2551 	EFUNC_LABELED_RESPONSE_SET_CONTEXT,
   2552 	EFUNC_LABELED_RESPONSE_FORCE_END,
   2553 	EFUNC_KICK_USER,
   2554 	EFUNC_WATCH_ADD,
   2555 	EFUNC_WATCH_DEL,
   2556 	EFUNC_WATCH_DEL_LIST,
   2557 	EFUNC_WATCH_GET,
   2558 	EFUNC_WATCH_CHECK,
   2559 	EFUNC_TKL_UHOST,
   2560 	EFUNC_DO_UNREAL_LOG_REMOTE_DELIVER,
   2561 	EFUNC_GET_CHMODES_FOR_USER,
   2562 	EFUNC_WHOIS_GET_POLICY,
   2563 	EFUNC_MAKE_OPER,
   2564 	EFUNC_UNREAL_MATCH_IPLIST,
   2565 	EFUNC_WEBSERVER_SEND_RESPONSE,
   2566 	EFUNC_WEBSERVER_CLOSE_CLIENT,
   2567 	EFUNC_WEBSERVER_HANDLE_BODY,
   2568 	EFUNC_RPC_RESPONSE,
   2569 	EFUNC_RPC_ERROR,
   2570 	EFUNC_RPC_ERROR_FMT,
   2571 	EFUNC_RPC_SEND_REQUEST_TO_REMOTE,
   2572 	EFUNC_RPC_SEND_RESPONSE_TO_REMOTE,
   2573 	EFUNC_RRPC_SUPPORTED,
   2574 	EFUNC_RRPC_SUPPORTED_SIMPLE,
   2575 	EFUNC_WEBSOCKET_HANDLE_WEBSOCKET,
   2576 	EFUNC_WEBSOCKET_CREATE_PACKET,
   2577 	EFUNC_WEBSOCKET_CREATE_PACKET_EX,
   2578 	EFUNC_WEBSOCKET_CREATE_PACKET_SIMPLE,
   2579 	EFUNC_CHECK_DENY_LINK,
   2580 	EFUNC_MTAG_GENERATE_ISSUED_BY_IRC,
   2581 };
   2582 
   2583 /* Module flags */
   2584 #define MODFLAG_NONE	0x0000
   2585 #define MODFLAG_LOADED	0x0001 /* Fully loaded */
   2586 #define MODFLAG_TESTING 0x0002 /* Not yet initialized */
   2587 #define MODFLAG_INIT	0x0004 /* Initialized */
   2588 #define MODFLAG_DELAYED 0x0008 /* Delayed unload */
   2589 
   2590 /* Module function return values */
   2591 #define MOD_SUCCESS 0
   2592 #define MOD_FAILED -1
   2593 #define MOD_DELAY 2
   2594 
   2595 #define CONFIG_MAIN 1
   2596 #define CONFIG_SET 2
   2597 #define CONFIG_BAN 3
   2598 #define CONFIG_EXCEPT 4
   2599 #define CONFIG_DENY 5
   2600 #define CONFIG_ALLOW 6
   2601 #define CONFIG_CLOAKKEYS 7
   2602 #define CONFIG_SET_ANTI_FLOOD 8
   2603 #define CONFIG_REQUIRE 9
   2604 #define CONFIG_LISTEN 10
   2605 #define CONFIG_LISTEN_OPTIONS 11
   2606 #define CONFIG_SET_HISTORY_CHANNEL 12
   2607 
   2608 #define MOD_HEADER Mod_Header
   2609 #define MOD_TEST() DLLFUNC int Mod_Test(ModuleInfo *modinfo)
   2610 #define MOD_INIT() DLLFUNC int Mod_Init(ModuleInfo *modinfo)
   2611 #define MOD_LOAD() DLLFUNC int Mod_Load(ModuleInfo *modinfo)
   2612 #define MOD_UNLOAD() DLLFUNC int Mod_Unload(ModuleInfo *modinfo)
   2613 
   2614 #define CLOAK_KEY_CHECKSUM	RCallbacks[CALLBACKTYPE_CLOAK_KEY_CHECKSUM] != NULL ? RCallbacks[CALLBACKTYPE_CLOAK_KEY_CHECKSUM]->func.stringfunc() : "nil"
   2615 
   2616 #ifdef DYNAMIC_LINKING
   2617  #include "modversion.h"
   2618 #endif
   2619 
   2620 #endif
   2621