diff --git a/doc/example.conf b/doc/example.conf index 7d881228..3544b09f 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -889,33 +889,35 @@ features # "MAXBANS"="30"; # "MAXSILES"="15"; # "HANGONGOODLINK"="300"; -# "HANGONRETRYDELAY" = "10"; -# "CONNECTTIMEOUT" = "90"; -# "PINGFREQUENCY" = "120"; -# "CONNECTFREQUENCY" = "600"; -# "DEFAULTMAXSENDQLENGTH" = "40000"; -# "GLINEMAXUSERCOUNT" = "20"; -# "MPATH" = "ircd.motd"; -# "RPATH" = "remote.motd"; -# "PPATH" = "ircd.pid"; -# "TOS_SERVER" = "0x08"; -# "TOS_CLIENT" = "0x08"; -# "POLLS_PER_LOOP" = "200"; -# "IRCD_RES_TIMEOUT" = "4"; -# "IRCD_RES_RETRIES" = "2"; -# "AUTH_TIMEOUT" = "9"; -# "IPCHECK_CLONE_LIMIT" = "4"; -# "IPCHECK_CLONE_PERIOD" = "40"; -# "IPCHECK_CLONE_DELAY" = "600"; -# "CHANNELLEN" = "200"; -# "CONFIG_OPERCMDS" = "FALSE"; -# "OPLEVELS" = "FALSE"; -# "ZANNELS" = "FALSE"; -# "LOCAL_CHANNELS" = "TRUE"; -# "STRICT_USERNAME" = "FALSE"; -# "TOPIC_BURST" = "TRUE" -# "AWAY_BURST" = "TRUE"; -# "ANNOUNCE_INVITES" = "FALSE"; +# "HANGONRETRYDELAY" = "10"; +# "CONNECTTIMEOUT" = "90"; +# "PINGFREQUENCY" = "120"; +# "CONNECTFREQUENCY" = "600"; +# "DEFAULTMAXSENDQLENGTH" = "40000"; +# "GLINEMAXUSERCOUNT" = "20"; +# "DISABLE_GLINES" = "FALSE"; +# "DISABLE_SLINES" = "FALSE"; +# "MPATH" = "ircd.motd"; +# "RPATH" = "remote.motd"; +# "PPATH" = "ircd.pid"; +# "TOS_SERVER" = "0x08"; +# "TOS_CLIENT" = "0x08"; +# "POLLS_PER_LOOP" = "200"; +# "IRCD_RES_TIMEOUT" = "4"; +# "IRCD_RES_RETRIES" = "2"; +# "AUTH_TIMEOUT" = "9"; +# "IPCHECK_CLONE_LIMIT" = "4"; +# "IPCHECK_CLONE_PERIOD" = "40"; +# "IPCHECK_CLONE_DELAY" = "600"; +# "CHANNELLEN" = "200"; +# "CONFIG_OPERCMDS" = "FALSE"; +# "OPLEVELS" = "FALSE"; +# "ZANNELS" = "FALSE"; +# "LOCAL_CHANNELS" = "TRUE"; +# "STRICT_USERNAME" = "FALSE"; +# "TOPIC_BURST" = "TRUE" +# "AWAY_BURST" = "TRUE"; +# "ANNOUNCE_INVITES" = "FALSE"; # "CAP_ACCOUNTNOTIFY" = "TRUE"; # "CAP_AWAYNOTIFY" = "TRUE"; # "CAP_CHGHOST" = "TRUE"; @@ -933,6 +935,7 @@ features # "HIS_TRACE" = "TRUE"; # "HIS_STATS_a" = "TRUE"; # "HIS_STATS_c" = "TRUE"; +# "HIS_STATS_C" = "TRUE"; # "HIS_STATS_d" = "TRUE"; # "HIS_STATS_e" = "TRUE"; # "HIS_STATS_f" = "TRUE"; @@ -950,6 +953,7 @@ features # "HIS_STATS_q" = "TRUE"; # "HIS_STATS_r" = "TRUE"; # "HIS_STATS_R" = "TRUE"; +# "HIS_STATS_s" = "TRUE"; # "HIS_STATS_t" = "TRUE"; # "HIS_STATS_T" = "TRUE"; # "HIS_STATS_u" = "FALSE"; diff --git a/include/client.h b/include/client.h index 92e4816c..7297b314 100644 --- a/include/client.h +++ b/include/client.h @@ -169,6 +169,7 @@ enum Flag FLAG_DEBUG, /**< send global debug/anti-hack info */ FLAG_ACCOUNT, /**< account name has been set */ FLAG_HIDDENHOST, /**< user's host is hidden */ + FLAG_SPAMHOLD, /**< user is the sender or recipient of a message on hold */ FLAG_LAST_FLAG, /**< number of flags */ FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */ FLAG_GLOBAL_UMODES = FLAG_OPER /**< First global mode flag */ @@ -602,6 +603,8 @@ struct Client { #define IsHiddenHost(x) HasFlag(x, FLAG_HIDDENHOST) /** Return non-zero if the client has an active PING request. */ #define IsPingSent(x) HasFlag(x, FLAG_PINGSENT) +/** Return non-zero if the client is the sender or recipient of a message on hold (spamfilter) */ +#define IsSpamHold(x) HasFlag(x, FLAG_SPAMHOLD) /** Return non-zero if the client has operator or server privileges. */ #define IsPrivileged(x) (IsAnOper(x) || IsServer(x)) @@ -648,6 +651,8 @@ struct Client { #define SetHiddenHost(x) SetFlag(x, FLAG_HIDDENHOST) /** Mark a client as having a pending PING. */ #define SetPingSent(x) SetFlag(x, FLAG_PINGSENT) +/** Mark a client as being the sender or recipient of a message on hold (spamfilter). */ +#define SetSpamHold(x) SetFlag(x, FLAG_SPAMHOLD) /** Return non-zero if \a sptr sees \a acptr as an operator. */ #define SeeOper(sptr,acptr) (IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) \ @@ -683,6 +688,8 @@ struct Client { #define ClearPingSent(x) ClrFlag(x, FLAG_PINGSENT) /** Clear the client's HUB flag. */ #define ClearHub(x) ClrFlag(x, FLAG_HUB) +/** Clear the client's spam hold flag. */ +#define ClearSpamHold(x) ClrFlag(x, FLAG_SPAMHOLD) /* free flags */ #define FREEFLAG_SOCKET 0x0001 /**< socket needs to be freed */ diff --git a/include/handlers.h b/include/handlers.h index f8bc6073..5bdfb59e 100644 --- a/include/handlers.h +++ b/include/handlers.h @@ -89,6 +89,7 @@ struct Client; extern int m_admin(struct Client*, struct Client*, int, char*[]); extern int m_away(struct Client*, struct Client*, int, char*[]); extern int m_cap(struct Client*, struct Client*, int, char*[]); +extern int ms_config(struct Client*, struct Client*, int, char*[]); extern int m_cnotice(struct Client*, struct Client*, int, char*[]); extern int m_cprivmsg(struct Client*, struct Client*, int, char*[]); extern int m_gline(struct Client*, struct Client*, int, char*[]); @@ -215,6 +216,7 @@ extern int ms_rpong(struct Client*, struct Client*, int, char*[]); extern int ms_server(struct Client*, struct Client*, int, char*[]); extern int ms_settime(struct Client*, struct Client*, int, char*[]); extern int ms_silence(struct Client*, struct Client*, int, char*[]); +extern int ms_sline(struct Client*, struct Client*, int, char*[]); extern int ms_squit(struct Client*, struct Client*, int, char*[]); extern int ms_stats(struct Client*, struct Client*, int, char*[]); extern int ms_topic(struct Client*, struct Client*, int, char*[]); diff --git a/include/ircd_defs.h b/include/ircd_defs.h index c3138233..c897cc13 100644 --- a/include/ircd_defs.h +++ b/include/ircd_defs.h @@ -86,7 +86,10 @@ #define TOPICLEN 160 /** Maximum length for away messages. */ -#define AWAYLEN 160 +#define AWAYLEN 160 +/** Maximum length of S:line patterns. +*/ +#define SLINELEN 470 /** Exactly long enough to hold one protocol message (RFC 1459) * including the line termination (\\r\\n). DO NOT CHANGE THIS!!!! */ diff --git a/include/ircd_features.h b/include/ircd_features.h index 10167947..938ac5ed 100644 --- a/include/ircd_features.h +++ b/include/ircd_features.h @@ -61,6 +61,7 @@ enum Feature { FEAT_TOPIC_BURST, FEAT_AWAY_BURST, FEAT_DISABLE_GLINES, + FEAT_DISABLE_SLINES, FEAT_JOIN_TARGET, /* features that probably should not be touched */ @@ -122,6 +123,7 @@ enum Feature { FEAT_HIS_TRACE, FEAT_HIS_STATS_a, FEAT_HIS_STATS_c, + FEAT_HIS_STATS_C, FEAT_HIS_STATS_d, FEAT_HIS_STATS_e, FEAT_HIS_STATS_f, @@ -132,13 +134,14 @@ enum Feature { FEAT_HIS_STATS_k, FEAT_HIS_STATS_l, FEAT_HIS_STATS_L, - FEAT_HIS_STATS_M, FEAT_HIS_STATS_m, + FEAT_HIS_STATS_M, FEAT_HIS_STATS_o, FEAT_HIS_STATS_p, FEAT_HIS_STATS_q, - FEAT_HIS_STATS_R, FEAT_HIS_STATS_r, + FEAT_HIS_STATS_R, + FEAT_HIS_STATS_s, FEAT_HIS_STATS_t, FEAT_HIS_STATS_T, FEAT_HIS_STATS_u, diff --git a/include/ircd_netconf.h b/include/ircd_netconf.h new file mode 100644 index 00000000..6eacc76a --- /dev/null +++ b/include/ircd_netconf.h @@ -0,0 +1,80 @@ +/* + * IRC - Internet Relay Chat, include/ircd_netconf.h + * Copyright (C) 2025 MrIron + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef INCLUDED_ircd_netconf_h +#define INCLUDED_ircd_netconf_h + +#include + +struct Client; +struct StatDesc; + +/** Configuration set return values */ +#define CONFIG_REJECTED -1 /**< Rejected - older timestamp */ +#define CONFIG_CREATED 0 /**< New entry created */ +#define CONFIG_TIMESTAMP 1 /**< Timestamp updated, same value */ +#define CONFIG_CHANGED 2 /**< Value actually changed */ + +/** Configuration entry structure */ +struct ConfigEntry { + char *key; /**< Configuration option key */ + char *value; /**< Configuration option value */ + time_t timestamp; /**< Timestamp when this config was set */ + struct ConfigEntry *next; /**< Next configuration entry */ +}; + +/** Configuration change callback function type */ +typedef void (*config_callback_f)(const char *key, const char *old_value, const char *new_value); + +/** Configuration callback structure */ +struct ConfigCallback { + char *key_prefix; /**< Key prefix to match (e.g., "sasl.") */ + config_callback_f callback; /**< Callback function */ + struct ConfigCallback *next; /**< Next callback */ +}; + +/** Network configuration options */ +enum NetConf { + /* S:line related settings */ + NETCONF_SLINE_SERVER, + NETCONF_SLINE_HOLD_TIMEOUT, + NETCONF_SLINE_HOLD_TIMEOUT_BLOCK, + + /* Add more as needed */ + NETCONF_LAST_NC +}; + +/* + * Prototypes + */ + +extern int config_set(const char *key, const char *value, time_t timestamp); +extern const char *config_get(const char *key); +extern void config_register_callback(const char *key_prefix, config_callback_f callback); +extern void config_unregister_callback(const char *key_prefix); +extern void config_burst(struct Client *cptr); +extern void config_stats(struct Client *sptr, const struct StatDesc *sd, char *param); +extern int netconf_int(enum NetConf key); +extern int netconf_bool(enum NetConf key); +extern const char *netconf_str(enum NetConf key); + +#endif /* INCLUDED_ircd_netconf_h */ diff --git a/include/msg.h b/include/msg.h index 2fba1e79..0475da80 100644 --- a/include/msg.h +++ b/include/msg.h @@ -292,6 +292,10 @@ struct Client; #define TOK_GLINE "GL" #define CMD_GLINE MSG_GLINE, TOK_GLINE +#define MSG_SLINE "SLINE" /* SLIN */ +#define TOK_SLINE "SL" +#define CMD_SLINE MSG_SLINE, TOK_SLINE + #define MSG_BURST "BURST" /* BURS */ #define TOK_BURST "B" #define CMD_BURST MSG_BURST, TOK_BURST @@ -376,6 +380,10 @@ struct Client; #define TOK_CHGHOST "CHGHOST" #define CMD_CHGHOST MSG_CHGHOST, TOK_CHGHOST +#define MSG_CONFIG "CONFIG" +#define TOK_CONFIG "CF" +#define CMD_CONFIG MSG_CONFIG, TOK_CONFIG + /* * Constants */ diff --git a/include/numeric.h b/include/numeric.h index 7da37e91..71a15379 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -130,7 +130,7 @@ extern const struct Numeric* get_error_numeric(int err); #define RPL_STATSENGINE 237 /* Undernet engine name */ #define RPL_STATSFLINE 238 /* Undernet feature lines */ /* RPL_STATSIAUTH 239 IRCnet extension */ -/* RPL_STATSVLINE 240 IRCnet extension */ +#define RPL_STATSSLINE 240 /* Undernet extension */ /* RPL_STATSXLINE 240 austnet */ #define RPL_STATSLLINE 241 /* Undernet dynamicly loaded modules */ #define RPL_STATSUPTIME 242 diff --git a/include/sline.h b/include/sline.h new file mode 100644 index 00000000..495d2747 --- /dev/null +++ b/include/sline.h @@ -0,0 +1,97 @@ +#ifndef INCLUDED_sline_h +#define INCLUDED_sline_h +/* + * IRC - Internet Relay Chat, include/sline.h + * Copyright (C) 2025 MrIron + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef INCLUDED_sys_types_h +#include +#define INCLUDED_sys_types_h +#endif + +#include +#include + +struct Client; +struct StatDesc; +struct Channel; + +/** Forward declaration for hold queue entry */ +struct HoldQueueEntry; + +/* Regex capture group limits */ +#define SLINE_MAX_CAPTURES 16 /**< Maximum regex capture groups supported (including full match). + If an S-line regex pattern contains more than 15 capture groups, + only the first 15 will be captured and passed to spam filters. */ + +/* Message type flags */ +#define SLINE_PRIVATE 0x0001 /**< Match private messages. */ +#define SLINE_CHANNEL 0x0002 /**< Match channel messages. */ +#define SLINE_PART 0x0004 /**< Match partial messages. */ +#define SLINE_QUIT 0x0008 /**< Match quit messages. */ + +#define SLINE_ALL (SLINE_PRIVATE | SLINE_CHANNEL | SLINE_PART | SLINE_QUIT) + +/** S:line flags */ +#define SLINE_ACTIVE 0x0001 /**< S-line is active. */ +#define SLINE_INVALID 0x0002 /**< S-line regex failed to compile. */ + +/* Flags to track update actions. */ +#define SLINE_EXPIRE 0x0004 /**< S-line expire update. */ +#define SLINE_MSGTYPE 0x0008 /**< S-line message type update. */ +#define SLINE_STATE 0x0010 /**< S-line state update. */ + +/** Value to hold a set of message type bits. */ +typedef unsigned short sl_msgtype_t; + +/** Value to hold a set of S-line state bits. */ +typedef unsigned short sl_flagtype_t; + +/** Description of an S-line. */ +struct Sline { + struct Sline *sl_next; /**< Next S-line in linked list. */ + struct Sline **sl_prev_p; /**< Previous pointer to this S-line. */ + char *sl_pattern; /**< Regex pattern to match against messages. */ + time_t sl_lastmod; /**< When the S-line was last modified. */ + time_t sl_expire; /**< When the S-line will expire. */ + sl_msgtype_t sl_msgtype; /**< Message type to match against. */ + sl_flagtype_t sl_flags; /**< S-line status flags. */ + uint64_t sl_count; /**< Number of times this S-line has matched. */ + regex_t sl_regex; /**< Precompiled regex for this pattern. */ +}; + +extern int sline_add(struct Client *cptr, struct Client *sptr, char *pattern, + time_t lastmod, time_t expire, sl_msgtype_t msgtype, sl_flagtype_t flags); +extern void sline_modify(struct Client *sptr, struct Sline *sline, time_t lastmod, + time_t expire, sl_msgtype_t msgtype, sl_flagtype_t flags, unsigned int updates); + +extern struct Sline *sline_find(char *pattern); +extern void sline_stats(struct Client *sptr, const struct StatDesc *sd, + char *param); +extern void sline_send_meminfo(struct Client* sptr); +extern void sline_burst(struct Client *cptr); +extern int sline_check_pattern_bool(const char *text, sl_msgtype_t msg_type); +extern int sline_check_privmsg(struct Client *sender, struct Client *recipient, const char *text, const char* cmd_type); +extern int sline_check_chanmsg(struct Client *sender, struct Channel *channel, const char *text, const char* cmd_type); +extern void sline_cleanup_client(struct Client *cptr); +extern void sline_cleanup_channel(struct Channel *chptr); +extern int sline_xreply_handler(struct Client *sptr, const char *token, const char *reply); +extern void sline_init(void); +extern const char *sline_flags_to_string(sl_msgtype_t msgtype); + +#endif /* INCLUDED_sline_h */ diff --git a/ircd/Makefile.in b/ircd/Makefile.in index 432c66e2..a01a5bef 100644 --- a/ircd/Makefile.in +++ b/ircd/Makefile.in @@ -102,6 +102,7 @@ IRCD_SRC = \ ircd_features.c \ ircd_lexer.c \ ircd_log.c \ + ircd_netconf.c \ ircd_relay.c \ ircd_reply.c \ ircd_res.c \ @@ -120,6 +121,7 @@ IRCD_SRC = \ m_cap.c \ m_clearmode.c \ m_close.c \ + m_config.c \ m_connect.c \ m_cprivmsg.c \ m_create.c \ @@ -168,6 +170,7 @@ IRCD_SRC = \ m_set.c \ m_settime.c \ m_silence.c \ + m_sline.c \ m_squit.c \ m_stats.c \ m_time.c \ @@ -210,6 +213,7 @@ IRCD_SRC = \ s_stats.c \ s_user.c \ send.c \ + sline.c \ uping.c \ userload.c \ whocmds.c \ @@ -354,85 +358,93 @@ IPcheck.o: IPcheck.c ../config.h ../include/IPcheck.h \ ../include/channel.h ../include/ircd_defs.h ../include/res.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ - ../include/ircd.h ../include/struct.h ../include/match.h \ - ../include/msg.h ../include/ircd_alloc.h ../include/ircd_events.h \ - ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/res.h \ - ../include/s_debug.h ../include/s_user.h ../include/send.h + ../include/ircd_features.h ../include/ircd.h ../include/struct.h \ + ../include/match.h ../include/msg.h ../include/ircd_alloc.h \ + ../include/ircd_events.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_string.h ../include/ircd_chattr.h \ + ../include/res.h ../include/s_debug.h ../include/s_user.h \ + ../include/send.h channel.o: channel.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/destruct_event.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_chattr.h ../include/ircd_defs.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \ - ../include/match.h ../include/msg.h ../include/msgq.h \ - ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ - ../include/ircd_features.h ../include/s_bsd.h ../include/s_conf.h \ - ../include/client.h ../include/s_debug.h ../include/s_misc.h \ - ../include/s_user.h ../include/send.h ../include/struct.h \ - ../include/sys.h ../include/whowas.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/destruct_event.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \ + ../include/ircd_defs.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/ircd_string.h ../include/list.h ../include/match.h \ + ../include/msg.h ../include/msgq.h ../include/numeric.h \ + ../include/numnicks.h ../include/querycmds.h ../include/s_bsd.h \ + ../include/s_conf.h ../include/client.h ../include/s_debug.h \ + ../include/s_misc.h ../include/s_user.h ../include/send.h \ + ../include/sline.h ../include/struct.h ../include/sys.h \ + ../include/whowas.h class.o: class.c ../config.h ../include/class.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/client.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/list.h ../include/numeric.h \ - ../include/s_conf.h ../include/s_debug.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/client.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ + ../include/numeric.h ../include/s_conf.h ../include/s_debug.h \ + ../include/send.h client.o: client.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/class.h ../include/client.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/list.h ../include/msgq.h \ - ../include/numeric.h ../include/s_conf.h ../include/s_debug.h \ - ../include/send.h ../include/struct.h + ../include/ircd_features.h ../include/class.h ../include/client.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/list.h \ + ../include/msgq.h ../include/numeric.h ../include/s_conf.h \ + ../include/s_debug.h ../include/send.h ../include/struct.h crule.o: crule.c ../config.h ../include/crule.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_chattr.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \ ../include/ircd_string.h ../include/match.h ../include/s_bsd.h \ ../include/s_debug.h ../include/struct.h dbuf.o: dbuf.c ../config.h ../include/dbuf.h ../include/ircd_alloc.h \ ../include/ircd_chattr.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/send.h ../include/sys.h + ../include/ircd_log.h ../include/send.h ../include/client.h \ + ../include/ircd_defs.h ../include/msgq.h ../include/ircd_events.h \ + ../include/ircd_handler.h ../include/res.h ../include/capab.h \ + ../include/ircd_features.h ../include/sys.h destruct_event.o: destruct_event.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/s_debug.h \ ../include/ircd_alloc.h ../include/ircd.h ../include/struct.h \ ../include/ircd_events.h ../include/ircd_log.h ../include/send.h \ - ../include/msg.h ../include/ircd_handler.h + ../include/client.h ../include/dbuf.h ../include/msgq.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/msg.h fileio.o: fileio.c ../config.h ../include/fileio.h \ ../include/ircd_alloc.h ../include/ircd_log.h gline.o: gline.c ../config.h ../include/gline.h ../include/res.h \ ../include/channel.h ../include/ircd_defs.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_snprintf.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ - ../include/numeric.h ../include/s_bsd.h ../include/s_debug.h \ - ../include/s_misc.h ../include/s_stats.h ../include/send.h \ - ../include/struct.h ../include/sys.h ../include/msg.h \ - ../include/numnicks.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_snprintf.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/match.h ../include/numeric.h \ + ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \ + ../include/s_stats.h ../include/send.h ../include/struct.h \ + ../include/sys.h ../include/msg.h ../include/numnicks.h hash.o: hash.c ../config.h ../include/hash.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/channel.h ../include/ircd_alloc.h \ - ../include/ircd_chattr.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd.h ../include/struct.h \ - ../include/match.h ../include/msg.h ../include/numeric.h \ - ../include/random.h ../include/send.h ../include/struct.h \ - ../include/sys.h + ../include/capab.h ../include/ircd_features.h ../include/channel.h \ + ../include/ircd_alloc.h ../include/ircd_chattr.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h ../include/ircd.h \ + ../include/struct.h ../include/match.h ../include/msg.h \ + ../include/numeric.h ../include/random.h ../include/send.h \ + ../include/struct.h ../include/sys.h ircd.o: ircd.c ../config.h ../include/ircd.h ../include/struct.h \ ../include/ircd_defs.h ../include/IPcheck.h ../include/class.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/client.h ../include/crule.h \ - ../include/destruct_event.h ../include/channel.h ../include/hash.h \ - ../include/ircd_alloc.h ../include/ircd_events.h \ + ../include/capab.h ../include/ircd_features.h ../include/client.h \ + ../include/crule.h ../include/destruct_event.h ../include/channel.h \ + ../include/hash.h ../include/ircd_alloc.h ../include/ircd_events.h \ ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ ../include/ircd_signal.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/ircd_crypt.h ../include/jupe.h \ @@ -441,8 +453,8 @@ ircd.o: ircd.c ../config.h ../include/ircd.h ../include/struct.h \ ../include/parse.h ../include/res.h ../include/s_auth.h \ ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \ ../include/s_misc.h ../include/s_stats.h ../include/send.h \ - ../include/sys.h ../include/uping.h ../include/userload.h \ - ../include/version.h ../include/whowas.h + ../include/sline.h ../include/sys.h ../include/uping.h \ + ../include/userload.h ../include/version.h ../include/whowas.h ircd_alloc.o: ircd_alloc.c ../config.h ../include/ircd_alloc.h \ ../include/ircd_log.h ../include/ircd_string.h ../include/ircd_chattr.h \ ../include/s_debug.h ../include/ircd_defs.h @@ -459,56 +471,66 @@ ircd_features.o: ircd_features.c ../config.h ../include/ircd_features.h \ ../include/channel.h ../include/ircd_defs.h ../include/res.h \ ../include/class.h ../include/client.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ - ../include/capab.h ../include/client.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/motd.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/random.h ../include/s_bsd.h ../include/s_debug.h \ - ../include/s_misc.h ../include/s_stats.h ../include/send.h \ - ../include/struct.h ../include/sys.h ../include/whowas.h + ../include/capab.h ../include/ircd_features.h ../include/client.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/motd.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/random.h ../include/s_bsd.h \ + ../include/s_debug.h ../include/s_misc.h ../include/s_stats.h \ + ../include/send.h ../include/struct.h ../include/sys.h \ + ../include/whowas.h ircd_lexer.o: ircd_lexer.c ../config.h ../include/ircd.h \ ../include/struct.h ../include/ircd_defs.h ../include/ircd_alloc.h \ ../include/ircd_log.h ../include/ircd_string.h ../include/ircd_chattr.h \ ../include/s_conf.h ../include/client.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ - ../include/res.h ../include/capab.h y.tab.h + ../include/res.h ../include/capab.h ../include/ircd_features.h y.tab.h ircd_log.o: ircd_log.c ../config.h ../include/ircd_log.h \ ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ - ../include/res.h ../include/capab.h ../include/ircd_alloc.h \ - ../include/ircd_reply.h ../include/ircd_snprintf.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \ - ../include/struct.h ../include/numeric.h ../include/s_debug.h \ - ../include/send.h ../include/struct.h + ../include/res.h ../include/capab.h ../include/ircd_features.h \ + ../include/ircd_alloc.h ../include/ircd_reply.h \ + ../include/ircd_snprintf.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \ + ../include/numeric.h ../include/s_debug.h ../include/send.h \ + ../include/struct.h +ircd_netconf.o: ircd_netconf.c ../config.h ../include/client.h \ + ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ + ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_netconf.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/s_debug.h ../include/send.h ircd_relay.o: ircd_relay.c ../config.h ../include/ircd_relay.h \ ../include/channel.h ../include/ircd_defs.h ../include/res.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_features.h \ + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \ ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/match.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \ - ../include/s_user.h ../include/send.h + ../include/s_user.h ../include/send.h ../include/sline.h ircd_reply.o: ircd_reply.c ../config.h ../include/ircd_reply.h \ ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ - ../include/res.h ../include/capab.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_snprintf.h \ - ../include/msg.h ../include/msgq.h ../include/numeric.h \ - ../include/s_conf.h ../include/client.h ../include/s_debug.h \ - ../include/send.h + ../include/res.h ../include/capab.h ../include/ircd_features.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_snprintf.h ../include/msg.h ../include/msgq.h \ + ../include/numeric.h ../include/s_conf.h ../include/client.h \ + ../include/s_debug.h ../include/send.h ircd_res.o: ircd_res.c ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h ../config.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_osdep.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_features.h ../include/ircd_alloc.h ../include/ircd_log.h \ + ../include/ircd_osdep.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/ircd_snprintf.h ../include/ircd.h \ ../include/struct.h ../include/numeric.h ../include/fileio.h \ ../include/random.h ../include/s_bsd.h ../include/s_debug.h \ - ../include/s_stats.h ../include/ircd_features.h ../include/send.h \ - ../include/sys.h ../include/res.h ../include/ircd_reslib.h + ../include/s_stats.h ../include/send.h ../include/sys.h ../include/res.h \ + ../include/ircd_reslib.h ircd_reslib.o: ircd_reslib.c ../include/ircd.h ../include/struct.h \ ../include/ircd_defs.h ../include/res.h ../config.h \ ../include/ircd_reslib.h ../include/ircd_defs.h ../include/fileio.h \ @@ -518,31 +540,31 @@ ircd_signal.o: ircd_signal.c ../config.h ../include/ircd.h \ ../include/ircd_events.h ../include/ircd_log.h ../include/ircd_signal.h \ ../include/s_conf.h ../include/client.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h + ../include/capab.h ../include/ircd_features.h ircd_snprintf.o: ircd_snprintf.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/channel.h ../include/ircd_log.h \ - ../include/ircd_snprintf.h ../include/struct.h + ../include/capab.h ../include/ircd_features.h ../include/channel.h \ + ../include/ircd_log.h ../include/ircd_snprintf.h ../include/struct.h ircd_string.o: ircd_string.c ../config.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/ircd_defs.h ../include/ircd_chattr.h \ ../include/ircd_log.h ../include/res.h chattr.tab.c jupe.o: jupe.c ../config.h ../include/jupe.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \ - ../include/s_misc.h ../include/send.h ../include/struct.h \ - ../include/sys.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_bsd.h ../include/s_misc.h ../include/send.h \ + ../include/struct.h ../include/sys.h list.o: list.c ../config.h ../include/list.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_events.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_events.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/listener.h ../include/match.h \ ../include/numeric.h ../include/res.h ../include/s_auth.h \ ../include/s_bsd.h ../include/s_conf.h ../include/client.h \ @@ -551,177 +573,193 @@ list.o: list.c ../config.h ../include/list.h ../include/client.h \ listener.o: listener.c ../config.h ../include/listener.h \ ../include/ircd_defs.h ../include/ircd_events.h ../include/res.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ - ../include/ircd_handler.h ../include/capab.h ../include/client.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_events.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \ - ../include/ircd_snprintf.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/numeric.h \ - ../include/s_bsd.h ../include/s_conf.h ../include/s_misc.h \ - ../include/s_stats.h ../include/send.h ../include/sys.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/client.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_events.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_osdep.h \ + ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/numeric.h ../include/s_bsd.h ../include/s_conf.h \ + ../include/s_misc.h ../include/s_stats.h ../include/send.h \ + ../include/sys.h m_account.o: m_account.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numnicks.h \ - ../include/s_debug.h ../include/s_user.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numnicks.h ../include/s_debug.h ../include/s_user.h \ + ../include/send.h m_admin.o: m_admin.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/match.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ - ../include/client.h ../include/s_user.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_conf.h ../include/client.h ../include/s_user.h m_asll.o: m_asll.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \ - ../include/match.h ../include/msg.h ../include/send.h ../include/s_bsd.h \ - ../include/s_user.h + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \ + ../include/numnicks.h ../include/match.h ../include/msg.h \ + ../include/send.h ../include/s_bsd.h ../include/s_user.h m_away.o: m_away.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/s_user.h ../include/send.h + ../include/ircd_features.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_user.h \ + ../include/send.h m_burst.o: m_burst.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ - ../include/match.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/s_conf.h ../include/client.h \ - ../include/s_misc.h ../include/send.h ../include/struct.h \ - ../include/ircd_snprintf.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/list.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_conf.h ../include/client.h ../include/s_misc.h \ + ../include/send.h ../include/struct.h ../include/ircd_snprintf.h m_cap.o: m_cap.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_snprintf.h \ - ../include/ircd_string.h ../include/msg.h ../include/numeric.h \ - ../include/send.h ../include/s_auth.h ../include/s_user.h + ../include/ircd_features.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_chattr.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_snprintf.h ../include/ircd_string.h ../include/msg.h \ + ../include/numeric.h ../include/send.h ../include/s_auth.h \ + ../include/s_user.h m_clearmode.o: m_clearmode.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/channel.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/s_conf.h ../include/client.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/channel.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/list.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ + ../include/client.h ../include/send.h m_close.o: m_close.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/numeric.h \ - ../include/s_bsd.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/numeric.h ../include/s_bsd.h ../include/send.h +m_config.o: m_config.c ../config.h ../include/client.h \ + ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ + ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_netconf.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/send.h ../include/s_debug.h m_connect.o: m_connect.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/crule.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/jupe.h ../include/match.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/s_bsd.h ../include/s_conf.h ../include/client.h \ - ../include/s_user.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/crule.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \ + ../include/match.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/s_bsd.h ../include/s_conf.h \ + ../include/client.h ../include/s_user.h ../include/send.h m_cprivmsg.o: m_cprivmsg.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/s_user.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h + ../include/capab.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/s_user.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h m_create.o: m_create.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \ ../include/s_user.h ../include/send.h m_defaults.o: m_defaults.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/numeric.h \ - ../include/numnicks.h ../include/send.h ../include/supported.h \ - ../include/channel.h ../include/version.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/numeric.h ../include/numnicks.h ../include/send.h \ + ../include/supported.h ../include/channel.h ../include/version.h m_destruct.o: m_destruct.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/send.h \ - ../include/channel.h ../include/destruct_event.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/send.h ../include/channel.h \ + ../include/destruct_event.h m_desynch.o: m_desynch.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \ - ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/s_bsd.h ../include/send.h m_die.o: m_die.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_features.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/s_bsd.h ../include/send.h m_endburst.o: m_endburst.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/send.h m_error.o: m_error.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_alloc.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \ ../include/s_debug.h ../include/s_misc.h ../include/send.h m_get.o: m_get.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \ - ../include/numnicks.h ../include/send.h + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \ + ../include/send.h m_gline.o: m_gline.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/gline.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ - ../include/client.h ../include/s_debug.h ../include/s_misc.h \ - ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/gline.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_conf.h ../include/client.h ../include/s_debug.h \ + ../include/s_misc.h ../include/send.h m_help.o: m_help.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/send.h + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/send.h m_info.o: m_info.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_features.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/s_misc.h ../include/s_user.h \ ../include/s_conf.h ../include/client.h ../include/send.h \ @@ -729,25 +767,25 @@ m_info.o: m_info.c ../config.h ../include/client.h ../include/ircd_defs.h \ m_invite.o: m_invite.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/list.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_user.h \ - ../include/send.h ../include/struct.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_user.h ../include/send.h ../include/struct.h m_ison.o: m_ison.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msgq.h ../include/numeric.h \ - ../include/send.h + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msgq.h \ + ../include/numeric.h ../include/send.h m_join.o: m_join.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/gline.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_features.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/gline.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \ ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/msg.h ../include/numeric.h ../include/numnicks.h \ ../include/s_debug.h ../include/s_user.h ../include/send.h \ @@ -755,351 +793,374 @@ m_join.o: m_join.c ../config.h ../include/channel.h \ m_jupe.o: m_jupe.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/jupe.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_features.h ../include/jupe.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ ../include/client.h ../include/s_misc.h ../include/send.h m_kick.o: m_kick.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/send.h ../include/ircd_features.h m_kill.o: m_kill.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_snprintf.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/s_misc.h ../include/send.h \ - ../include/whowas.h + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_misc.h \ + ../include/send.h ../include/whowas.h m_links.o: m_links.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_defs.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_defs.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/s_user.h \ ../include/send.h ../include/struct.h m_list.o: m_list.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_chattr.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/s_bsd.h ../include/send.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_chattr.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/s_bsd.h ../include/send.h m_lusers.o: m_lusers.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ - ../include/ircd_features.h ../include/s_user.h ../include/s_serv.h \ - ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/querycmds.h ../include/s_user.h \ + ../include/s_serv.h ../include/send.h m_map.o: m_map.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_defs.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_snprintf.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/list.h ../include/match.h \ - ../include/msg.h ../include/numeric.h ../include/s_user.h \ - ../include/s_serv.h ../include/send.h ../include/querycmds.h \ - ../include/ircd_features.h + ../include/ircd_features.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_defs.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ + ../include/match.h ../include/msg.h ../include/numeric.h \ + ../include/s_user.h ../include/s_serv.h ../include/send.h \ + ../include/querycmds.h m_mode.o: m_mode.c ../config.h ../include/handlers.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/s_conf.h ../include/client.h \ - ../include/s_debug.h ../include/s_user.h ../include/send.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ + ../include/client.h ../include/s_debug.h ../include/s_user.h \ + ../include/send.h m_motd.o: m_motd.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/motd.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/s_conf.h ../include/client.h ../include/class.h \ - ../include/s_user.h ../include/send.h + ../include/ircd_features.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/motd.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/s_conf.h ../include/client.h \ + ../include/class.h ../include/s_user.h ../include/send.h m_names.o: m_names.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/s_user.h ../include/send.h m_nick.o: m_nick.c ../config.h ../include/IPcheck.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \ - ../include/send.h ../include/sys.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \ + ../include/s_user.h ../include/send.h ../include/sys.h m_notice.o: m_notice.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/handlers.h ../include/ircd_chattr.h \ - ../include/ircd_log.h ../include/ircd_relay.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/match.h ../include/msg.h \ - ../include/numeric.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/handlers.h \ + ../include/ircd_chattr.h ../include/ircd_log.h ../include/ircd_relay.h \ + ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/send.h m_oper.o: m_oper.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/ircd_crypt.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ - ../include/ircd_features.h ../include/s_conf.h ../include/client.h \ - ../include/s_debug.h ../include/s_user.h ../include/s_misc.h \ - ../include/send.h + ../include/s_conf.h ../include/client.h ../include/s_debug.h \ + ../include/s_user.h ../include/s_misc.h ../include/send.h m_opmode.o: m_opmode.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/channel.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/querycmds.h ../include/ircd_features.h \ + ../include/capab.h ../include/ircd_features.h ../include/channel.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ ../include/send.h ../include/s_conf.h ../include/client.h \ ../include/s_user.h m_part.o: m_part.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \ - ../include/send.h + ../include/send.h ../include/sline.h ../include/s_user.h m_pass.o: m_pass.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/s_auth.h ../include/send.h + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/s_auth.h \ + ../include/send.h m_ping.o: m_ping.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \ - ../include/struct.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/opercmds.h ../include/s_debug.h \ - ../include/send.h + ../include/ircd_features.h ../include/hash.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/opercmds.h ../include/s_debug.h ../include/send.h m_pong.o: m_pong.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/opercmds.h ../include/s_auth.h \ - ../include/s_user.h ../include/send.h + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \ + ../include/s_auth.h ../include/s_user.h ../include/send.h m_privmsg.o: m_privmsg.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_features.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \ ../include/ircd_log.h ../include/ircd_relay.h ../include/ircd_reply.h \ ../include/ircd_string.h ../include/match.h ../include/msg.h \ ../include/numeric.h ../include/send.h m_privs.o: m_privs.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/send.h m_proto.o: m_proto.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_chattr.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \ - ../include/s_misc.h ../include/send.h ../include/supported.h \ - ../include/channel.h ../include/version.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_debug.h ../include/s_misc.h ../include/send.h \ + ../include/supported.h ../include/channel.h ../include/version.h m_pseudo.o: m_pseudo.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_relay.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/ircd_snprintf.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ - ../include/client.h ../include/s_user.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_relay.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h \ + ../include/ircd_snprintf.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/s_conf.h ../include/client.h \ + ../include/s_user.h m_quit.o: m_quit.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/struct.h ../include/s_misc.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/sline.h \ + ../include/struct.h ../include/s_misc.h ../include/s_user.h \ ../include/ircd_reply.h m_rehash.o: m_rehash.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/motd.h ../include/numeric.h \ - ../include/s_conf.h ../include/client.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/motd.h \ + ../include/numeric.h ../include/s_conf.h ../include/client.h \ + ../include/send.h m_reset.o: m_reset.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \ ../include/send.h m_restart.o: m_restart.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \ - ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \ + ../include/numnicks.h ../include/send.h m_rping.o: m_rping.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \ - ../include/s_user.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/opercmds.h ../include/s_user.h \ + ../include/send.h m_rpong.o: m_rpong.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \ - ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/numnicks.h ../include/opercmds.h ../include/send.h m_server.o: m_server.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_features.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/jupe.h ../include/list.h \ - ../include/match.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/querycmds.h ../include/ircd_features.h \ + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_features.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \ + ../include/list.h ../include/match.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ ../include/s_bsd.h ../include/s_conf.h ../include/client.h \ ../include/s_debug.h ../include/s_misc.h ../include/s_serv.h \ ../include/send.h ../include/userload.h m_set.o: m_set.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \ - ../include/numnicks.h ../include/send.h + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \ + ../include/send.h m_settime.o: m_settime.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_snprintf.h \ ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ ../include/msg.h ../include/numeric.h ../include/numnicks.h \ ../include/s_user.h ../include/send.h ../include/struct.h m_silence.o: m_silence.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_snprintf.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/s_user.h ../include/send.h ../include/struct.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_snprintf.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/list.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_user.h \ + ../include/send.h ../include/struct.h +m_sline.o: m_sline.c ../config.h ../include/client.h \ + ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ + ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ + ../include/capab.h ../include/ircd_features.h ../include/sline.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h \ + ../include/ircd_snprintf.h ../include/match.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ + ../include/client.h ../include/s_debug.h ../include/s_misc.h \ + ../include/send.h m_squit.o: m_squit.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_chattr.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h ../include/numeric.h \ - ../include/numnicks.h ../include/match.h ../include/s_debug.h \ - ../include/s_misc.h ../include/s_user.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/numeric.h ../include/numnicks.h ../include/match.h \ + ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \ + ../include/send.h m_stats.o: m_stats.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/s_stats.h ../include/s_user.h \ - ../include/send.h ../include/struct.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/s_stats.h ../include/s_user.h ../include/send.h \ + ../include/struct.h m_time.o: m_time.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/s_misc.h ../include/s_user.h \ - ../include/send.h + ../include/ircd_features.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_misc.h \ + ../include/s_user.h ../include/send.h m_topic.o: m_topic.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/send.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/send.h m_trace.o: m_trace.c ../config.h ../include/class.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/client.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \ - ../include/s_conf.h ../include/s_user.h ../include/send.h \ - ../include/version.h + ../include/capab.h ../include/ircd_features.h ../include/client.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_bsd.h ../include/s_conf.h ../include/s_user.h \ + ../include/send.h ../include/version.h m_uping.o: m_uping.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/s_conf.h ../include/client.h ../include/s_user.h \ - ../include/send.h ../include/uping.h + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ + ../include/client.h ../include/s_user.h ../include/send.h \ + ../include/uping.h m_user.o: m_user.c ../config.h ../include/handlers.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/numeric.h ../include/numnicks.h \ - ../include/s_auth.h ../include/s_debug.h ../include/s_misc.h \ - ../include/s_user.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_chattr.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h ../include/numeric.h \ + ../include/numnicks.h ../include/s_auth.h ../include/s_debug.h \ + ../include/s_misc.h ../include/s_user.h ../include/send.h m_userhost.o: m_userhost.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msgq.h \ - ../include/numeric.h ../include/s_user.h ../include/struct.h + ../include/capab.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msgq.h ../include/numeric.h \ + ../include/s_user.h ../include/struct.h m_userip.o: m_userip.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/msgq.h ../include/numeric.h \ - ../include/s_user.h ../include/struct.h + ../include/capab.h ../include/ircd_features.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/msgq.h \ + ../include/numeric.h ../include/s_user.h ../include/struct.h m_version.o: m_version.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_snprintf.h \ ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ ../include/msg.h ../include/numeric.h ../include/numnicks.h \ ../include/s_debug.h ../include/s_user.h ../include/send.h \ @@ -1107,79 +1168,84 @@ m_version.o: m_version.c ../config.h ../include/client.h \ m_wallchops.o: m_wallchops.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/s_user.h ../include/send.h + ../include/numnicks.h ../include/s_user.h ../include/send.h \ + ../include/sline.h m_wallops.o: m_wallops.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/send.h m_wallusers.o: m_wallusers.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ - ../include/numeric.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ + ../include/send.h m_wallvoices.o: m_wallvoices.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/s_user.h ../include/send.h + ../include/numnicks.h ../include/s_user.h ../include/send.h \ + ../include/sline.h m_webirc.o: m_webirc.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_features.h ../include/ircd_reply.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \ ../include/ircd_string.h ../include/ircd_chattr.h ../include/s_auth.h \ ../include/s_conf.h ../include/client.h ../include/s_misc.h m_who.o: m_who.c ../config.h ../include/channel.h ../include/ircd_defs.h \ ../include/res.h ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_features.h \ + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \ ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/match.h ../include/numeric.h ../include/numnicks.h \ ../include/send.h ../include/whocmds.h m_whois.o: m_whois.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ - ../include/client.h ../include/s_user.h ../include/send.h \ - ../include/whocmds.h + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_conf.h ../include/client.h ../include/s_user.h \ + ../include/send.h ../include/whocmds.h m_whowas.o: m_whowas.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/capab.h ../include/ircd_features.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/s_user.h ../include/s_misc.h \ ../include/send.h ../include/whowas.h m_xquery.o: m_xquery.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/send.h m_xreply.o: m_xreply.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/s_auth.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_auth.h \ + ../include/send.h ../include/sline.h match.o: match.c ../config.h ../include/match.h ../include/res.h \ ../include/ircd_chattr.h ../include/ircd_string.h \ ../include/ircd_snprintf.h @@ -1187,15 +1253,15 @@ memdebug.o: memdebug.c ../include/ircd.h ../include/struct.h \ ../include/ircd_defs.h ../include/ircd_alloc.h ../include/ircd_log.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../config.h ../include/ircd_handler.h \ - ../include/res.h ../include/capab.h ../include/s_debug.h \ - ../include/send.h + ../include/res.h ../include/capab.h ../include/ircd_features.h \ + ../include/s_debug.h ../include/send.h motd.o: motd.c ../config.h ../include/motd.h ../include/res.h \ ../include/class.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ - ../include/ircd_handler.h ../include/capab.h ../include/client.h \ - ../include/fileio.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_handler.h ../include/capab.h ../include/ircd_features.h \ + ../include/client.h ../include/fileio.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ ../include/s_debug.h ../include/s_user.h ../include/s_stats.h \ @@ -1204,21 +1270,24 @@ msgq.o: msgq.c ../config.h ../include/msgq.h ../include/ircd_defs.h \ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ ../include/ircd_defs.h ../include/ircd_features.h ../include/ircd_log.h \ ../include/ircd_reply.h ../include/ircd_snprintf.h ../include/numeric.h \ - ../include/send.h ../include/s_debug.h ../include/s_stats.h + ../include/send.h ../include/client.h ../include/dbuf.h \ + ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ + ../include/capab.h ../include/ircd_features.h ../include/s_debug.h \ + ../include/s_stats.h numnicks.o: numnicks.c ../config.h ../include/numnicks.h \ ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ - ../include/res.h ../include/capab.h ../include/client.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_log.h ../include/ircd_string.h ../include/ircd_chattr.h \ - ../include/match.h ../include/s_bsd.h ../include/s_debug.h \ - ../include/s_misc.h ../include/struct.h + ../include/res.h ../include/capab.h ../include/ircd_features.h \ + ../include/client.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/match.h ../include/s_bsd.h \ + ../include/s_debug.h ../include/s_misc.h ../include/struct.h opercmds.o: opercmds.c ../config.h ../include/opercmds.h \ ../include/class.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/client.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_reply.h \ + ../include/ircd_features.h ../include/client.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \ ../include/ircd_string.h ../include/listener.h ../include/match.h \ ../include/msg.h ../include/numeric.h ../include/numnicks.h \ ../include/s_conf.h ../include/send.h ../include/struct.h @@ -1228,69 +1297,70 @@ os_generic.o: os_generic.c ../config.h ../include/ircd_osdep.h \ packet.o: packet.c ../config.h ../include/packet.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_log.h ../include/parse.h \ - ../include/s_bsd.h ../include/s_misc.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_chattr.h ../include/ircd_log.h \ + ../include/parse.h ../include/s_bsd.h ../include/s_misc.h \ + ../include/send.h parse.o: parse.c ../config.h ../include/parse.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/channel.h ../include/handlers.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_chattr.h \ + ../include/capab.h ../include/ircd_features.h ../include/channel.h \ + ../include/handlers.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \ ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ ../include/ircd_string.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/opercmds.h ../include/querycmds.h \ - ../include/ircd_features.h ../include/res.h ../include/s_bsd.h \ - ../include/s_conf.h ../include/client.h ../include/s_debug.h \ - ../include/s_misc.h ../include/s_numeric.h ../include/s_user.h \ - ../include/send.h ../include/struct.h ../include/sys.h \ - ../include/whocmds.h ../include/whowas.h + ../include/res.h ../include/s_bsd.h ../include/s_conf.h \ + ../include/client.h ../include/s_debug.h ../include/s_misc.h \ + ../include/s_numeric.h ../include/s_user.h ../include/send.h \ + ../include/struct.h ../include/sys.h ../include/whocmds.h \ + ../include/whowas.h querycmds.o: querycmds.c ../config.h ../include/querycmds.h \ ../include/ircd_features.h random.o: random.c ../config.h ../include/random.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd_log.h ../include/ircd_md5.h \ - ../include/ircd_reply.h ../include/send.h + ../include/capab.h ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_md5.h ../include/ircd_reply.h ../include/send.h s_auth.o: s_auth.c ../config.h ../include/s_auth.h \ ../include/ircd_events.h ../include/class.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_handler.h ../include/res.h ../include/capab.h \ - ../include/client.h ../include/IPcheck.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \ - ../include/ircd_events.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \ - ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/querycmds.h ../include/ircd_features.h ../include/random.h \ - ../include/res.h ../include/s_bsd.h ../include/s_conf.h \ - ../include/s_debug.h ../include/s_misc.h ../include/s_stats.h \ - ../include/s_user.h ../include/send.h + ../include/ircd_features.h ../include/client.h ../include/IPcheck.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ + ../include/ircd_chattr.h ../include/ircd_events.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_osdep.h \ + ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/ircd_string.h ../include/list.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ + ../include/random.h ../include/res.h ../include/s_bsd.h \ + ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \ + ../include/s_stats.h ../include/s_user.h ../include/send.h s_bsd.o: s_bsd.c ../config.h ../include/s_bsd.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/IPcheck.h ../include/channel.h \ - ../include/class.h ../include/client.h ../include/hash.h \ - ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_features.h \ - ../include/ircd_osdep.h ../include/ircd_reply.h \ - ../include/ircd_snprintf.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \ - ../include/list.h ../include/listener.h ../include/msg.h \ - ../include/msgq.h ../include/numeric.h ../include/numnicks.h \ - ../include/packet.h ../include/parse.h ../include/querycmds.h \ - ../include/ircd_features.h ../include/res.h ../include/s_auth.h \ + ../include/capab.h ../include/ircd_features.h ../include/IPcheck.h \ + ../include/channel.h ../include/class.h ../include/client.h \ + ../include/hash.h ../include/ircd_alloc.h ../include/ircd_log.h \ + ../include/ircd_features.h ../include/ircd_osdep.h \ + ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \ + ../include/struct.h ../include/list.h ../include/listener.h \ + ../include/msg.h ../include/msgq.h ../include/numeric.h \ + ../include/numnicks.h ../include/packet.h ../include/parse.h \ + ../include/querycmds.h ../include/res.h ../include/s_auth.h \ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \ ../include/s_user.h ../include/send.h ../include/struct.h \ ../include/sys.h ../include/uping.h ../include/version.h s_conf.o: s_conf.c ../config.h ../include/s_conf.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/IPcheck.h ../include/class.h \ - ../include/client.h ../include/crule.h ../include/ircd_features.h \ - ../include/fileio.h ../include/gline.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_chattr.h ../include/ircd_lexer.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/capab.h ../include/ircd_features.h ../include/IPcheck.h \ + ../include/class.h ../include/client.h ../include/crule.h \ + ../include/ircd_features.h ../include/fileio.h ../include/gline.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_chattr.h ../include/ircd_lexer.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_snprintf.h \ ../include/ircd_string.h ../include/list.h ../include/listener.h \ ../include/match.h ../include/motd.h ../include/numeric.h \ ../include/numnicks.h ../include/opercmds.h ../include/parse.h \ @@ -1301,103 +1371,119 @@ s_debug.o: s_debug.c ../config.h ../include/s_debug.h \ ../include/ircd_defs.h ../include/channel.h ../include/res.h \ ../include/class.h ../include/client.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ - ../include/capab.h ../include/client.h ../include/gline.h \ - ../include/hash.h ../include/ircd_alloc.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \ - ../include/ircd.h ../include/struct.h ../include/jupe.h \ - ../include/list.h ../include/listener.h ../include/motd.h \ - ../include/msgq.h ../include/numeric.h ../include/numnicks.h \ - ../include/res.h ../include/s_bsd.h ../include/s_conf.h \ - ../include/s_user.h ../include/s_stats.h ../include/send.h \ - ../include/struct.h ../include/sys.h ../include/whowas.h + ../include/capab.h ../include/ircd_features.h ../include/client.h \ + ../include/gline.h ../include/hash.h ../include/ircd_alloc.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_osdep.h \ + ../include/ircd_reply.h ../include/ircd.h ../include/struct.h \ + ../include/jupe.h ../include/list.h ../include/listener.h \ + ../include/motd.h ../include/msgq.h ../include/numeric.h \ + ../include/numnicks.h ../include/res.h ../include/s_bsd.h \ + ../include/s_conf.h ../include/s_user.h ../include/s_stats.h \ + ../include/send.h ../include/struct.h ../include/sys.h \ + ../include/whowas.h s_err.o: s_err.c ../config.h ../include/numeric.h ../include/ircd_log.h \ ../include/s_debug.h ../include/ircd_defs.h s_misc.o: s_misc.c ../config.h ../include/s_misc.h ../include/IPcheck.h \ ../include/channel.h ../include/ircd_defs.h ../include/res.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_features.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_snprintf.h \ + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_snprintf.h \ ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ ../include/match.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/parse.h ../include/querycmds.h \ - ../include/ircd_features.h ../include/res.h ../include/s_auth.h \ - ../include/s_bsd.h ../include/s_conf.h ../include/client.h \ - ../include/s_debug.h ../include/s_stats.h ../include/s_user.h \ - ../include/send.h ../include/struct.h ../include/sys.h \ + ../include/res.h ../include/s_auth.h ../include/s_bsd.h \ + ../include/s_conf.h ../include/client.h ../include/s_debug.h \ + ../include/s_stats.h ../include/s_user.h ../include/send.h \ + ../include/sline.h ../include/struct.h ../include/sys.h \ ../include/uping.h ../include/userload.h s_numeric.o: s_numeric.c ../config.h ../include/s_numeric.h \ ../include/channel.h ../include/ircd_defs.h ../include/res.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_features.h ../include/ircd_snprintf.h \ - ../include/numnicks.h ../include/send.h ../include/struct.h + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_snprintf.h ../include/numnicks.h ../include/send.h \ + ../include/struct.h s_serv.o: s_serv.c ../config.h ../include/s_serv.h ../include/IPcheck.h \ ../include/channel.h ../include/ircd_defs.h ../include/res.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ - ../include/gline.h ../include/hash.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_alloc.h ../include/ircd_log.h \ + ../include/ircd_features.h ../include/gline.h ../include/sline.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_netconf.h \ ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/ircd_snprintf.h \ ../include/ircd_crypt.h ../include/jupe.h ../include/list.h \ ../include/match.h ../include/msg.h ../include/msgq.h \ ../include/numeric.h ../include/numnicks.h ../include/parse.h \ - ../include/querycmds.h ../include/ircd_features.h ../include/s_bsd.h \ - ../include/s_conf.h ../include/client.h ../include/s_debug.h \ - ../include/s_misc.h ../include/s_user.h ../include/send.h \ - ../include/struct.h ../include/sys.h ../include/userload.h + ../include/querycmds.h ../include/s_bsd.h ../include/s_conf.h \ + ../include/client.h ../include/s_debug.h ../include/s_misc.h \ + ../include/s_user.h ../include/send.h ../include/struct.h \ + ../include/sys.h ../include/userload.h s_stats.o: s_stats.c ../config.h ../include/class.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/client.h ../include/gline.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_events.h \ + ../include/capab.h ../include/ircd_features.h ../include/client.h \ + ../include/gline.h ../include/hash.h ../include/sline.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \ + ../include/ircd_netconf.h ../include/ircd_events.h \ ../include/ircd_features.h ../include/ircd_crypt.h ../include/ircd_log.h \ ../include/ircd_reply.h ../include/ircd_string.h ../include/listener.h \ ../include/list.h ../include/match.h ../include/motd.h ../include/msg.h \ ../include/msgq.h ../include/numeric.h ../include/numnicks.h \ - ../include/querycmds.h ../include/ircd_features.h ../include/res.h \ - ../include/s_auth.h ../include/s_bsd.h ../include/s_conf.h \ - ../include/s_debug.h ../include/s_misc.h ../include/s_serv.h \ - ../include/s_stats.h ../include/s_user.h ../include/send.h \ - ../include/struct.h ../include/userload.h + ../include/querycmds.h ../include/res.h ../include/s_auth.h \ + ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \ + ../include/s_misc.h ../include/s_serv.h ../include/s_stats.h \ + ../include/s_user.h ../include/send.h ../include/struct.h \ + ../include/userload.h s_user.o: s_user.c ../config.h ../include/s_user.h ../include/IPcheck.h \ ../include/channel.h ../include/ircd_defs.h ../include/res.h \ ../include/class.h ../include/client.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ - ../include/capab.h ../include/client.h ../include/hash.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/ircd_chattr.h ../include/ircd_features.h \ - ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_snprintf.h \ - ../include/ircd_string.h ../include/list.h ../include/match.h \ - ../include/motd.h ../include/msg.h ../include/msgq.h \ + ../include/capab.h ../include/ircd_features.h ../include/client.h \ + ../include/hash.h ../include/ircd.h ../include/struct.h \ + ../include/ircd_alloc.h ../include/ircd_chattr.h \ + ../include/ircd_features.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \ + ../include/match.h ../include/motd.h ../include/msg.h ../include/msgq.h \ ../include/numeric.h ../include/numnicks.h ../include/parse.h \ - ../include/querycmds.h ../include/ircd_features.h ../include/random.h \ - ../include/s_auth.h ../include/s_bsd.h ../include/s_conf.h \ - ../include/s_debug.h ../include/s_misc.h ../include/s_serv.h \ - ../include/send.h ../include/struct.h ../include/supported.h \ - ../include/channel.h ../include/sys.h ../include/userload.h \ - ../include/version.h ../include/whowas.h ../include/handlers.h -send.o: send.c ../config.h ../include/send.h ../include/channel.h \ - ../include/ircd_defs.h ../include/res.h ../include/class.h \ - ../include/client.h ../include/dbuf.h ../include/msgq.h \ - ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ - ../include/client.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_features.h ../include/ircd_log.h \ + ../include/querycmds.h ../include/random.h ../include/s_auth.h \ + ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \ + ../include/s_misc.h ../include/s_serv.h ../include/send.h \ + ../include/struct.h ../include/supported.h ../include/channel.h \ + ../include/sys.h ../include/userload.h ../include/version.h \ + ../include/whowas.h ../include/handlers.h +send.o: send.c ../config.h ../include/send.h ../include/client.h \ + ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ + ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ + ../include/capab.h ../include/ircd_features.h ../include/channel.h \ + ../include/class.h ../include/client.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ ../include/ircd_snprintf.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/list.h ../include/match.h \ ../include/msg.h ../include/numnicks.h ../include/parse.h \ ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \ ../include/s_user.h ../include/struct.h ../include/sys.h +sline.o: sline.c ../config.h ../include/channel.h ../include/ircd_defs.h \ + ../include/res.h ../include/client.h ../include/dbuf.h ../include/msgq.h \ + ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_events.h \ + ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_netconf.h ../include/ircd_reply.h \ + ../include/ircd_snprintf.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \ + ../include/s_stats.h ../include/s_user.h ../include/send.h \ + ../include/sline.h ../include/struct.h ../include/sys.h uping.o: uping.c ../config.h ../include/uping.h ../include/ircd_defs.h \ ../include/ircd_events.h ../include/res.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_events.h ../include/ircd_log.h \ - ../include/ircd_osdep.h ../include/ircd_string.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_events.h \ + ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \ ../include/s_conf.h ../include/client.h ../include/s_debug.h \ @@ -1406,30 +1492,30 @@ uping.o: uping.c ../config.h ../include/uping.h ../include/ircd_defs.h \ userload.o: userload.c ../config.h ../include/userload.h \ ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ - ../include/res.h ../include/capab.h ../include/ircd.h \ - ../include/struct.h ../include/msg.h ../include/numnicks.h \ - ../include/querycmds.h ../include/ircd_features.h ../include/s_misc.h \ + ../include/res.h ../include/capab.h ../include/ircd_features.h \ + ../include/ircd.h ../include/struct.h ../include/msg.h \ + ../include/numnicks.h ../include/querycmds.h ../include/s_misc.h \ ../include/s_stats.h ../include/send.h ../include/struct.h \ ../include/sys.h whocmds.o: whocmds.c ../config.h ../include/whocmds.h \ ../include/channel.h ../include/ircd_defs.h ../include/res.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/capab.h \ - ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_chattr.h ../include/ircd_features.h \ + ../include/ircd_features.h ../include/hash.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \ ../include/ircd_reply.h ../include/ircd_snprintf.h \ ../include/ircd_string.h ../include/list.h ../include/match.h \ ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ - ../include/ircd_features.h ../include/random.h ../include/s_bsd.h \ - ../include/s_conf.h ../include/client.h ../include/s_misc.h \ - ../include/s_user.h ../include/send.h ../include/struct.h \ - ../include/sys.h ../include/userload.h ../include/version.h \ - ../include/whowas.h ../include/msg.h + ../include/random.h ../include/s_bsd.h ../include/s_conf.h \ + ../include/client.h ../include/s_misc.h ../include/s_user.h \ + ../include/send.h ../include/struct.h ../include/sys.h \ + ../include/userload.h ../include/version.h ../include/whowas.h \ + ../include/msg.h whowas.o: whowas.c ../config.h ../include/whowas.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_alloc.h ../include/ircd_chattr.h \ + ../include/capab.h ../include/ircd_features.h ../include/ircd.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \ ../include/ircd_features.h ../include/ircd_log.h \ ../include/ircd_string.h ../include/list.h ../include/numeric.h \ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \ @@ -1437,18 +1523,18 @@ whowas.o: whowas.c ../config.h ../include/whowas.h ../include/client.h \ y.tab.o: y.tab.c ../config.h ../include/s_conf.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \ - ../include/capab.h ../include/class.h ../include/client.h \ - ../include/crule.h ../include/fileio.h ../include/gline.h \ - ../include/hash.h ../include/IPcheck.h ../include/ircd.h \ - ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \ - ../include/ircd_features.h ../include/ircd_lexer.h ../include/ircd_log.h \ - ../include/ircd_reply.h ../include/ircd_snprintf.h \ - ../include/ircd_string.h ../include/list.h ../include/listener.h \ - ../include/match.h ../include/motd.h ../include/numeric.h \ - ../include/numnicks.h ../include/opercmds.h ../include/parse.h \ - ../include/res.h ../include/s_auth.h ../include/s_bsd.h \ - ../include/s_debug.h ../include/s_misc.h ../include/send.h \ - ../include/struct.h ../include/sys.h + ../include/capab.h ../include/ircd_features.h ../include/class.h \ + ../include/client.h ../include/crule.h ../include/fileio.h \ + ../include/gline.h ../include/hash.h ../include/IPcheck.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ + ../include/ircd_chattr.h ../include/ircd_features.h \ + ../include/ircd_lexer.h ../include/ircd_log.h ../include/ircd_reply.h \ + ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \ + ../include/listener.h ../include/match.h ../include/motd.h \ + ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \ + ../include/parse.h ../include/res.h ../include/s_auth.h \ + ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \ + ../include/send.h ../include/struct.h ../include/sys.h engine_devpoll.o: engine_devpoll.c ../config.h ../include/ircd_events.h \ ../include/ircd.h ../include/struct.h ../include/ircd_defs.h \ ../include/ircd_alloc.h ../include/ircd_features.h ../include/ircd_log.h \ diff --git a/ircd/channel.c b/ircd/channel.c index 16eacc36..8136d013 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -49,6 +49,7 @@ #include "s_misc.h" #include "s_user.h" #include "send.h" +#include "sline.h" #include "struct.h" #include "sys.h" #include "whowas.h" @@ -330,6 +331,12 @@ int destruct_channel(struct Channel* chptr) next = ban->next; free_ban(ban); } + + /* + * Clean up S-line hold queue entries for this channel + */ + sline_cleanup_channel(chptr); + if (chptr->prev) chptr->prev->next = chptr->next; else diff --git a/ircd/ircd.c b/ircd/ircd.c index d643fb09..98c16e11 100644 --- a/ircd/ircd.c +++ b/ircd/ircd.c @@ -55,6 +55,7 @@ #include "s_misc.h" #include "s_stats.h" #include "send.h" +#include "sline.h" #include "sys.h" #include "uping.h" #include "userload.h" @@ -731,6 +732,7 @@ int main(int argc, char **argv) { stats_init(); IPcheck_init(); + sline_init(); timer_add(timer_init(&connect_timer), try_connections, 0, TT_RELATIVE, 1); timer_add(timer_init(&ping_timer), check_pings, 0, TT_RELATIVE, 1); timer_add(timer_init(&destruct_event_timer), exec_expired_destruct_events, 0, TT_PERIODIC, 60); diff --git a/ircd/ircd_features.c b/ircd/ircd_features.c index 6410099b..a6f3b7aa 100644 --- a/ircd/ircd_features.c +++ b/ircd/ircd_features.c @@ -326,6 +326,7 @@ static struct FeatureDesc { F_B(TOPIC_BURST, 0, 1, 0), F_B(AWAY_BURST, 0, 1, 0), F_B(DISABLE_GLINES, 0, 0, 0), + F_B(DISABLE_SLINES, 0, 0, 0), F_B(JOIN_TARGET, 0, 0, 0), /* features that probably should not be touched */ @@ -387,6 +388,7 @@ static struct FeatureDesc { F_B(HIS_TRACE, 0, 1, 0), F_B(HIS_STATS_a, 0, 1, 0), F_B(HIS_STATS_c, 0, 1, 0), + F_B(HIS_STATS_C, 0, 1, 0), F_B(HIS_STATS_d, 0, 1, 0), F_B(HIS_STATS_e, 0, 1, 0), F_B(HIS_STATS_f, 0, 1, 0), @@ -397,13 +399,14 @@ static struct FeatureDesc { F_B(HIS_STATS_k, 0, 1, 0), F_B(HIS_STATS_l, 0, 1, 0), F_B(HIS_STATS_L, 0, 1, 0), - F_B(HIS_STATS_M, 0, 1, 0), F_B(HIS_STATS_m, 0, 1, 0), + F_B(HIS_STATS_M, 0, 1, 0), F_B(HIS_STATS_o, 0, 1, 0), F_B(HIS_STATS_p, 0, 1, 0), F_B(HIS_STATS_q, 0, 1, 0), - F_B(HIS_STATS_R, 0, 1, 0), F_B(HIS_STATS_r, 0, 1, 0), + F_B(HIS_STATS_R, 0, 1, 0), + F_B(HIS_STATS_s, 0, 1, 0), F_B(HIS_STATS_t, 0, 1, 0), F_B(HIS_STATS_T, 0, 1, 0), F_B(HIS_STATS_u, 0, 0, 0), diff --git a/ircd/ircd_netconf.c b/ircd/ircd_netconf.c new file mode 100644 index 00000000..568c4006 --- /dev/null +++ b/ircd/ircd_netconf.c @@ -0,0 +1,352 @@ +/* + * IRC - Internet Relay Chat, ircd/ircd_netconf.c + * Copyright (C) 2025 MrIron + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" + +#include "client.h" +#include "ircd.h" +#include "ircd_alloc.h" +#include "ircd_netconf.h" +#include "ircd_reply.h" +#include "ircd_string.h" +#include "msg.h" +#include "numeric.h" +#include "numnicks.h" +#include "s_debug.h" +#include "send.h" + +#include +#include + +/** Head of the configuration list */ +static struct ConfigEntry *config_list = NULL; + +/** Head of the callback list */ +static struct ConfigCallback *callback_list = NULL; + +#define NETCONF_INT 0x0001 /**< set if entry contains an integer value */ +#define NETCONF_BOOL 0x0002 /**< set if entry contains a boolean value */ +#define NETCONF_STR 0x0003 /**< set if entry contains a string value */ +#define NETCONF_MASK 0x000f /**< possible value types */ + +/** Declare a network configuration option that takes integer values. */ +#define NC_I(type, cf_string, v_int) \ + { NETCONF_ ## type, cf_string, NETCONF_INT, 0, (v_int), 0, 0 } + +/** Declare a network configuration option that takes boolean values. */ +#define NC_B(type, cf_string, v_int) \ + { NETCONF_ ## type, cf_string, NETCONF_BOOL, 0, (v_int), 0, 0 } + +/** Declare a network configuration option that takes string values. */ +#define NC_S(type, cf_string, v_str) \ + { NETCONF_ ## type, cf_string, NETCONF_STR, 0, 0, 0, (v_str) } + +/** Network configuration description structure */ +static struct NetConfDesc { + enum NetConf netconf; /**< configuration identifier */ + char* type; /**< string describing type */ + unsigned int flags; /**< flags for configuration */ + int v_int; /**< integer value */ + int def_int; /**< default integer value */ + char* v_str; /**< string value */ + char* def_str; /**< default string value */ +} netconf_descs[] = { + /* S:line related settings */ + NC_S(SLINE_SERVER, "sline.server", ""), + NC_I(SLINE_HOLD_TIMEOUT, "sline.hold_timeout", 60), + NC_B(SLINE_HOLD_TIMEOUT_BLOCK, "sline.hold_timeout_block", 1), + + { NETCONF_LAST_NC, 0, 0, 0, 0, 0, 0 } /* sentinel */ +}; + +/** Find a configuration entry by key + * @param[in] key Configuration key to find + * @return Configuration entry or NULL if not found + */ +static struct ConfigEntry *config_find(const char *key) +{ + struct ConfigEntry *entry; + + assert(key != NULL); + + for (entry = config_list; entry; entry = entry->next) { + if (ircd_strcmp(entry->key, key) == 0) + return entry; + } + + return NULL; +} + +/** Call registered callbacks for a key + * @param[in] key Configuration key that changed + * @param[in] old_value Previous value (NULL if new) + * @param[in] new_value New value + */ +static void config_call_callbacks(const char *key, const char *old_value, const char *new_value) +{ + struct ConfigCallback *cb; + + for (cb = callback_list; cb; cb = cb->next) { + if (ircd_strncmp(key, cb->key_prefix, strlen(cb->key_prefix)) == 0) { + cb->callback(key, old_value, new_value); + } + } +} + +/** Set a configuration option + * @param[in] key Configuration key + * @param[in] value Configuration value + * @param[in] timestamp Timestamp when this config was set + * @return 1 if the value was updated, 0 if it was created, -1 on error + */ +int config_set(const char *key, const char *value, time_t timestamp) +{ + struct ConfigEntry *entry; + char *old_value = NULL; + int result; + + assert(key != NULL); + assert(value != NULL); + + entry = config_find(key); + + if (entry) { + /* Only update if timestamp is newer */ + if (timestamp <= entry->timestamp) + return CONFIG_REJECTED; + + /* Save old value for callbacks */ + DupString(old_value, entry->value); + + /* Check if value actually changed */ + int value_changed = (ircd_strcmp(old_value, value) != 0); + + /* Update existing entry */ + MyFree(entry->value); + DupString(entry->value, value); + entry->timestamp = timestamp; + + result = value_changed ? CONFIG_CHANGED : CONFIG_TIMESTAMP; + } else { + /* Create new entry */ + entry = MyMalloc(sizeof(struct ConfigEntry)); + DupString(entry->key, key); + DupString(entry->value, value); + entry->timestamp = timestamp; + entry->next = config_list; + config_list = entry; + result = CONFIG_CREATED; + } + + Debug((DEBUG_DEBUG, "Config %s: %s = %s (timestamp: %lu)", + (result == CONFIG_CHANGED) ? "changed" : + (result == CONFIG_TIMESTAMP) ? "timestamp updated" : "set", + key, value, (unsigned long)timestamp)); + + /* Call callbacks */ + config_call_callbacks(key, old_value, value); + + if (old_value) + MyFree(old_value); + + return result; +} + +/** Get a configuration value + * @param[in] key Configuration key + * @return Configuration value or NULL if not found + */ +const char *config_get(const char *key) +{ + struct ConfigEntry *entry; + + assert(key != NULL); + + entry = config_find(key); + return entry ? entry->value : NULL; +} + +/** Count the number of configuration entries + * @return Number of configuration entries + */ +static int config_count(void) +{ + struct ConfigEntry *entry; + int count = 0; + + for (entry = config_list; entry; entry = entry->next) + count++; + + return count; +} + +/** Register a callback for configuration changes + * @param[in] key_prefix Key prefix to match (e.g., "sasl.") + * @param[in] callback Callback function to call + */ +void config_register_callback(const char *key_prefix, config_callback_f callback) +{ + struct ConfigCallback *cb; + + assert(key_prefix != NULL); + assert(callback != NULL); + + /* Check if callback already exists */ + for (cb = callback_list; cb; cb = cb->next) { + if (ircd_strcmp(cb->key_prefix, key_prefix) == 0) { + cb->callback = callback; + return; + } + } + + /* Create new callback */ + cb = MyMalloc(sizeof(struct ConfigCallback)); + DupString(cb->key_prefix, key_prefix); + cb->callback = callback; + cb->next = callback_list; + callback_list = cb; + + Debug((DEBUG_DEBUG, "Config callback registered for prefix: %s", key_prefix)); +} + +/** Unregister a callback for configuration changes + * @param[in] key_prefix Key prefix that was registered + */ +void config_unregister_callback(const char *key_prefix) +{ + struct ConfigCallback *cb, *prev = NULL; + + assert(key_prefix != NULL); + + for (cb = callback_list; cb; prev = cb, cb = cb->next) { + if (ircd_strcmp(cb->key_prefix, key_prefix) == 0) { + if (prev) + prev->next = cb->next; + else + callback_list = cb->next; + + MyFree(cb->key_prefix); + MyFree(cb); + + Debug((DEBUG_DEBUG, "Config callback unregistered for prefix: %s", key_prefix)); + return; + } + } +} + +/** Burst all configuration entries to a newly connected server + * @param[in] cptr Server to send CF messages to + */ +void config_burst(struct Client *cptr) +{ + struct ConfigEntry *entry; + + for (entry = config_list; entry; entry = entry->next) { + sendcmdto_one(&me, CMD_CONFIG, cptr, "%Tu %s %s", + entry->timestamp, entry->key, entry->value); + } + + Debug((DEBUG_INFO, "Config burst: %d entries sent to %s", + config_count(), cli_name(cptr))); +} + +/** Generate configuration statistics for /STATS C + * @param[in] sptr Client requesting statistics + * @param[in] sd Stats descriptor (unused) + * @param[in] param Additional parameter (unused) + */ +void config_stats(struct Client *sptr, const struct StatDesc *sd, char *param) +{ + struct ConfigEntry *entry; + + for (entry = config_list; entry; entry = entry->next) { + send_reply(sptr, SND_EXPLICIT | RPL_STATSDEBUG, + "%Tu %s :%s", + entry->timestamp, entry->key, entry->value); + } +} + +/** Find a netconf description by key + * @param[in] key NetConf enum key + * @return NetConf description or NULL if not found + */ +static struct NetConfDesc *netconf_find(enum NetConf key) +{ + int i; + for (i = 0; netconf_descs[i].netconf != NETCONF_LAST_NC; i++) { + if (netconf_descs[i].netconf == key) + return &netconf_descs[i]; + } + return NULL; +} + +/** Get integer value of a configuration option with default + * @param[in] key NetConf enum key + * @return Integer value (from config or default) + */ +int netconf_int(enum NetConf key) +{ + struct NetConfDesc *desc = netconf_find(key); + const char *value; + + assert(desc != NULL); + assert((desc->flags & NETCONF_MASK) == NETCONF_INT); + + value = config_get(desc->type); + return value ? atoi(value) : desc->def_int; +} + +/** Get boolean value of a configuration option with default + * @param[in] key NetConf enum key + * @return Boolean value (0 or 1, from config or default) + */ +int netconf_bool(enum NetConf key) +{ + struct NetConfDesc *desc = netconf_find(key); + const char *value; + + assert(desc != NULL); + assert((desc->flags & NETCONF_MASK) == NETCONF_BOOL); + + value = config_get(desc->type); + if (!value) return desc->def_int; + + return (ircd_strcmp(value, "true") == 0 || + ircd_strcmp(value, "1") == 0 || + ircd_strcmp(value, "yes") == 0) ? 1 : 0; +} + +/** Get string value of a configuration option with default + * @param[in] key NetConf enum key + * @return String value (from config or default) + */ +const char *netconf_str(enum NetConf key) +{ + struct NetConfDesc *desc = netconf_find(key); + const char *value; + + assert(desc != NULL); + assert((desc->flags & NETCONF_MASK) == NETCONF_STR); + + value = config_get(desc->type); + return value ? value : desc->def_str; +} diff --git a/ircd/ircd_relay.c b/ircd/ircd_relay.c index e39e7dba..4867bc02 100644 --- a/ircd/ircd_relay.c +++ b/ircd/ircd_relay.c @@ -63,6 +63,7 @@ #include "s_misc.h" #include "s_user.h" #include "send.h" +#include "sline.h" /* #include -- Now using assert in ircd_log.h */ #include @@ -129,6 +130,10 @@ void relay_channel_message(struct Client* sptr, const char* name, const char* te } } + if (sline_check_chanmsg(sptr, chptr, text, MSG_PRIVATE)) { + return; + } + RevealDelayedJoinIfNeeded(sptr, chptr); sendcmdto_channel_butone(sptr, CMD_PRIVATE, chptr, cli_from(sptr), SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text); @@ -186,6 +191,10 @@ void relay_channel_notice(struct Client* sptr, const char* name, const char* tex } } + if (sline_check_chanmsg(sptr, chptr, text, MSG_NOTICE)) { + return; + } + RevealDelayedJoinIfNeeded(sptr, chptr); sendcmdto_channel_butone(sptr, CMD_NOTICE, chptr, cli_from(sptr), SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text); @@ -315,6 +324,10 @@ void relay_directed_message(struct Client* sptr, char* name, char* server, const return; } + if (sline_check_privmsg(sptr, acptr, text, MSG_PRIVATE)) { + return; + } + *server = '@'; if (host) *--host = '%'; @@ -387,6 +400,10 @@ void relay_directed_notice(struct Client* sptr, char* name, char* server, const return; } + if (sline_check_privmsg(sptr, acptr, text, MSG_NOTICE)) { + return; + } + *server = '@'; if (host) *--host = '%'; @@ -426,6 +443,10 @@ void relay_private_message(struct Client* sptr, const char* name, const char* te is_silenced(sptr, acptr)) return; + if (sline_check_privmsg(sptr, acptr, text, MSG_PRIVATE)) { + return; + } + /* * send away message if user away */ @@ -464,6 +485,11 @@ void relay_private_notice(struct Client* sptr, const char* name, const char* tex check_target_limit(sptr, acptr, NULL)) || is_silenced(sptr, acptr)) return; + + if (sline_check_privmsg(sptr, acptr, text, MSG_NOTICE)) { + return; + } + /* * deliver the message */ @@ -579,7 +605,7 @@ void relay_masked_message(struct Client* sptr, const char* mask, const char* tex sendcmdto_one(sptr, CMD_PRIVATE, cli_from(sptr), "%s :%s", mask, text); } - +//SPAM: Relevant here? /** Relay a masked notice from a local user. * Sends an error response if there is no top-level domain label in \a * mask, or if that TLD contains a wildcard. diff --git a/ircd/m_config.c b/ircd/m_config.c new file mode 100644 index 00000000..c9d9d3e3 --- /dev/null +++ b/ircd/m_config.c @@ -0,0 +1,94 @@ +/* + * IRC - Internet Relay Chat, ircd/m_config.c + * Copyright (C) 2025 MrIron + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" + +#include "client.h" +#include "ircd.h" +#include "ircd_alloc.h" +#include "ircd_netconf.h" +#include "ircd_reply.h" +#include "ircd_string.h" +#include "msg.h" +#include "numeric.h" +#include "numnicks.h" +#include "send.h" +#include "s_debug.h" + +#include + +/** Handler for server CONFIG messages + * @param[in] cptr Local client that sent us the message + * @param[in] sptr Original source of the message + * @param[in] parc Number of parameters + * @param[in] parv Parameter vector (source CF timestamp key value) + * @return 0 on success + */ +int ms_config(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) +{ + time_t timestamp; + const char *key, *value; + const char *old_value; + int result; + + if (parc < 4) + return need_more_params(sptr, "CF"); + + timestamp = atol(parv[1]); + key = parv[2]; + value = parv[3]; + + /* Get the old value for comparison */ + old_value = config_get(key); + char *old_value_copy = NULL; + if (old_value) + DupString(old_value_copy, old_value); + + /* Try to set the configuration */ + result = config_set(key, value, timestamp); + + if (result != CONFIG_REJECTED) { + /* Configuration was set or updated, propagate to other servers */ + sendcmdto_serv_butone(sptr, CMD_CONFIG, cptr, "%Tu %s :%s", + timestamp, key, value); + + /* Send notification to operators based on what actually happened */ + if (result == CONFIG_CREATED) { + sendto_opmask_butone(0, SNO_NETWORK, + "Network configuration set: %s = %s", + key, value); + } else if (result == CONFIG_CHANGED) { + sendto_opmask_butone(0, SNO_NETWORK, + "Network configuration updated: %s = %s (was: %s)", + key, value, old_value_copy ? old_value_copy : "(unset)"); + } + + Debug((DEBUG_DEBUG, "NETCONF: %s set %s = %s (timestamp: %Tu)", + cli_name(sptr), key, value, timestamp)); + } + + /* Clean up the copied old value */ + if (old_value_copy) + MyFree(old_value_copy); + + return 0; +} diff --git a/ircd/m_part.c b/ircd/m_part.c index e5b69811..859caf32 100644 --- a/ircd/m_part.c +++ b/ircd/m_part.c @@ -91,6 +91,7 @@ #include "numeric.h" #include "numnicks.h" #include "send.h" +#include "sline.h" #include "s_user.h" /* #include -- Now using assert in ircd_log.h */ @@ -108,7 +109,7 @@ int m_part(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) struct Channel *chptr; struct Membership *member; struct JoinBuf parts; - int colors = 0; + int colors = 0, slined = 0; char *p = 0; char *name; @@ -133,6 +134,10 @@ int m_part(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) } } + /* Check if the part message matches any S-line patterns */ + if (sline_check_pattern_bool(parts.jb_comment, SLINE_PART)) + slined = 1; + /* scan through channel list */ for (name = ircd_strtok(&p, parv[1], ","); name; name = ircd_strtok(&p, 0, ",")) { @@ -154,15 +159,9 @@ int m_part(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) if (!member_can_send_to_channel(member, 0) || ((member->channel->mode.mode & MODE_NOCOLOR) && colors) + || (member->channel->mode.mode & MODE_NOPARTMSGS) + || slined || (IsDelayedTarget(member) && check_target_limit(sptr, NULL, chptr))) - { - flags |= CHFL_BANNED; - } - - if ((member->channel->mode.mode & MODE_NOCOLOR) && colors) - flags |= CHFL_BANNED; - - if (member->channel->mode.mode & MODE_NOPARTMSGS) flags |= CHFL_BANNED; if (IsDelayedJoin(member)) diff --git a/ircd/m_quit.c b/ircd/m_quit.c index dec6084f..912703b1 100644 --- a/ircd/m_quit.c +++ b/ircd/m_quit.c @@ -86,6 +86,7 @@ #include "ircd.h" #include "ircd_log.h" #include "ircd_string.h" +#include "sline.h" #include "struct.h" #include "s_misc.h" #include "s_user.h" @@ -102,17 +103,21 @@ */ int m_quit(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { - int delayed_targets = 0; + int delayed_targets = 0, slined = 0; assert(0 != cptr); assert(0 != sptr); assert(cptr == sptr); + /* Check if the quit message matches any S-line patterns */ + if (parc > 1 && sline_check_pattern_bool(parv[parc - 1], SLINE_QUIT)) + slined = 1; + if (cli_user(sptr)) { struct Membership* chan; for (chan = cli_user(sptr)->channel; chan; chan = chan->next_channel) { if (!IsZombie(chan) && !IsDelayedJoin(chan) && - (!member_can_send_to_channel(chan, 0) || chan->channel->mode.mode & MODE_NOPARTMSGS)) + (!member_can_send_to_channel(chan, 0) || chan->channel->mode.mode & MODE_NOPARTMSGS || slined)) return exit_client(cptr, sptr, sptr, "Signed off"); if (IsDelayedTarget(chan)) ++delayed_targets; diff --git a/ircd/m_rping.c b/ircd/m_rping.c index 1db4b239..29e61957 100644 --- a/ircd/m_rping.c +++ b/ircd/m_rping.c @@ -142,6 +142,13 @@ int ms_rping(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) return need_more_params(sptr, "RPING"); } if ((destination = FindNServer(parv[1]))) { + /* + * Store lag value. + */ + int timestamp = atoi(parv[3]); + if (timestamp > 0) + cli_serv(sptr)->lag = TStime() - timestamp; + /* * if it's not for me, pass it on */ diff --git a/ircd/m_sline.c b/ircd/m_sline.c new file mode 100644 index 00000000..f3079167 --- /dev/null +++ b/ircd/m_sline.c @@ -0,0 +1,203 @@ +/* + * IRC - Internet Relay Chat, ircd/m_sline.c + * Copyright (C) 2025 MrIron + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +/* + * m_functions execute protocol messages on this server: + * + * cptr is always NON-NULL, pointing to a *LOCAL* client + * structure (with an open socket connected!). This + * identifies the physical socket where the message + * originated (or which caused the m_function to be + * executed--some m_functions may call others...). + * + * sptr is the source of the message, defined by the + * prefix part of the message if present. If not + * or prefix not found, then sptr==cptr. + * + * (!IsServer(cptr)) => (cptr == sptr), because + * prefixes are taken *only* from servers... + * + * (IsServer(cptr)) + * (sptr == cptr) => the message didn't + * have the prefix. + * + * (sptr != cptr && IsServer(sptr) means + * the prefix specified servername. (?) + * + * (sptr != cptr && !IsServer(sptr) means + * that message originated from a remote + * user (not local). + * + * combining + * + * (!IsServer(sptr)) means that, sptr can safely + * taken as defining the target structure of the + * message in this server. + * + * *Always* true (if 'parse' and others are working correct): + * + * 1) sptr->from == cptr (note: cptr->from == cptr) + * + * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr + * *cannot* be a local connection, unless it's + * actually cptr!). [MyConnect(x) should probably + * be defined as (x == x->from) --msa ] + * + * parc number of variable parameter strings (if zero, + * parv is allowed to be NULL) + * + * parv a NULL terminated list of parameter pointers, + * + * parv[0], sender (prefix string), if not present + * this points to an empty string. + * parv[1]...parv[parc-1] + * pointers to additional parameters + * parv[parc] == NULL, *always* + * + * note: it is guaranteed that parv[0]..parv[parc-1] are all + * non-NULL pointers. + */ +#include "config.h" + +#include "client.h" +#include "sline.h" +#include "hash.h" +#include "ircd.h" +#include "ircd_features.h" +#include "ircd_log.h" +#include "ircd_reply.h" +#include "ircd_string.h" +#include "ircd_snprintf.h" +#include "match.h" +#include "msg.h" +#include "numeric.h" +#include "numnicks.h" +#include "s_conf.h" +#include "s_debug.h" +#include "s_misc.h" +#include "send.h" + +/* #include -- Now using assert in ircd_log.h */ +#include +#include + +/* + * ms_sline - server message handler + * + * * parv[0] = Sender prefix + * * parv[1] = (+ or -) (activate or deactivate) + * * parv[2] = last modified timestamp + * * parv[3] = expiration timestamp (0 = never) + * * parv[4] = type (A/P/C/L/Q) + * * parv[5] = pattern + * + */ +int +ms_sline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) +{ + struct Sline *asline = 0; + sl_msgtype_t msgtype = 0; + time_t lastmod = 0, expire = 0; + char *state = NULL, *pattern = NULL, *type = NULL; + + if (parc < 5) + return need_more_params(sptr, "SLINE"); + + state = parv[1]; + lastmod = atoi(parv[2]) == 0 ? TStime() : atoi(parv[2]); + expire = atoi(parv[3]); + type = parv[4]; + pattern = parv[5]; + + if (*state != '+' && *state != '-') + return protocol_violation(sptr, "Invalid SLINE action, expected '+' or '-'"); + + /* Check if the pattern is valid */ + if (!pattern || strlen(pattern) == 0) + return protocol_violation(sptr, "Invalid SLINE pattern"); + + /* Parse type flags */ + for (int i = 0; type[i] != '\0'; i++) { + if (type[i] == 'A') { + msgtype |= SLINE_ALL; + break; /* A overrides everything */ + } else if (type[i] == 'P') { + msgtype |= SLINE_PRIVATE; + } else if (type[i] == 'C') { + msgtype |= SLINE_CHANNEL; + } else if (type[i] == 'L') { + msgtype |= SLINE_PART; + } else if (type[i] == 'Q') { + msgtype |= SLINE_QUIT; + } else { + // If we are adding other types later, we could perhaps propagate unknown types but avoid adding them ourself. + return protocol_violation(sptr, "Invalid SLINE type '%c', expected 'A', 'P', 'C', 'L', or 'Q'", type[i]); + } + } + + /* Check if S-line already exists with the exact same pattern */ + asline = sline_find(pattern); + if (asline) { + unsigned int updates = 0; + + /* If we have a newer last modified timestamp, we ignore. */ + if (asline->sl_lastmod >= lastmod) { + Debug((DEBUG_DEBUG, "S-line already exists with newer or equal timestamp, ignoring")); + return 0; + } + + /* Check whether there is a state update. */ + if ((*state == '+' && !(asline->sl_flags & SLINE_ACTIVE)) || + (*state == '-' && (asline->sl_flags & SLINE_ACTIVE))) { + updates |= SLINE_STATE; + } + + /* Check whether there is a message type update. */ + if (asline->sl_msgtype != msgtype) { + updates |= SLINE_MSGTYPE; + } + + /* Check whether the expire time has updated. */ + if (asline->sl_expire != expire) { + updates |= SLINE_EXPIRE; + } + + /* If there is no updates, we ignore. */ + if (updates == 0) { + Debug((DEBUG_DEBUG, "S-line already exists with same state, msgtype and expire time, ignoring")); + return 0; + } + + /* Modify S:line record. */ + sline_modify(sptr, asline, lastmod, expire, msgtype, *state == '+' ? SLINE_ACTIVE : 0, updates); + } else { + sline_add(cptr, sptr, pattern, lastmod, expire, msgtype, *state == '+' ? SLINE_ACTIVE : 0); + } + + /* Propagate. */ + sendcmdto_serv_butone(sptr, CMD_SLINE, cptr, "%c %Tu %Tu %s :%s", + *state, lastmod, expire, sline_flags_to_string(msgtype), pattern); + + return 1; +} \ No newline at end of file diff --git a/ircd/m_wallchops.c b/ircd/m_wallchops.c index 6dbc93d2..1af69e17 100644 --- a/ircd/m_wallchops.c +++ b/ircd/m_wallchops.c @@ -93,6 +93,7 @@ #include "numnicks.h" #include "s_user.h" #include "send.h" +#include "sline.h" /* #include -- Now using assert in ircd_log.h */ @@ -119,6 +120,11 @@ int m_wallchops(struct Client* cptr, struct Client* sptr, int parc, char* parv[] if ((chptr->mode.mode & MODE_NOPRIVMSGS) && check_target_limit(sptr, NULL, chptr)) return 0; + + if (sline_check_chanmsg(sptr, chptr, parv[parc - 1], MSG_WALLCHOPS)) { + return 0; + } + RevealDelayedJoinIfNeeded(sptr, chptr); sendcmdto_channel_butone(sptr, CMD_WALLCHOPS, chptr, cptr, SKIP_DEAF | SKIP_BURST | SKIP_NONOPS, diff --git a/ircd/m_wallvoices.c b/ircd/m_wallvoices.c index bb2f04db..8beca05b 100644 --- a/ircd/m_wallvoices.c +++ b/ircd/m_wallvoices.c @@ -92,6 +92,7 @@ #include "numnicks.h" #include "s_user.h" #include "send.h" +#include "sline.h" /* #include -- Now using assert in ircd_log.h */ @@ -118,6 +119,10 @@ int m_wallvoices(struct Client* cptr, struct Client* sptr, int parc, char* parv[ if ((chptr->mode.mode & MODE_NOPRIVMSGS) && check_target_limit(sptr, NULL, chptr)) return 0; + + if (sline_check_chanmsg(sptr, chptr, parv[parc - 1], MSG_WALLVOICES)) + return 0; + RevealDelayedJoinIfNeeded(sptr, chptr); sendcmdto_channel_butone(sptr, CMD_WALLVOICES, chptr, cptr, SKIP_DEAF | SKIP_BURST | SKIP_NONVOICES, diff --git a/ircd/m_xreply.c b/ircd/m_xreply.c index f4323d97..f65a5e50 100644 --- a/ircd/m_xreply.c +++ b/ircd/m_xreply.c @@ -90,6 +90,7 @@ #include "numnicks.h" #include "s_auth.h" #include "send.h" +#include "sline.h" #include @@ -129,6 +130,8 @@ int ms_xreply(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) /* OK, figure out where to route the message */ if (!ircd_strncmp("iauth:", routing, 6)) auth_send_xreply(sptr, routing + 6, reply); + else if (!ircd_strncmp("spam:", routing, 5)) + sline_xreply_handler(sptr, routing + 5, reply); else /* If we don't know where to route it, log it and drop it */ log_write(LS_SYSTEM, L_NOTICE, 0, "Received unroutable extension reply " diff --git a/ircd/parse.c b/ircd/parse.c index cfc78ca3..698da54a 100644 --- a/ircd/parse.c +++ b/ircd/parse.c @@ -498,6 +498,13 @@ struct Message msgtab[] = { /* UNREG, CLIENT, SERVER, OPER, SERVICE */ { m_unregistered, m_gline, ms_gline, mo_gline, m_ignore } }, + { + MSG_SLINE, + TOK_SLINE, + 0, MAXPARA, 0, 0, NULL, + /* UNREG, CLIENT, SERVER, OPER, SERVICE */ + { m_unregistered, m_ignore, ms_sline, m_ignore, m_ignore } + }, { MSG_JUPE, TOK_JUPE, @@ -658,6 +665,13 @@ struct Message msgtab[] = { /* UNREG, CLIENT, SERVER, OPER, SERVICE */ { m_quit, m_ignore, m_ignore, m_ignore, m_ignore } }, + { + MSG_CONFIG, + TOK_CONFIG, + 0, MAXPARA, 0, 0, NULL, + /* UNREG, CLIENT, SERVER, OPER, SERVICE */ + { m_ignore, m_ignore, ms_config, m_ignore, m_ignore } + }, { 0 } }; diff --git a/ircd/s_err.c b/ircd/s_err.c index 3390ce12..bef17a60 100644 --- a/ircd/s_err.c +++ b/ircd/s_err.c @@ -512,7 +512,7 @@ static Numeric replyTable[] = { /* 239 */ { 0 }, /* 240 */ - { 0 }, + { RPL_STATSSLINE, "%Tu %Tu %d %s :%s", "240" }, /* 241 */ { RPL_STATSLLINE, "Module Description EntryPoint", "241" }, /* 242 */ diff --git a/ircd/s_misc.c b/ircd/s_misc.c index a6a0cff3..65aec544 100644 --- a/ircd/s_misc.c +++ b/ircd/s_misc.c @@ -53,6 +53,7 @@ #include "s_stats.h" #include "s_user.h" #include "send.h" +#include "sline.h" #include "struct.h" #include "sys.h" #include "uping.h" @@ -228,6 +229,10 @@ static void exit_one_client(struct Client* bcptr, const char* comment) if (MyUser(bcptr)) set_snomask(bcptr, ~0, SNO_DEL); + /* Clean up S-line hold queue entries */ + if (IsSpamHold(bcptr)) + sline_cleanup_client(bcptr); + if (IsInvisible(bcptr)) { assert(UserStats.inv_clients > 0); --UserStats.inv_clients; diff --git a/ircd/s_serv.c b/ircd/s_serv.c index 2969808b..2022e4d3 100644 --- a/ircd/s_serv.c +++ b/ircd/s_serv.c @@ -31,10 +31,12 @@ #include "channel.h" #include "client.h" #include "gline.h" +#include "sline.h" #include "hash.h" #include "ircd.h" #include "ircd_alloc.h" #include "ircd_log.h" +#include "ircd_netconf.h" #include "ircd_reply.h" #include "ircd_string.h" #include "ircd_snprintf.h" @@ -196,6 +198,10 @@ int server_estab(struct Client *cptr, struct ConfItem *aconf) */ gline_burst(cptr); jupe_burst(cptr); + sline_burst(cptr); + + /* Burst server configuration. */ + config_burst(cptr); /* * Pass on my client information to the new server diff --git a/ircd/s_stats.c b/ircd/s_stats.c index 07ddf9cb..efbb8c15 100644 --- a/ircd/s_stats.c +++ b/ircd/s_stats.c @@ -25,8 +25,10 @@ #include "client.h" #include "gline.h" #include "hash.h" +#include "sline.h" #include "ircd.h" #include "ircd_chattr.h" +#include "ircd_netconf.h" #include "ircd_events.h" #include "ircd_features.h" #include "ircd_crypt.h" @@ -532,6 +534,7 @@ stats_meminfo(struct Client* to, const struct StatDesc* sd, char* param) class_send_meminfo(to); bans_send_meminfo(to); + sline_send_meminfo(to); send_listinfo(to, 0); } @@ -558,9 +561,12 @@ struct StatDesc statsinfo[] = { { 'a', "nameservers", STAT_FLAG_OPERFEAT|STAT_FLAG_LOCONLY, FEAT_HIS_STATS_a, report_dns_servers, 0, "DNS servers." }, - { 'c', "connect", STAT_FLAG_OPERFEAT, FEAT_HIS_STATS_c, + { 'c', "connect", (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_c, stats_configured_links, CONF_SERVER, "Remote server connection lines." }, + { 'C', "config", (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_C, + config_stats, 0, + "Network configuration entries." }, { 'd', "maskrules", (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_d, stats_crule_list, CRULE_MASK, "Dynamic routing configuration." }, @@ -619,6 +625,9 @@ struct StatDesc statsinfo[] = { send_usage, 0, "System resource usage (Debug only)." }, #endif + { 's', "slines", STAT_FLAG_OPERFEAT, FEAT_HIS_STATS_s, + sline_stats, 0, + "Regex pattern bans (S-lines)." }, { 'T', "motds", (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_T, motd_report, 0, "Configured Message Of The Day files." }, diff --git a/ircd/sline.c b/ircd/sline.c new file mode 100644 index 00000000..fbf273b9 --- /dev/null +++ b/ircd/sline.c @@ -0,0 +1,1326 @@ +/* + * IRC - Internet Relay Chat, ircd/sline.c + * Copyright (C) 2025 MrIron + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "config.h" + +#include "channel.h" +#include "client.h" +#include "hash.h" +#include "ircd.h" +#include "ircd_alloc.h" +#include "ircd_events.h" +#include "ircd_features.h" +#include "ircd_log.h" +#include "ircd_netconf.h" +#include "ircd_reply.h" +#include "ircd_snprintf.h" +#include "ircd_string.h" +#include "match.h" +#include "msg.h" +#include "numeric.h" +#include "numnicks.h" +#include "s_debug.h" +#include "s_stats.h" +#include "s_user.h" +#include "send.h" +#include "sline.h" +#include "struct.h" +#include "sys.h" + +/* #include -- Now using assert in ircd_log.h */ +#include +#include +#include +#include + +/** List of S-lines. */ +struct Sline* GlobalSlineList = 0; + +/** Hold queue entry structure */ +struct HoldQueueEntry { + struct HoldQueueEntry *next; /**< Next entry in queue */ + struct HoldQueueEntry **prev_p; /**< Previous pointer to this entry */ + unsigned int token; /**< Unique token for this entry */ + sl_msgtype_t msgtype; /**< Type of message (SLINE_PRIVATE, SLINE_CHANNEL) */ + const char *cmdtype; /**< Type of command (MSG_PRIVATE, MSG_NOTICE, MSG_WALLCHOPS, MSG_WALLVOICES) */ + struct Client *sender; /**< Sender of the message */ + union { + struct Client *recipient; /**< Recipient for private messages */ + struct Channel *channel; /**< Channel for channel messages */ + } target; + char *text; /**< Message text */ + char *captures; /**< S-line regex captures */ + time_t timestamp; /**< When message was held */ +}; + +/** Global hold queue list */ +static struct HoldQueueEntry *GlobalHoldQueue = 0; + +/** Next available token number */ +static uint64_t next_hold_token = 1; + +/** Statistics counters for S-line operations */ +static struct { + unsigned int sline_hits; /**< Number of times S-lines matched messages */ + unsigned int messages_held; /**< Total number of messages held */ + unsigned int messages_released; /**< Number of messages released (XREPLY YES) */ + unsigned int messages_blocked; /**< Number of messages blocked (XREPLY NO + timeout) */ + unsigned int xreply_accepted; /**< Number of XREPLY YES responses */ + unsigned int xreply_rejected; /**< Number of XREPLY NO responses */ + unsigned int timeout_expired; /**< Number of messages expired due to timeout */ +} sline_stats_counters = { 0, 0, 0, 0, 0, 0, 0 }; + +/** Timer for checking expired hold queue entries */ +static struct Timer hold_timeout_timer; + +/** Forward declaration for timer callback */ +static void sline_hold_timeout_callback(struct Event* ev); + +/** Check if S-lines are active based on features and netconf settings. + * @return 1 if S-lines are active, 0 if disabled. + */ +static int sline_is_enabled(void) +{ + /* Check if S-lines are disabled by feature */ + if (feature_bool(FEAT_DISABLE_SLINES)) + return 0; + + /* Check if S-line server is configured */ + const char *spamfilter_server = netconf_str(NETCONF_SLINE_SERVER); + if (!spamfilter_server || *spamfilter_server == '\0') + return 0; + + return 1; +} + +/** Create an Sline structure. + * @param[in] pattern Regex pattern to match against messages. + * @param[in] lastmod Last modification timestamp. + * @param[in] flags Bitwise combination of SLINE_* bits. + * @return Newly allocated S-line. + */ +static struct Sline * +make_sline(char *pattern, time_t lastmod, time_t expire, sl_msgtype_t msgtype, sl_flagtype_t flags) +{ + assert(pattern); + + struct Sline *sline; + + sline = (struct Sline *)MyMalloc(sizeof(struct Sline)); + assert(0 != sline); + + DupString(sline->sl_pattern, pattern); + sline->sl_lastmod = lastmod > 0 ? lastmod : TStime(); + sline->sl_expire = expire; + sline->sl_msgtype = msgtype; + sline->sl_count = 0; + sline->sl_flags = flags; + + /* Precompile the regex at creation time; invalid patterns are accepted but marked invalid */ + { + int ret = regcomp(&sline->sl_regex, sline->sl_pattern, REG_EXTENDED); + if (ret == 0) { + Debug((DEBUG_DEBUG, "make_sline: compiled regex for pattern '%s'", sline->sl_pattern)); + } else { + sline->sl_flags |= SLINE_INVALID; + Debug((DEBUG_DEBUG, "make_sline: failed to compile regex for pattern '%s'", sline->sl_pattern)); + } + } + + sline->sl_next = GlobalSlineList; /* then link it into list */ + sline->sl_prev_p = &GlobalSlineList; + if (GlobalSlineList) + GlobalSlineList->sl_prev_p = &sline->sl_next; + GlobalSlineList = sline; + + return sline; +} + +/** Create a new S-line and add it to global lists. + * @param[in] cptr Client that sent us the S-line. + * @param[in] sptr Client that originated the S-line. + * @param[in] pattern Regex pattern to match against messages. + * @param[in] lastmod Last modification time of S-line. + * @param[in] msgtype Bitwise combination of SLINE_* flags. + * @return Zero. + */ +int +sline_add(struct Client *cptr, struct Client *sptr, char *pattern, + time_t lastmod, time_t expire, sl_msgtype_t msgtype, sl_flagtype_t flags) +{ + assert(pattern); + assert(cptr); + assert(sptr); + + struct Sline *asline; + + assert(0 != pattern); + + Debug((DEBUG_DEBUG, "sline_add(\"%s\", \"%s\", \"%s\", %Tu, %Tu, 0x%04x, 0x%04x)", + cli_name(cptr), cli_name(sptr), pattern, lastmod, expire, msgtype, flags)); + + /* Check pattern length */ + if (strlen(pattern) >= SLINELEN) + return send_reply(sptr, ERR_LONGMASK); + + /* make the sline */ + asline = make_sline(pattern, lastmod, expire, msgtype, flags); + assert(asline); + + /* Inform ops... */ + sendto_opmask_butone(0, SNO_GLINE, "%s adding SLINE for pattern \"%s\" (%s) expiring at %Tu", + cli_name(sptr), pattern, + asline->sl_flags & SLINE_INVALID ? "I" : sline_flags_to_string(msgtype), expire); + + /* and log it */ + log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE, + "%#C adding SLINE for pattern \"%s\" (%s)", sptr, + pattern, + asline->sl_flags & SLINE_INVALID ? "I" : sline_flags_to_string(msgtype)); + + Debug((DEBUG_DEBUG, "S-line added successfully: pattern=%s, msgtype=0x%04x, lastmod=%Tu, expire=%Tu, flags=0x%04x", + asline->sl_pattern, asline->sl_msgtype, asline->sl_lastmod, asline->sl_expire, asline->sl_flags)); + + return 0; +} + +void sline_modify(struct Client *sptr, struct Sline *sline, time_t lastmod, time_t expire, sl_msgtype_t msgtype, sl_flagtype_t flags, unsigned int updates) +{ + assert(sline); + + const char *buf; + char text_extra[128] = ""; + char text_msgtype[40] = ""; + + sline->sl_lastmod = lastmod; + + if (updates & SLINE_STATE) { + if (flags & SLINE_ACTIVE) { + sline->sl_flags |= SLINE_ACTIVE; + } else { + sline->sl_flags &= ~SLINE_ACTIVE; + } + buf = (sline->sl_flags & SLINE_ACTIVE) ? "activating" : "deactivating"; + } else { + buf = "updating"; + } + + if (updates & SLINE_EXPIRE) { + sline->sl_expire = expire; + ircd_snprintf(0, text_extra, sizeof(text_extra), " changing expire time to %Tu", expire); + } else if (sline->sl_flags & SLINE_ACTIVE && sline->sl_expire > 0) { + ircd_snprintf(0, text_extra, sizeof(text_extra), " expiring at %Tu", sline->sl_expire); + } + + if (updates & SLINE_MSGTYPE) { + char old_type[16], new_type[16]; + strncpy(old_type, sline_flags_to_string(sline->sl_msgtype), sizeof(old_type)); + old_type[sizeof(old_type) - 1] = '\0'; + strncpy(new_type, sline_flags_to_string(msgtype), sizeof(new_type)); + new_type[sizeof(new_type) - 1] = '\0'; + ircd_snprintf(0, text_msgtype, sizeof(text_msgtype), "%s -> %s", old_type, new_type); + sline->sl_msgtype = msgtype; + } else { + ircd_snprintf(0, text_msgtype, sizeof(text_msgtype), "%s", sline_flags_to_string(sline->sl_msgtype)); + } + + sendto_opmask_butone(0, SNO_GLINE, "%C %s SLINE for pattern \"%s\" (%s)%s", + sptr, buf, sline->sl_pattern, + text_msgtype, text_extra); + + log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE, + "%#C %s SLINE for pattern \"%s\" (%s)%s", + sptr, buf, sline->sl_pattern, + text_msgtype, text_extra); + + Debug((DEBUG_DEBUG, "S-line modified successfully: pattern=%s, msgtype=0x%04x, lastmod=%Tu, expire=%Tu, flags=0x%04x", + sline->sl_pattern, sline->sl_msgtype, sline->sl_lastmod, sline->sl_expire, sline->sl_flags)); +} + +/** Find an S-line for a particular pattern, guided by certain flags. + * @param[in] pattern Pattern to search for. + * @return First matching S-line, or NULL if none are found. + */ +struct Sline * +sline_find(char *pattern) +{ + struct Sline *sline; + + for (sline = GlobalSlineList; sline; sline = sline->sl_next) { + if (ircd_strcmp(sline->sl_pattern, pattern) == 0) + return sline; + } + + return 0; +} + +/** Delink and free an S-line. + * @param[in] sline S-line to free. + */ +static void +sline_free(struct Sline *sline) +{ + assert(0 != sline); + + *sline->sl_prev_p = sline->sl_next; /* squeeze this sline out */ + if (sline->sl_next) + sline->sl_next->sl_prev_p = sline->sl_prev_p; + + /* Free compiled regex if present */ + if (sline->sl_flags & SLINE_INVALID) { + regfree(&sline->sl_regex); + sline->sl_flags &= ~SLINE_INVALID; + } + + MyFree(sline->sl_pattern); /* free up the memory */ + MyFree(sline); +} + +/** Convert S-line message type flags to a readable string. + * @param[in] msgtype Message type flags to convert. + * @return Static string buffer containing the flag representation. + */ +const char * +sline_flags_to_string(sl_msgtype_t msgtype) +{ + static char flag_str[16]; /* Buffer for flag string */ + int flag_pos = 0; + + /* Clear the buffer */ + memset(flag_str, 0, sizeof(flag_str)); + + /* Check for SLINE_ALL first */ + if (msgtype == SLINE_ALL) { + return "A"; + } + + /* Build individual flag string */ + if (msgtype & SLINE_PRIVATE) { + flag_str[flag_pos++] = 'P'; + } + if (msgtype & SLINE_CHANNEL) { + flag_str[flag_pos++] = 'C'; + } + if (msgtype & SLINE_PART) { + flag_str[flag_pos++] = 'L'; + } + if (msgtype & SLINE_QUIT) { + flag_str[flag_pos++] = 'Q'; + } + + /* If no flags were set, return "U" for unknown */ + if (flag_pos == 0) { + return "U"; + } + + /* Null terminate and return */ + flag_str[flag_pos] = '\0'; + return flag_str; +} + +/** Statistics callback to list S-lines. + * @param[in] sptr Client requesting statistics. + * @param[in] sd Stats descriptor for request (ignored). + * @param[in] param Pattern to filter reported S-lines. + */ +void +sline_stats(struct Client *sptr, const struct StatDesc *sd, + char *param) +{ + struct Sline *sline; + char type_str[32]; + int count = 0; + + for (sline = GlobalSlineList; sline; sline = sline->sl_next) { + if (!(sline->sl_flags & SLINE_ACTIVE)) { + /* Deactivated S-line, skip it */ + continue; + } + + /* Build type string */ + if (sline->sl_flags & SLINE_INVALID) + ircd_strncpy(type_str, "I", sizeof(type_str)); + else + ircd_strncpy(type_str, sline_flags_to_string(sline->sl_msgtype), sizeof(type_str)); + + send_reply(sptr, RPL_STATSSLINE, + sline->sl_lastmod, sline->sl_expire, sline->sl_count, type_str, + sline->sl_pattern); + count++; + } + + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S:line enabled: %s", sline_is_enabled() ? "yes" : "no"); + if (sline_is_enabled()) { + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "spamfilter server configured: %s", netconf_str(NETCONF_SLINE_SERVER)); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "hold timeout: %u", netconf_int(NETCONF_SLINE_HOLD_TIMEOUT)); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "hold timeout block: %s", netconf_bool(NETCONF_SLINE_HOLD_TIMEOUT_BLOCK) ? "yes" : "no"); + } + + /* Send summary statistics */ + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S :--- S-line Summary ---"); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S :S-line Hits: %u", sline_stats_counters.sline_hits); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S :Messages Held: %u", sline_stats_counters.messages_held); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S :Messages Released: %u", sline_stats_counters.messages_released); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S :Messages Blocked: %u", sline_stats_counters.messages_blocked); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S :XREPLY Accepted: %u", sline_stats_counters.xreply_accepted); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S :XREPLY Rejected: %u", sline_stats_counters.xreply_rejected); + send_reply(sptr, SND_EXPLICIT | RPL_STATSSLINE, + "S :Timeout Expired: %u", sline_stats_counters.timeout_expired); + + Debug((DEBUG_DEBUG, "sline_stats: found %d S-lines total", count)); +} + +/** Calculate memory used by S-lines. + * @param[out] sl_size Number of bytes used by S-lines. + * @return Number of S-lines in use. + */ +static int +sline_memory_count(size_t *sl_size) +{ + struct Sline *sline; + unsigned int sl = 0; + + for (sline = GlobalSlineList; sline; sline = sline->sl_next) { + sl++; + *sl_size += sizeof(struct Sline); + *sl_size += sline->sl_pattern ? (strlen(sline->sl_pattern) + 1) : 0; + } + + return sl; +} + +/** Report hold queue memory usage to a client. + * @param[in] sptr Client requesting memory information. + */ +void +sline_send_meminfo(struct Client* sptr) +{ + struct HoldQueueEntry *entry; + unsigned int hold_count = 0; + size_t hold_size = 0; + + /* Count hold queue entries and calculate memory usage */ + for (entry = GlobalHoldQueue; entry; entry = entry->next) { + hold_count++; + hold_size += sizeof(struct HoldQueueEntry); + if (entry->text) + hold_size += strlen(entry->text) + 1; + if (entry->captures) + hold_size += strlen(entry->captures) + 1; + } + + send_reply(sptr, SND_EXPLICIT | RPL_STATSDEBUG, + ":S-line hold queue: %u entries using %zu bytes", + hold_count, hold_size); +} + +/** Burst all known S-lines to another server. + * @param[in] cptr Destination of burst. + */ +void +sline_burst(struct Client *cptr) +{ + assert(cptr); + + struct Sline *sline, *next; + + for (sline = GlobalSlineList; sline; sline = next) { + next = sline->sl_next; + if (sline->sl_expire > 0 && sline->sl_expire < TStime()) { + sline_free(sline); + continue; + } + sendcmdto_one(&me, CMD_SLINE, cptr, "%c %Tu %Tu %s :%s", + sline->sl_flags & SLINE_ACTIVE ? '+' : '-', + sline->sl_lastmod, + sline->sl_expire, + sline_flags_to_string(sline->sl_msgtype), + sline->sl_pattern); + } +} + +/** Check if a string matches any S-line pattern and return captures. + * @param[in] text String to check against S-line patterns. + * @param[in] msg_type Message type flags (SLINE_PRIVATE, SLINE_CHANNEL, SLINE_ALL). + * @return Allocated string with captures if match found, NULL otherwise. + * Caller is responsible for freeing the returned string. + */ +static char * +sline_check_pattern(const char *text, sl_msgtype_t msg_type) +{ + struct Sline *sline; + regmatch_t matches[SLINE_MAX_CAPTURES]; /* Support up to 15 capture groups + full match */ + int ret; + char *result = NULL; + + if (!text) + return NULL; + + Debug((DEBUG_DEBUG, "sline_check_pattern: checking text='%s' against msg_type=0x%04x", text, msg_type)); + + struct Sline *next; + for (sline = GlobalSlineList; sline; sline = next) { + next = sline->sl_next; + if (sline->sl_expire > 0 && sline->sl_expire < TStime()) { + sline_free(sline); + continue; + } + + /* Check if this S-line is active and valid and applies to the message type */ + if (!(sline->sl_msgtype & msg_type) + || !(sline->sl_flags & SLINE_ACTIVE) + || (sline->sl_flags & SLINE_INVALID)) + continue; + + Debug((DEBUG_DEBUG, "sline_check_pattern: testing pattern '%s'", sline->sl_pattern)); + + /* Execute the regex match */ + ret = regexec(&sline->sl_regex, text, SLINE_MAX_CAPTURES, matches, 0); + if (ret == 0) { + /* Match found! Extract captures */ + Debug((DEBUG_DEBUG, "sline_check_pattern: pattern '%s' matched text '%s'", sline->sl_pattern, text)); + sline->sl_count++; /* Increment match count for this S-line */ + sline_stats_counters.sline_hits++; /* Increment global hit counter */ + + /* Calculate total length needed for all captures */ + int total_len = 0; + int num_captures = 0; + for (int i = 1; i < SLINE_MAX_CAPTURES && matches[i].rm_so != -1; i++) { + total_len += (matches[i].rm_eo - matches[i].rm_so) + 1; /* +1 for separator/null */ + num_captures++; + } + + if (num_captures > 0) { + /* Allocate result string */ + result = (char *)MyMalloc(total_len + 1); + result[0] = '\0'; + + /* Copy captures separated by spaces */ + for (int i = 1; i < SLINE_MAX_CAPTURES && matches[i].rm_so != -1; i++) { + if (i > 1) strcat(result, " "); + strncat(result, text + matches[i].rm_so, matches[i].rm_eo - matches[i].rm_so); + } + + Debug((DEBUG_DEBUG, "sline_check_pattern: extracted captures: '%s'", result)); + } else { + /* No captures, just return the full match */ + int match_len = matches[0].rm_eo - matches[0].rm_so; + result = (char *)MyMalloc(match_len + 1); + strncpy(result, text + matches[0].rm_so, match_len); + result[match_len] = '\0'; + + Debug((DEBUG_DEBUG, "sline_check_pattern: no captures, returning full match: '%s'", result)); + } + return result; + } + } + + Debug((DEBUG_DEBUG, "sline_check_pattern: no patterns matched")); + return NULL; +} + +/** Check if text matches any S-line patterns for a given message type. + * This is a boolean version that doesn't allocate memory. + * @param[in] text Text to check against S-line patterns. + * @param[in] msg_type Message type to check (SLINE_PRIVATE, SLINE_CHANNEL, etc.). + * @return 1 if text matches any S-line pattern, 0 otherwise. + */ +int +sline_check_pattern_bool(const char *text, sl_msgtype_t msg_type) +{ + struct Sline *sline, *next; + regmatch_t matches[SLINE_MAX_CAPTURES]; + + if (!text) + return 0; + + Debug((DEBUG_DEBUG, "sline_check_pattern_bool: checking text='%s' against msg_type=0x%04x", text, msg_type)); + + /* Check each S-line pattern */ + for (sline = GlobalSlineList; sline; sline = next) { + next = sline->sl_next; + if (sline->sl_expire > 0 && sline->sl_expire < TStime()) { + sline_free(sline); + continue; + } + + /* Check if this S-line is active and valid and applies to the message type */ + if (!(sline->sl_msgtype & msg_type) + || (sline->sl_expire > 0 && sline->sl_expire < TStime()) + || !(sline->sl_flags & SLINE_ACTIVE) + || (sline->sl_flags & SLINE_INVALID)) + continue; + + Debug((DEBUG_DEBUG, "sline_check_pattern_bool: testing pattern '%s'", sline->sl_pattern)); + + /* Execute the precompiled regex match */ + if (regexec(&sline->sl_regex, text, SLINE_MAX_CAPTURES, matches, 0) == 0) { + Debug((DEBUG_DEBUG, "sline_check_pattern_bool: pattern '%s' matched text '%s'", sline->sl_pattern, text)); + sline->sl_count++; /* Increment match count for this S-line */ + sline_stats_counters.sline_hits++; /* Increment global hit counter */ + return 1; /* Match found */ + } + } + + Debug((DEBUG_DEBUG, "sline_check_pattern_bool: no patterns matched")); + return 0; +} + +/** Send S-line match notification to the configured spam filter server. + * @param[in] entry Hold queue entry containing message and match information. + */ +static int +sline_notify_spamfilter(struct HoldQueueEntry *entry) +{ + assert(entry); + assert(entry->sender); + assert(entry->target.recipient || entry->target.channel); + assert(entry->msgtype == SLINE_PRIVATE || entry->msgtype == SLINE_CHANNEL); + + struct Client *acptr; + const char *target_name; + + if (!entry || !entry->sender) + return 0; + + /* Get target name based on message type */ + if (entry->msgtype == SLINE_PRIVATE && entry->target.recipient) + target_name = NumNick(entry->target.recipient); + else if (entry->msgtype == SLINE_CHANNEL && entry->target.channel) + target_name = entry->target.channel->chname; + else + return 0; + + Debug((DEBUG_DEBUG, "sline_notify_spamfilter: notifying about token %u from %s to %s", + entry->token, cli_name(entry->sender), target_name)); + + struct Client *serv = FindServer(netconf_str(NETCONF_SLINE_SERVER)); + if (!serv) { + Debug((DEBUG_DEBUG, "sline_notify_spamfilter: the spamfilter server is not available")); + return 0; + } + + Debug((DEBUG_DEBUG, "sline_notify_spamfilter: sending notification to spamfilter %s", cli_name(serv))); + + /* Send the S-line match notification to the nearest spam filter server + * Format: SL spam: : : + */ + if (entry->msgtype == SLINE_PRIVATE) { + sendcmdto_one(&me, CMD_XQUERY, serv, + "%C spam:%d :%C %C :%s", + serv, + entry->token, + entry->sender, + entry->target.recipient, + entry->captures ? entry->captures : ""); + } else { + sendcmdto_one(&me, CMD_XQUERY, serv, + "%C spam:%d :%C %H :%s", + serv, + entry->token, + entry->sender, + entry->target.channel, + entry->captures ? entry->captures : ""); + } + + return 1; +} + +/** Add a private message to the hold queue. + * @param[in] sender Client who sent the message. + * @param[in] recipient Client who should receive the message. + * @param[in] text Message text. + * @param[in] captures S-line regex captures (can be NULL). + * @param[in] cmd_type Message type (MSG_PRIVATE, MSG_NOTICE). + * @return Pointer to the created hold queue entry, or NULL on failure. + */ +static struct HoldQueueEntry * +sline_hold_privmsg(struct Client *sender, struct Client *recipient, + const char *text, const char *captures, const char* cmd_type) +{ + assert(sender); + assert(recipient); + + struct HoldQueueEntry *entry; + + if (!sender || !recipient || !text) + return NULL; + + Debug((DEBUG_DEBUG, "sline_hold_privmsg: holding %s from %s to %s: '%s'", + cmd_type, cli_name(sender), cli_name(recipient), text)); + + /* Allocate new hold queue entry */ + entry = (struct HoldQueueEntry *)MyMalloc(sizeof(struct HoldQueueEntry)); + if (!entry) + return NULL; + + /* Initialize entry */ + entry->token = next_hold_token++; + entry->msgtype = SLINE_PRIVATE; + entry->cmdtype = cmd_type; + entry->sender = sender; + entry->target.recipient = recipient; + entry->timestamp = TStime(); + + /* Mark both sender and recipient as having messages on hold */ + SetSpamHold(sender); + SetSpamHold(recipient); + + /* Duplicate strings */ + DupString(entry->text, text); + if (captures) + DupString(entry->captures, captures); + else + entry->captures = NULL; + + /* Add to global hold queue */ + entry->next = GlobalHoldQueue; + entry->prev_p = &GlobalHoldQueue; + if (GlobalHoldQueue) + GlobalHoldQueue->prev_p = &entry->next; + GlobalHoldQueue = entry; + + /* Update statistics */ + sline_stats_counters.messages_held++; + + Debug((DEBUG_DEBUG, "sline_hold_privmsg: assigned token %u", entry->token)); + return entry; +} + +/** Add a channel message to the hold queue. + * @param[in] sender Client who sent the message. + * @param[in] channel Channel where message was sent. + * @param[in] text Message text. + * @param[in] captures S-line regex captures (can be NULL). + * @param[in] cmd_type Type of command (MSG_PRIVATE, MSG_NOTICE, MSG_WALLCHOPS, MSG_WALLVOICES). + * @return Pointer to the created hold queue entry, or NULL on failure. + */ +static struct HoldQueueEntry * +sline_hold_chanmsg(struct Client *sender, struct Channel *channel, + const char *text, const char *captures, const char* cmd_type) +{ + assert(sender); + assert(channel); + + struct HoldQueueEntry *entry; + + if (!sender || !channel || !text) + return NULL; + + Debug((DEBUG_DEBUG, "sline_hold_chanmsg: holding %s from %s to %s: '%s'", + cmd_type, cli_name(sender), channel->chname, text)); + + /* Allocate new hold queue entry */ + entry = (struct HoldQueueEntry *)MyMalloc(sizeof(struct HoldQueueEntry)); + if (!entry) + return NULL; + + /* Initialize entry */ + entry->token = next_hold_token++; + entry->msgtype = SLINE_CHANNEL; + entry->cmdtype = cmd_type; + entry->sender = sender; + entry->target.channel = channel; + entry->timestamp = TStime(); + + /* Mark sender as having messages on hold */ + SetSpamHold(sender); + + /* Duplicate strings */ + DupString(entry->text, text); + if (captures) + DupString(entry->captures, captures); + else + entry->captures = NULL; + + /* Add to global hold queue */ + entry->next = GlobalHoldQueue; + entry->prev_p = &GlobalHoldQueue; + if (GlobalHoldQueue) + GlobalHoldQueue->prev_p = &entry->next; + GlobalHoldQueue = entry; + + /* Update statistics */ + sline_stats_counters.messages_held++; + + Debug((DEBUG_DEBUG, "sline_hold_chanmsg: assigned token %u", entry->token)); + return entry; +} + +/** Check if a client has any messages on hold and clear FLAG_SPAMHOLD if not. + * This is called when removing a hold queue entry to efficiently manage the flag. + * @param[in] cptr Client to check and potentially clear flag for. + */ +static void +sline_check_clear_spamhold(struct Client *cptr) +{ + assert(cptr); + + struct HoldQueueEntry *entry; + + if (!cptr || !IsSpamHold(cptr)) + return; + + /* Check if this client is referenced in any remaining hold queue entries */ + for (entry = GlobalHoldQueue; entry; entry = entry->next) { + if (entry->sender == cptr) + return; /* Still has messages on hold as sender */ + + if (entry->msgtype == SLINE_PRIVATE && + entry->target.recipient == cptr) + return; /* Still has messages on hold as recipient */ + } + + /* No more hold queue entries reference this client */ + ClearSpamHold(cptr); + Debug((DEBUG_DEBUG, "sline_check_clear_spamhold: cleared FLAG_SPAMHOLD for %s", cli_name(cptr))); +} + +/** Remove and free a hold queue entry. + * @param[in] entry Hold queue entry to remove. + */ +static void +sline_hold_free(struct HoldQueueEntry *entry) +{ + assert(entry); + + struct Client *sender, *recipient; + + if (!entry) + return; + + Debug((DEBUG_DEBUG, "sline_hold_free: removing token %u", entry->token)); + + /* Store references for FLAG_SPAMHOLD cleanup */ + sender = entry->sender; + recipient = NULL; + if (entry->msgtype == SLINE_PRIVATE) + recipient = entry->target.recipient; + + /* Remove from linked list */ + *entry->prev_p = entry->next; + if (entry->next) + entry->next->prev_p = entry->prev_p; + + /* Free allocated strings */ + MyFree(entry->text); + if (entry->captures) + MyFree(entry->captures); + + /* Free the entry itself */ + MyFree(entry); + + /* Check if FLAG_SPAMHOLD should be cleared for affected clients */ + if (sender) + sline_check_clear_spamhold(sender); + if (recipient) + sline_check_clear_spamhold(recipient); +} + +/** Helper function to check S-line and handle private messages. + * @param[in] sender Client who sent the message. + * @param[in] recipient Client who should receive the message. + * @param[in] text Message text to check against S-lines. + * @param[in] cmd_type Message type (MSG_PRIVATE, MSG_NOTICE). + * @return 1 if message was held (S-line matched), 0 if message should be delivered normally. + */ +int +sline_check_privmsg(struct Client *sender, struct Client *recipient, const char *text, const char* cmd_type) +{ + assert(sender); + assert(recipient); + assert(text); + + char *captures; + struct HoldQueueEntry *entry; + + if (!sender || !recipient || !text || IsAnOper(sender) || !sline_is_enabled()) + return 0; + + Debug((DEBUG_DEBUG, "sline_check_privmsg: checking %s from %s to %s: '%s'", + cmd_type, cli_name(sender), cli_name(recipient), text)); + + /* Check if message matches any S-line patterns for private messages */ + captures = sline_check_pattern(text, SLINE_PRIVATE); + if (!captures) { + Debug((DEBUG_DEBUG, "sline_check_privmsg: no S-line match, allowing message")); + return 0; /* No match, allow message to be delivered */ + } + + Debug((DEBUG_DEBUG, "sline_check_privmsg: S-line matched, captures: '%s'", captures)); + + /* S-line matched, add to hold queue */ + entry = sline_hold_privmsg(sender, recipient, text, captures, cmd_type); + if (!entry) { + Debug((DEBUG_DEBUG, "sline_check_privmsg: failed to add to hold queue")); + MyFree(captures); + return 0; /* Failed to hold, allow delivery */ + } + + /* Notify spam filter servers */ + sline_notify_spamfilter(entry); + + /* Clean up */ + MyFree(captures); + + Debug((DEBUG_DEBUG, "sline_check_privmsg: message held with token %u", entry->token)); + return 1; /* Message was held */ +} + +/** Helper function to check S-line and handle channel messages. + * @param[in] sender Client who sent the message. + * @param[in] channel Channel where message was sent. + * @param[in] text Message text to check against S-lines. + * @param[in] cmd_type Message type (MSG_PRIVATE, MSG_NOTICE, MSG_WALLCHOPS, MSG_WALLVOICES). + * @return 1 if message was held (S-line matched), 0 if message should be delivered normally. + */ +int +sline_check_chanmsg(struct Client *sender, struct Channel *channel, const char *text, const char* cmd_type) +{ + assert(sender); + assert(channel); + assert(text); + + char *captures; + struct HoldQueueEntry *entry; + + if (!sender || !channel || !text || IsAnOper(sender) || !sline_is_enabled()) + return 0; + + Debug((DEBUG_DEBUG, "sline_check_chanmsg: checking %s from %s to %s: '%s'", + cmd_type, cli_name(sender), channel->chname, text)); + + /* Check if message matches any S-line patterns for channel messages */ + captures = sline_check_pattern(text, SLINE_CHANNEL); + if (!captures) { + Debug((DEBUG_DEBUG, "sline_check_chanmsg: no S-line match, allowing message")); + return 0; /* No match, allow message to be delivered */ + } + + Debug((DEBUG_DEBUG, "sline_check_chanmsg: S-line matched, captures: '%s'", captures)); + + /* S-line matched, add to hold queue */ + entry = sline_hold_chanmsg(sender, channel, text, captures, cmd_type); + if (!entry) { + Debug((DEBUG_DEBUG, "sline_check_chanmsg: failed to add to hold queue")); + MyFree(captures); + return 0; /* Failed to hold, allow delivery */ + } + + /* Notify spam filter servers */ + sline_notify_spamfilter(entry); + + /* Clean up */ + MyFree(captures); + + Debug((DEBUG_DEBUG, "sline_check_chanmsg: message held with token %u", entry->token)); + return 1; /* Message was held */ +} + +/** Find a hold queue entry by token. + * @param[in] token Token to search for. + * @return Pointer to hold queue entry if found, NULL otherwise. + */ +static struct HoldQueueEntry * +sline_find_hold_entry(unsigned int token) +{ + struct HoldQueueEntry *entry; + + for (entry = GlobalHoldQueue; entry; entry = entry->next) { + if (entry->token == token) + return entry; + } + + return NULL; +} + +/** Release a private message from the hold queue and deliver it. + * @param[in] entry Hold queue entry to release. + * @return 1 if message was delivered, 0 if there was an error. + */ +static int +sline_release_privmsg(struct HoldQueueEntry *entry) +{ + assert(entry != NULL); + assert(entry->sender != NULL); + assert(entry->target.recipient != NULL); + assert(entry->text != NULL); + assert(entry->msgtype == SLINE_PRIVATE); + + if (!entry || entry->msgtype != SLINE_PRIVATE || !entry->sender || !entry->target.recipient || !entry->text) + return 0; + + Debug((DEBUG_DEBUG, "sline_release_privmsg: releasing token %u from %s to %s", + entry->token, cli_name(entry->sender), cli_name(entry->target.recipient))); + + /* Check if the sender and recipient are still valid */ + if (!IsUser(entry->sender) || !IsUser(entry->target.recipient)) { + Debug((DEBUG_DEBUG, "sline_release_privmsg: sender or recipient no longer valid")); + return 0; + } + + /* Check silence list */ + if (is_silenced(entry->sender, entry->target.recipient)) { + Debug((DEBUG_DEBUG, "sline_release_privmsg: sender is silenced by recipient")); + return 0; + } + + /* Send away message if user is away */ + if (cli_user(entry->target.recipient) && cli_user(entry->target.recipient)->away) + send_reply(entry->sender, RPL_AWAY, cli_name(entry->target.recipient), cli_user(entry->target.recipient)->away); + + /* Deliver the message */ + if (MyUser(entry->target.recipient)) + add_target(entry->target.recipient, entry->sender); + + sendcmdto_one(entry->sender, entry->cmdtype == MSG_NOTICE ? CMD_NOTICE : CMD_PRIVATE, entry->target.recipient, "%C :%s", entry->target.recipient, entry->text); + if (CapHas(cli_active(entry->sender), CAP_ECHOMESSAGE)) + sendcmdto_one(entry->sender, entry->cmdtype == MSG_NOTICE ? CMD_NOTICE : CMD_PRIVATE, cli_from(entry->sender), "%C :%s", entry->target.recipient, entry->text); + + Debug((DEBUG_DEBUG, "sline_release_privmsg: message delivered successfully")); + return 1; +} + +/** Release a channel message from the hold queue and deliver it. + * @param[in] entry Hold queue entry to release. + * @return 1 if message was delivered, 0 if there was an error. + */ +static int +sline_release_chanmsg(struct HoldQueueEntry *entry) +{ + assert(entry != NULL); + assert(entry->sender != NULL); + assert(entry->target.channel != NULL); + assert(entry->text != NULL); + assert(entry->msgtype == SLINE_CHANNEL); + + if (!entry || entry->msgtype != SLINE_CHANNEL || !entry->sender || !entry->target.channel || !entry->text) + return 0; + + Debug((DEBUG_DEBUG, "sline_release_chanmsg: releasing token %u from %s to %s", + entry->token, cli_name(entry->sender), entry->target.channel->chname)); + + /* Check if the sender and channel are still valid */ + if (!IsUser(entry->sender) || !entry->target.channel->chname) { + Debug((DEBUG_DEBUG, "sline_release_chanmsg: sender or channel no longer valid")); + return 0; + } + + /* Check if sender can still send to channel */ + if (!client_can_send_to_channel(entry->sender, entry->target.channel, 0)) { + Debug((DEBUG_DEBUG, "sline_release_chanmsg: sender can no longer send to channel")); + return 0; + } + + /* Reveal delayed join if needed */ + RevealDelayedJoinIfNeeded(entry->sender, entry->target.channel); + + /* Deliver the message */ + if (entry->cmdtype == MSG_NOTICE || entry->cmdtype == MSG_PRIVATE) { + sendcmdto_channel_butone(entry->sender, entry->cmdtype == MSG_NOTICE ? CMD_NOTICE : CMD_PRIVATE, + entry->target.channel, cli_from(entry->sender), + SKIP_DEAF | SKIP_BURST, "%H :%s", entry->target.channel, entry->text); + if (CapHas(cli_active(entry->sender), CAP_ECHOMESSAGE)) + sendcmdto_one(entry->sender, entry->cmdtype == MSG_NOTICE ? CMD_NOTICE : CMD_PRIVATE, + cli_from(entry->sender), "%H :%s", entry->target.channel, entry->text); + } else if (entry->cmdtype == MSG_WALLVOICES) { + sendcmdto_channel_butone(entry->sender, CMD_WALLVOICES, entry->target.channel, cli_from(entry->sender), + SKIP_DEAF | SKIP_BURST | SKIP_NONVOICES, + "%H :+ %s", entry->target.channel, entry->text); + if (CapHas(cli_active(entry->sender), CAP_ECHOMESSAGE)) + sendcmdto_one(entry->sender, CMD_NOTICE, cli_from(entry->sender), // Sending CMD_NOTICE since CMD_WALLVOICES is translated into CMD_NOTICE in sendcmdto_channel_butone() + "@%H :+ %s", entry->target.channel, entry->text); + } else if (entry->cmdtype == MSG_WALLCHOPS) { + sendcmdto_channel_butone(entry->sender, CMD_WALLCHOPS, entry->target.channel, cli_from(entry->sender), + SKIP_DEAF | SKIP_BURST | SKIP_NONOPS, + "%H :@ %s", entry->target.channel, entry->text); + if (CapHas(cli_active(entry->sender), CAP_ECHOMESSAGE)) + sendcmdto_one(entry->sender, CMD_NOTICE, cli_from(entry->sender), // Sending CMD_NOTICE since CMD_WALLCHOPS is translated into CMD_NOTICE in sendcmdto_channel_butone() + "@%H :@ %s", entry->target.channel, entry->text); + } + + Debug((DEBUG_DEBUG, "sline_release_chanmsg: message delivered successfully")); + return 1; +} + +/** Release a message from the hold queue by token. + * @param[in] token Token of the message to release. + * @return 1 if message was found and delivered, 0 otherwise. + */ +static int +sline_release_hold(unsigned int token) +{ + struct HoldQueueEntry *entry; + int result = 0; + + Debug((DEBUG_DEBUG, "sline_release_hold: attempting to release token %u", token)); + + entry = sline_find_hold_entry(token); + if (!entry) { + Debug((DEBUG_DEBUG, "sline_release_hold: token %u not found in hold queue", token)); + return 0; + } + + /* Release based on message type */ + if (entry->msgtype == SLINE_PRIVATE) { + result = sline_release_privmsg(entry); + } else if (entry->msgtype == SLINE_CHANNEL) { + result = sline_release_chanmsg(entry); + } else { + Debug((DEBUG_DEBUG, "sline_release_hold: unknown message type %d for token %u", entry->msgtype, token)); + } + + /* Remove from hold queue regardless of delivery result */ + sline_hold_free(entry); + + return result; +} + +/** Block a held message and send appropriate error to sender. + * @param[in] entry Hold queue entry to block. + */ +static void +sline_block_message(struct HoldQueueEntry *entry) +{ + assert(entry); + + if (!entry || !entry->sender || !IsUser(entry->sender)) + return; + + Debug((DEBUG_DEBUG, "sline_block_message: blocking token %u", entry->token)); + + /* Send error to sender based on message type */ + if (entry->msgtype == SLINE_PRIVATE) { + /* Private message - send ERR_NOSUCHNICK */ + if (entry->target.recipient) { + send_reply(entry->sender, ERR_NOSUCHNICK, cli_name(entry->target.recipient)); + Debug((DEBUG_DEBUG, "sline_block_message: sent ERR_NOSUCHNICK to %s for %s", + cli_name(entry->sender), cli_name(entry->target.recipient))); + } + } else if (entry->msgtype == SLINE_CHANNEL) { + /* Channel message - send ERR_CANNOTSENDTOCHAN */ + if (entry->target.channel) { + send_reply(entry->sender, ERR_CANNOTSENDTOCHAN, entry->target.channel->chname); + Debug((DEBUG_DEBUG, "sline_block_message: sent ERR_CANNOTSENDTOCHAN to %s for %s", + cli_name(entry->sender), entry->target.channel->chname)); + } + } +} + +/** Handle XREPLY response from spam filter servers. + * @param[in] sptr Client that sent the XREPLY. + * @param[in] token Token string of the held message. + * @param[in] reply Reply string - "YES" to release, "NO" to drop. + * @return 1 if message was found and processed, 0 otherwise. + */ +int +sline_xreply_handler(struct Client *sptr, const char *token, const char *reply) +{ + struct HoldQueueEntry *entry; + unsigned int token_num; + int should_release; + + if (!sptr || !token || !reply) { + Debug((DEBUG_DEBUG, "sline_xreply_handler: invalid parameters")); + return 0; + } + + /* Convert token string to number */ + token_num = atoi(token); + if (token_num == 0 && strcmp(token, "0") != 0) { + Debug((DEBUG_DEBUG, "sline_xreply_handler: invalid token '%s' from %s", token, cli_name(sptr))); + return 0; + } + + /* Determine action based on reply */ + if (ircd_strcmp(reply, "YES") == 0) { + should_release = 1; + sline_stats_counters.xreply_accepted++; /* Increment accepted counter */ + } else if (ircd_strcmp(reply, "NO") == 0) { + should_release = 0; + sline_stats_counters.xreply_rejected++; /* Increment rejected counter */ + } else { + Debug((DEBUG_DEBUG, "sline_xreply_handler: invalid reply '%s' from %s for token %u", reply, cli_name(sptr), token_num)); + return 0; + } + + Debug((DEBUG_DEBUG, "sline_xreply_handler: processing %s for token %u from %s", reply, token_num, cli_name(sptr))); + + /* Find the hold queue entry */ + entry = sline_find_hold_entry(token_num); + if (!entry) { + Debug((DEBUG_DEBUG, "sline_xreply_handler: token %u not found in hold queue", token_num)); + return 0; + } + + if (should_release) { + /* Release the message */ + Debug((DEBUG_DEBUG, "sline_xreply_handler: releasing token %u", token_num)); + sline_stats_counters.messages_released++; /* Increment released counter */ + if (sline_release_hold(token_num)) { + Debug((DEBUG_DEBUG, "sline_xreply_handler: successfully released token %u", token_num)); + } else { + Debug((DEBUG_DEBUG, "sline_xreply_handler: failed to release token %u", token_num)); + } + } else { + /* Drop the message and send appropriate error */ + Debug((DEBUG_DEBUG, "sline_xreply_handler: dropping token %u and sending error", token_num)); + sline_stats_counters.messages_blocked++; /* Increment blocked counter */ + + /* Block the message using helper function */ + sline_block_message(entry); + + /* Drop the message */ + sline_hold_free(entry); + } + + return 1; +} + +/** Clean up hold queue entries for a disconnecting client. + * This should be called when a client disconnects to remove any + * hold queue entries that reference that client. + * @param[in] cptr Client that is disconnecting. + */ +void +sline_cleanup_client(struct Client *cptr) +{ + assert(cptr); + + struct HoldQueueEntry *entry, *next_entry; + int cleaned = 0; + + Debug((DEBUG_DEBUG, "sline_cleanup_client: cleaning up hold queue for %s", cli_name(cptr))); + + for (entry = GlobalHoldQueue; entry; entry = next_entry) { + next_entry = entry->next; + + /* Check if this entry references the disconnecting client */ + if (entry->sender == cptr || + (entry->msgtype == SLINE_PRIVATE && entry->target.recipient == cptr)) { + + Debug((DEBUG_DEBUG, "sline_cleanup_client: removing hold entry token %u", entry->token)); + sline_hold_free(entry); + cleaned++; + } + } + + if (cleaned > 0) { + Debug((DEBUG_DEBUG, "sline_cleanup_client: cleaned %d hold queue entries for %s", cleaned, cli_name(cptr))); + } +} + +/** Clean up hold queue entries for a channel being destroyed. + * This should be called when a channel is destroyed to remove any + * hold queue entries that reference that channel. + * @param[in] chptr Channel that is being destroyed. + */ +void +sline_cleanup_channel(struct Channel *chptr) +{ + assert(chptr); + + struct HoldQueueEntry *entry, *next_entry; + int cleaned = 0; + + Debug((DEBUG_DEBUG, "sline_cleanup_channel: cleaning up hold queue for %s", chptr->chname)); + + for (entry = GlobalHoldQueue; entry; entry = next_entry) { + next_entry = entry->next; + + /* Check if this entry references the channel being destroyed */ + if (entry->msgtype == SLINE_CHANNEL && entry->target.channel == chptr) { + Debug((DEBUG_DEBUG, "sline_cleanup_channel: removing hold entry token %u", entry->token)); + sline_hold_free(entry); + cleaned++; + } + } + + if (cleaned > 0) { + Debug((DEBUG_DEBUG, "sline_cleanup_channel: cleaned %d hold queue entries for %s", cleaned, chptr->chname)); + } +} + +/** Timer callback to check and remove expired hold queue entries. + * @param[in] ev Event structure for the timer event. + */ +static void +sline_hold_timeout_callback(struct Event* ev) +{ + struct HoldQueueEntry *entry, *next_entry; + time_t current_time = TStime(); + + /* Iterate over hold queue and find expired entries */ + for (entry = GlobalHoldQueue; entry; entry = next_entry) { + next_entry = entry->next; + + /* Check if entry is expired */ + if (entry->timestamp + netconf_int(NETCONF_SLINE_HOLD_TIMEOUT) <= current_time) { + Debug((DEBUG_DEBUG, "sline_hold_timeout_callback: processing expired hold entry token %u", entry->token)); + + /* Increment timeout counter */ + sline_stats_counters.timeout_expired++; + + /* Check if we should block or release expired messages */ + if (netconf_bool(NETCONF_SLINE_HOLD_TIMEOUT_BLOCK)) { + /* Block the message (default behavior) - send timeout error to sender */ + Debug((DEBUG_DEBUG, "sline_hold_timeout_callback: blocking expired token %u", entry->token)); + sline_stats_counters.messages_blocked++; /* Increment blocked counter */ + + /* Block the message using helper function */ + sline_block_message(entry); + + /* Remove the entry */ + sline_hold_free(entry); + } else { + /* Release the message (allow it to be delivered) */ + Debug((DEBUG_DEBUG, "sline_hold_timeout_callback: releasing expired token %u", entry->token)); + sline_stats_counters.messages_released++; /* Increment released counter */ + + if (sline_release_hold(entry->token)) { + Debug((DEBUG_DEBUG, "sline_hold_timeout_callback: successfully released expired token %u", entry->token)); + } else { + Debug((DEBUG_DEBUG, "sline_hold_timeout_callback: failed to release expired token %u, removing entry", entry->token)); + sline_hold_free(entry); + } + } + } + } +} + +/** Initialize the S-line subsystem. + * This should be called during server initialization to start the + * hold queue timeout timer. + */ +void +sline_init(void) +{ + timer_add(timer_init(&hold_timeout_timer), sline_hold_timeout_callback, 0, TT_PERIODIC, 10); +} diff --git a/ircd/test/Makefile.in b/ircd/test/Makefile.in index 9831ecc0..388f1abb 100644 --- a/ircd/test/Makefile.in +++ b/ircd/test/Makefile.in @@ -70,7 +70,8 @@ ircd_in_addr_t.o: ircd_in_addr_t.c ../../include/ircd_log.h \ ../../include/numnicks.h ../../include/client.h \ ../../include/ircd_defs.h ../../include/dbuf.h ../../include/msgq.h \ ../../include/ircd_events.h ../../config.h ../../include/ircd_handler.h \ - ../../include/res.h ../../include/capab.h ../../include/res.h + ../../include/res.h ../../include/capab.h ../../include/ircd_features.h \ + ../../include/res.h ircd_match_t.o: ircd_match_t.c ../../include/ircd_log.h \ ../../include/match.h ../../include/res.h ../../config.h ircd_string_t.o: ircd_string_t.c ../../include/ircd_string.h \ @@ -78,4 +79,5 @@ ircd_string_t.o: ircd_string_t.c ../../include/ircd_string.h \ test_stub.o: test_stub.c ../../include/client.h ../../include/ircd_defs.h \ ../../include/dbuf.h ../../include/msgq.h ../../include/ircd_events.h \ ../../config.h ../../include/ircd_handler.h ../../include/res.h \ - ../../include/capab.h ../../include/ircd_log.h ../../include/s_debug.h + ../../include/capab.h ../../include/ircd_features.h \ + ../../include/ircd_log.h ../../include/s_debug.h