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