From: Bleep Date: Tue, 19 Sep 2000 05:41:48 +0000 (+0000) Subject: Author: Bleep X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=commitdiff_plain;h=8927a39c968bc739ebb61ff972a7fe0c375930a1 Author: Bleep Log message: Moved K:lines to new data structures and list, fixup affected code, rework stats code a bit to report them correctly. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@295 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- diff --git a/ChangeLog b/ChangeLog index 1bc9ff4..76d9b47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2000-09-19 Thomas Helvey + * ircd/s_conf.c: move K:lines to their own list and data + structures, add supporting code. + * ircd/m_stats.c: cleanup stats processing a bit move + kline listing code to a new function, haven't figured + out where it goes yet tho' + * ircd/s_stats.c: added K:line bulk lister + * include/s_conf.h: added new DenyConf struct + * *[ch]: fixeup code that depended on changes + 2000-09-17 Thomas Helvey * ircd/class.c: encapsulate class list * include/class.h: clean up classes diff --git a/include/class.h b/include/class.h index fa76495..a7b2519 100644 --- a/include/class.h +++ b/include/class.h @@ -33,32 +33,33 @@ struct ConfItem; * Structures */ struct ConnectionClass { - unsigned int conClass; - unsigned int conFreq; - unsigned int pingFreq; - unsigned int maxLinks; - unsigned int maxSendq; - unsigned int links; - struct ConnectionClass *next; + struct ConnectionClass* next; + int cc_class; + unsigned int max_sendq; + short ping_freq; + short conn_freq; + short max_links; + unsigned char valid; + int ref_count; }; /* * Macro's */ -#define ConClass(x) ((x)->conClass) -#define ConFreq(x) ((x)->conFreq) -#define PingFreq(x) ((x)->pingFreq) -#define MaxLinks(x) ((x)->maxLinks) -#define MaxSendq(x) ((x)->maxSendq) -#define Links(x) ((x)->links) +#define ConClass(x) ((x)->cc_class) +#define PingFreq(x) ((x)->ping_freq) +#define ConFreq(x) ((x)->conn_freq) +#define MaxLinks(x) ((x)->max_links) +#define MaxSendq(x) ((x)->max_sendq) +#define Links(x) ((x)->ref_count) -#define ConfLinks(x) ((x)->confClass->links) -#define ConfMaxLinks(x) ((x)->confClass->maxLinks) -#define ConfClass(x) ((x)->confClass->conClass) -#define ConfConFreq(x) ((x)->confClass->conFreq) -#define ConfPingFreq(x) ((x)->confClass->pingFreq) -#define ConfSendq(x) ((x)->confClass->maxSendq) +#define ConfClass(x) ((x)->conn_class->cc_class) +#define ConfPingFreq(x) ((x)->conn_class->ping_freq) +#define ConfConFreq(x) ((x)->conn_class->conn_freq) +#define ConfMaxLinks(x) ((x)->conn_class->max_links) +#define ConfSendq(x) ((x)->conn_class->max_sendq) +#define ConfLinks(x) ((x)->conn_class->ref_count) /* * Proto types @@ -76,7 +77,7 @@ extern void free_class(struct ConnectionClass * tmp); extern unsigned int get_con_freq(struct ConnectionClass * clptr); extern unsigned int get_client_ping(struct Client *acptr); extern unsigned int get_conf_class(const struct ConfItem *aconf); -extern unsigned int get_conf_ping(const struct ConfItem *aconf); +extern int get_conf_ping(const struct ConfItem *aconf); extern unsigned int get_client_class(struct Client *acptr); extern void add_class(unsigned int conclass, unsigned int ping, unsigned int confreq, unsigned int maxli, unsigned int sendq); diff --git a/include/client.h b/include/client.h index c8e77c5..f6c35f6 100644 --- a/include/client.h +++ b/include/client.h @@ -310,7 +310,7 @@ typedef enum ShowIPType { } ShowIPType; extern const char* get_client_name(const struct Client* sptr, int showip); -extern unsigned int client_get_ping(const struct Client* local_client); +extern int client_get_ping(const struct Client* local_client); #endif /* INCLUDED_client_h */ diff --git a/include/ircd_string.h b/include/ircd_string.h index d64802c..778a028 100644 --- a/include/ircd_string.h +++ b/include/ircd_string.h @@ -24,6 +24,7 @@ extern int init_string(void); extern int string_is_hostname(const char* str); extern int string_is_address(const char* str); +extern int string_has_wildcards(const char* str); extern char* ircd_strncpy(char* dest, const char* src, size_t len); extern int ircd_strcmp(const char *a, const char *b); diff --git a/include/s_conf.h b/include/s_conf.h index dc76528..7742f93 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -37,15 +37,12 @@ struct TRecord; #define CONF_SERVER 0x0004 #define CONF_LOCOP 0x0010 #define CONF_OPERATOR 0x0020 -#define CONF_KILL 0x0080 #define CONF_LEAF 0x1000 #define CONF_HUB 0x4000 #define CONF_UWORLD 0x8000 -#define CONF_IPKILL 0x00010000 #define CONF_OPS (CONF_OPERATOR | CONF_LOCOP) #define CONF_CLIENT_MASK (CONF_CLIENT | CONF_OPS | CONF_SERVER) -#define CONF_KLINE (CONF_KILL | CONF_IPKILL) #define IsIllegal(x) ((x)->status & CONF_ILLEGAL) @@ -54,18 +51,18 @@ struct TRecord; */ struct ConfItem { - struct ConfItem* next; - unsigned int status; /* If CONF_ILLEGAL, delete when no clients */ - unsigned int clients; /* Number of *LOCAL* clients using this */ - struct in_addr ipnum; /* ip number of host field */ - char bits; /* Number of bits for ipkills */ - char* host; - char* passwd; - char* name; - unsigned short int port; - time_t hold; /* Hold until this time (calendar time) */ - int dns_pending; /* a dns request is pending */ - struct ConnectionClass* confClass; /* Class of connection */ + struct ConfItem* next; + unsigned int status; /* If CONF_ILLEGAL, delete when no clients */ + unsigned int clients; /* Number of *LOCAL* clients using this */ + struct ConnectionClass* conn_class; /* Class of connection */ + struct in_addr ipnum; /* ip number of host field */ + char* host; + char* passwd; + char* name; + time_t hold; /* Hold until this time (calendar time) */ + int dns_pending; /* a dns request is pending */ + unsigned short port; + char bits; /* Number of bits for ipkills */ }; struct ServerConf { @@ -78,7 +75,18 @@ struct ServerConf { int dns_pending; int connected; time_t hold; - struct ConnectionClass* confClass; + struct ConnectionClass* conn_class; +}; + +struct DenyConf { + struct DenyConf* next; + char* hostmask; + char* message; + char* usermask; + unsigned int s_addr; + char is_file; + char ip_kill; + char bits; /* Number of bits for ipkills */ }; /* @@ -156,6 +164,7 @@ extern int init_conf(void); extern const struct LocalConf* conf_get_local(void); extern const struct MotdConf* conf_get_motd_list(void); extern const struct CRuleConf* conf_get_crule_list(void); +extern const struct DenyConf* conf_get_deny_list(void); extern const char* conf_eval_crule(const char* name, int mask); @@ -165,7 +174,6 @@ extern struct ConfItem* find_conf_byname(struct SLink* lp, const char *name, int extern struct ConfItem* conf_find_server(const char* name); extern void det_confs_butmask(struct Client *cptr, int mask); -extern int detach_conf(struct Client *cptr, struct ConfItem *aconf); extern enum AuthorizationCheckResult attach_conf(struct Client *cptr, struct ConfItem *aconf); extern struct ConfItem* find_conf_exact(const char* name, const char* user, const char* host, int statmask); diff --git a/include/s_stats.h b/include/s_stats.h index 58db90a..49dfe01 100644 --- a/include/s_stats.h +++ b/include/s_stats.h @@ -31,7 +31,9 @@ extern const char *statsinfo[]; extern void report_stats(struct Client *sptr, char stat); extern void report_configured_links(struct Client *sptr, int mask); extern int hunt_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[], char stat); + extern void report_crule_list(struct Client* to, int mask); extern void report_motd_list(struct Client* to); +extern void report_deny_list(struct Client* to); #endif /* INCLUDED_s_stats_h */ diff --git a/ircd/Makefile.in b/ircd/Makefile.in index 4607245..93c367e 100644 --- a/ircd/Makefile.in +++ b/ircd/Makefile.in @@ -306,9 +306,9 @@ channel.o: channel.c ../include/channel.h ../config/config.h \ class.o: class.c ../include/class.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/ircd_handler.h \ ../include/ircd.h ../config/config.h ../config/setup.h \ - ../include/struct.h ../include/ircd_reply.h ../include/list.h \ - ../include/numeric.h ../include/s_conf.h ../include/s_debug.h \ - ../include/send.h + ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \ + ../include/ircd_reply.h ../include/list.h ../include/numeric.h \ + ../include/s_conf.h ../include/s_debug.h ../include/send.h client.o: client.c ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/ircd_handler.h ../include/class.h \ ../include/ircd.h ../config/config.h ../config/setup.h \ @@ -396,11 +396,11 @@ jupe.o: jupe.c ../include/jupe.h ../config/config.h ../config/setup.h \ ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \ ../include/s_misc.h ../include/send.h ../include/support.h \ ../include/sys.h -list.o: list.c ../include/list.h ../include/class.h \ - ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \ - ../include/ircd_handler.h ../include/ircd.h ../config/config.h \ - ../config/setup.h ../include/struct.h ../include/ircd_alloc.h \ - ../include/fda.h ../include/ircd_reply.h ../include/ircd_string.h \ +list.o: list.c ../include/list.h ../include/client.h \ + ../include/ircd_defs.h ../include/dbuf.h ../include/ircd_handler.h \ + ../include/ircd.h ../config/config.h ../config/setup.h \ + ../include/struct.h ../include/ircd_alloc.h ../include/fda.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_bsd.h \ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \ diff --git a/ircd/chkconf.c b/ircd/chkconf.c index f67780e..00608cb 100644 --- a/ircd/chkconf.c +++ b/ircd/chkconf.c @@ -43,14 +43,16 @@ * stuff that isn't used by s_conf.c anymore */ #define CONF_ME 0x0040 +#define CONF_KILL 0x0080 #define CONF_ADMIN 0x0100 #define CONF_CLASS 0x0400 #define CONF_LISTEN_PORT 0x2000 +#define CONF_IPKILL 0x00010000 #define CONF_CRULEALL 0x00200000 #define CONF_CRULEAUTO 0x00400000 #define CONF_TLINES 0x00800000 - +#define CONF_KLINE (CONF_KILL | CONF_IPKILL) #define CONF_CRULE (CONF_CRULEALL | CONF_CRULEAUTO) diff --git a/ircd/class.c b/ircd/class.c index 533e029..77678e9 100644 --- a/ircd/class.c +++ b/ircd/class.c @@ -53,10 +53,11 @@ struct ConnectionClass* make_class(void) return tmp; } -void free_class(struct ConnectionClass* tmp) +void free_class(struct ConnectionClass* p) { - if (tmp) { - MyFree(tmp); + if (p) { + assert(0 == p->valid); + MyFree(p); --connClassAllocCount; } } @@ -69,10 +70,11 @@ void init_class(void) connClassList = (struct ConnectionClass*) make_class(); ConClass(connClassList) = 0; - ConFreq(connClassList) = CONNECTFREQUENCY; PingFreq(connClassList) = PINGFREQUENCY; + ConFreq(connClassList) = CONNECTFREQUENCY; MaxLinks(connClassList) = MAXIMUM_LINKS; MaxSendq(connClassList) = DEFAULTMAXSENDQLENGTH; + connClassList->valid = 1; Links(connClassList) = 0; connClassList->next = 0; } @@ -89,11 +91,11 @@ void class_mark_delete(void) assert(0 != connClassList); for (p = connClassList->next; p; p = p->next) - p->maxLinks = BAD_CONF_CLASS; + p->valid = 0; } /* - * check_class + * class_delete_marked * delete classes marked for deletion * XXX - memory leak, no one deletes classes that become unused * later @@ -111,19 +113,19 @@ void class_delete_marked(void) /* * unlink marked classes, delete unreferenced ones */ - if (BAD_CONF_CLASS == cl->maxLinks) { + if (cl->valid) + prev = cl; + else { prev->next = cl->next; - if (0 == cl->links) + if (0 == cl->ref_count) free_class(cl); } - else - prev = cl; } } unsigned int get_conf_class(const struct ConfItem* aconf) { - if ((aconf) && (aconf->confClass)) + if ((aconf) && (aconf->conn_class)) return (ConfClass(aconf)); Debug((DEBUG_DEBUG, "No Class For %s", (aconf) ? aconf->name : "*No Conf*")); @@ -131,14 +133,15 @@ unsigned int get_conf_class(const struct ConfItem* aconf) return (BAD_CONF_CLASS); } -unsigned int get_conf_ping(const struct ConfItem *aconf) +int get_conf_ping(const struct ConfItem* aconf) { - if ((aconf) && (aconf->confClass)) + assert(0 != aconf); + if (aconf->conn_class) return (ConfPingFreq(aconf)); - Debug((DEBUG_DEBUG, "No Ping For %s", (aconf) ? aconf->name : "*No Conf*")); + Debug((DEBUG_DEBUG, "No Ping For %s", aconf->name)); - return (BAD_PING); + return -1; } unsigned int get_client_class(struct Client *acptr) @@ -150,7 +153,7 @@ unsigned int get_client_class(struct Client *acptr) if (acptr && !IsMe(acptr) && (acptr->confs)) for (tmp = acptr->confs; tmp; tmp = tmp->next) { - if (!tmp->value.aconf || !(cl = tmp->value.aconf->confClass)) + if (!tmp->value.aconf || !(cl = tmp->value.aconf->conn_class)) continue; if (ConClass(cl) > retc || retc == BAD_CLIENT_CLASS) retc = ConClass(cl); @@ -228,6 +231,7 @@ void add_class(unsigned int conClass, unsigned int ping, unsigned int confreq, PingFreq(p) = ping; MaxLinks(p) = maxli; MaxSendq(p) = (sendq > 0) ? sendq : DEFAULTMAXSENDQLENGTH; + p->valid = 1; if (p != t) Links(p) = 0; } @@ -265,7 +269,7 @@ unsigned int get_sendq(struct Client *cptr) struct ConnectionClass* cl; for (tmp = cptr->confs; tmp; tmp = tmp->next) { - if (!tmp->value.aconf || !(cl = tmp->value.aconf->confClass)) + if (!tmp->value.aconf || !(cl = tmp->value.aconf->conn_class)) continue; if (ConClass(cl) != BAD_CLIENT_CLASS) { cptr->max_sendq = MaxSendq(cl); diff --git a/ircd/client.c b/ircd/client.c index 3caa2de..c204226 100644 --- a/ircd/client.c +++ b/ircd/client.c @@ -38,18 +38,17 @@ * returns shortest ping time in attached server or client conf * classes or PINGFREQUENCY */ -unsigned int client_get_ping(const struct Client* acptr) +int client_get_ping(const struct Client* acptr) { - unsigned int ping = 0; - unsigned int tmp; + int ping = 0; struct ConfItem* aconf; struct SLink* link; for (link = acptr->confs; link; link = link->next) { aconf = link->value.aconf; if (aconf->status & (CONF_CLIENT | CONF_SERVER)) { - tmp = get_conf_ping(aconf); - if ((tmp != BAD_PING) && ((ping > tmp) || !ping)) + int tmp = get_conf_ping(aconf); + if (0 < tmp && (ping > tmp || !ping)) ping = tmp; } } @@ -57,14 +56,14 @@ unsigned int client_get_ping(const struct Client* acptr) ping = PINGFREQUENCY; Debug((DEBUG_DEBUG, "Client %s Ping %d", acptr->name, ping)); - return (ping); + return ping; } #if 0 #define BAD_CONF_CLASS ((unsigned int)-1) #define BAD_CLIENT_CLASS ((unsigned int)-3) -unsigned int get_client_class(struct Client *acptr) +unsigned int get_client_class(struct Client* acptr) { struct SLink *tmp; struct ConnectionClass *cl; diff --git a/ircd/ircd.c b/ircd/ircd.c index a275cdb..095c117 100644 --- a/ircd/ircd.c +++ b/ircd/ircd.c @@ -211,7 +211,7 @@ static time_t try_connections(void) { continue; } - cltmp = aconf->confClass; + cltmp = aconf->conn_class; confrq = get_con_freq(cltmp); aconf->hold = CurrentTime + confrq; diff --git a/ircd/ircd_string.c b/ircd/ircd_string.c index 4976e13..113f59d 100644 --- a/ircd/ircd_string.c +++ b/ircd/ircd_string.c @@ -75,6 +75,20 @@ int string_is_address(const char* str) return (0 == regexec(&addrRegex, str, 0, 0, 0)); } +int string_has_wildcards(const char* str) +{ + assert(0 != str); + for ( ; *str; ++str) { + if ('\\' == *str) { + if ('\0' == *++str) + break; + } + else if ('*' == *str || '?' == *str) + return 1; + } + return 0; +} + /* * strtoken.c * diff --git a/ircd/m_stats.c b/ircd/m_stats.c index e775d4c..118d746 100644 --- a/ircd/m_stats.c +++ b/ircd/m_stats.c @@ -123,6 +123,53 @@ #include +int report_klines(struct Client* sptr, char* mask, int limit_query) +{ + int wilds = 0; + int count = 3; + char* user = 0; + char* host; + const struct DenyConf* conf; + + if (EmptyString(mask)) { + if (limit_query) + return need_more_params(sptr, "STATS K"); + else + report_deny_list(sptr); + return 1; + } + + if (!limit_query) { + wilds = string_has_wildcards(mask); + count = 1000; + } + + if ((host = strchr(mask, '@'))) { + user = mask; + *host++ = '\0'; + } + else { + host = mask; + } + + for (conf = conf_get_deny_list(); conf; conf = conf->next) { + if ((!wilds && ((user || conf->hostmask) && + !match(conf->hostmask, host) && + (!user || !match(conf->usermask, user)))) || + (wilds && !mmatch(host, conf->hostmask) && + (!user || !mmatch(user, conf->usermask)))) + { + send_reply(sptr, RPL_STATSKLINE, (conf->ip_kill) ? 'k' : 'K', + conf->hostmask, conf->message, conf->usermask); + if (--count == 0) + return 1; + } + } + /* send_reply(sptr, RPL_ENDOFSTATS, stat); */ + return 1; +} + + /* * m_stats - generic message handler * @@ -163,19 +210,13 @@ int m_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) case 'L': case 'l': { - int doall = 0, wilds = 0; + int doall = 0; + int wilds = 0; char *name = "*"; - if (parc > 3 && *parv[3]) - { - char *p; + + if (parc > 3 && !EmptyString(parv[3])) { name = parv[3]; - wilds = (*name == '*' || *name == '?'); - for (p = name + 1; *p; ++p) - if ((*p == '*' || *p == '?') && p[-1] != '\\') - { - wilds = 1; - break; - } + wilds = string_has_wildcards(name); } else doall = 1; @@ -223,92 +264,41 @@ int m_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) case 'h': report_configured_links(sptr, CONF_HUB | CONF_LEAF); break; + case 'K': + case 'k': /* display CONF_IPKILL as well as CONF_KILL -Kev */ + if (0 == report_klines(sptr, (parc == 4) ? parv[3] : 0, 0)) + return 0; + break; case 'I': case 'i': - case 'K': - case 'k': /* display CONF_IPKILL as well - as CONF_KILL -Kev */ { - int wilds, count; - char *user, *host, *p; - int conf_status = (stat == 'k' || stat == 'K') ? CONF_KLINE : CONF_CLIENT; - if (parc < 4) - { - report_configured_links(sptr, conf_status); - break; - } + int wilds = 0; + int count = 1000; + char* host; - wilds = 0; - for (p = parv[3]; *p; p++) - { - if (*p == '\\') - { - if (!*++p) - break; - continue; - } - if (*p == '?' || *p == '*') - { - wilds = 1; - break; - } + if (parc < 4) { + report_configured_links(sptr, CONF_CLIENT); + break; } + if (EmptyString(parv[3])) + return need_more_params(sptr, "STATS I"); - count = 1000; - - if (conf_status == CONF_CLIENT) - { - user = 0; /* Not used, but to avoid compiler warning. */ + host = parv[3]; + wilds = string_has_wildcards(host); - host = parv[3]; - } - else - { - if ((host = strchr(parv[3], '@'))) - { - user = parv[3]; - *host++ = 0;; - } - else - { - user = 0; - host = parv[3]; - } - } - for (aconf = GlobalConfList; aconf; aconf = aconf->next) - { - if ((aconf->status & conf_status)) - { - if (conf_status == CONF_KLINE) - { - if ((!wilds && ((user || aconf->host[1]) && - !match(aconf->host, host) && - (!user || !match(aconf->name, user)))) || - (wilds && !mmatch(host, aconf->host) && - (!user || !mmatch(user, aconf->name)))) - { - send_reply(sptr, RPL_STATSKLINE, - (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host, - aconf->passwd, aconf->name, aconf->port, - get_conf_class(aconf)); - if (--count == 0) - break; - } - } - else if (conf_status == CONF_CLIENT) - { - if ((!wilds && (!match(aconf->host, host) || - !match(aconf->name, host))) || - (wilds && (!mmatch(host, aconf->host) || - !mmatch(host, aconf->name)))) - { - send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name, - aconf->port, get_conf_class(aconf)); - if (--count == 0) - break; - } - } - } + for (aconf = GlobalConfList; aconf; aconf = aconf->next) { + if (CONF_CLIENT == aconf->status) { + if ((!wilds && (!match(aconf->host, host) || + !match(aconf->name, host))) || + (wilds && (!mmatch(host, aconf->host) || + !mmatch(host, aconf->name)))) + { + send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name, + aconf->port, get_conf_class(aconf)); + if (--count == 0) + break; + } + } } break; } @@ -460,19 +450,13 @@ int ms_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) case 'L': case 'l': { - int doall = 0, wilds = 0; + int doall = 0; + int wilds = 0; char *name = "*"; - if (parc > 3 && *parv[3]) - { - char *p; + + if (parc > 3 && !EmptyString(parv[3])) { name = parv[3]; - wilds = (*name == '*' || *name == '?'); - for (p = name + 1; *p; ++p) - if ((*p == '*' || *p == '?') && p[-1] != '\\') - { - wilds = 1; - break; - } + wilds = string_has_wildcards(name); } else doall = 1; @@ -521,100 +505,45 @@ int ms_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) case 'h': report_configured_links(sptr, CONF_HUB | CONF_LEAF); break; + case 'K': + case 'k': /* display CONF_IPKILL as well as CONF_KILL -Kev */ + if (0 == report_klines(sptr, (parc > 3) ? parv[3] : 0, !IsOper(sptr))) + return 0; + break; case 'I': case 'i': - case 'K': - case 'k': /* display CONF_IPKILL as well - as CONF_KILL -Kev */ { - int wilds, count; - char *user, *host, *p; - int conf_status = (stat == 'k' || stat == 'K') ? CONF_KLINE : CONF_CLIENT; - if (IsOper(sptr) && parc < 4) - { - report_configured_links(sptr, conf_status); + int wilds = 0; + int count = 3; + char* host; + + if (parc < 4 && IsOper(sptr)) { + report_configured_links(sptr, CONF_CLIENT); break; } - if (parc < 4 || *parv[3] == '\0') - return need_more_params(sptr, - (conf_status & CONF_KLINE) ? "STATS K" : "STATS I"); + if (parc < 4 || EmptyString(parv[3])) + return need_more_params(sptr, "STATS I"); - wilds = 0; - for (p = parv[3]; *p; p++) - { - if (*p == '\\') - { - if (!*++p) - break; - continue; - } - if (*p == '?' || *p == '*') - { - wilds = 1; - break; - } - } - if (!IsOper(sptr)) - { - wilds = 0; - count = 3; - } - else + if (IsOper(sptr)) { + wilds = string_has_wildcards(parv[3]); count = 1000; + } - if (conf_status == CONF_CLIENT) - { - user = 0; /* Not used, but to avoid compiler warning. */ + host = parv[3]; - host = parv[3]; - } - else - { - if ((host = strchr(parv[3], '@'))) - { - user = parv[3]; - *host++ = 0;; - } - else - { - user = 0; - host = parv[3]; - } - } - for (aconf = GlobalConfList; aconf; aconf = aconf->next) - { - if ((aconf->status & conf_status)) - { - if (conf_status == CONF_KLINE) - { - if ((!wilds && ((user || aconf->host[1]) && - !match(aconf->host, host) && - (!user || !match(aconf->name, user)))) || - (wilds && !mmatch(host, aconf->host) && - (!user || !mmatch(user, aconf->name)))) - { - send_reply(sptr, RPL_STATSKLINE, - (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host, - aconf->passwd, aconf->name, aconf->port, - get_conf_class(aconf)); - if (--count == 0) - break; - } - } - else if (conf_status == CONF_CLIENT) - { - if ((!wilds && (!match(aconf->host, host) || - !match(aconf->name, host))) || - (wilds && (!mmatch(host, aconf->host) || - !mmatch(host, aconf->name)))) - { - send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name, - aconf->port, get_conf_class(aconf)); - if (--count == 0) - break; - } - } - } + for (aconf = GlobalConfList; aconf; aconf = aconf->next) { + if (CONF_CLIENT == aconf->status) { + if ((!wilds && (!match(aconf->host, host) || + !match(aconf->name, host))) || + (wilds && (!mmatch(host, aconf->host) || + !mmatch(host, aconf->name)))) + { + send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name, + aconf->port, get_conf_class(aconf)); + if (--count == 0) + break; + } + } } break; } @@ -752,12 +681,12 @@ int ms_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) */ int mo_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { - struct Message *mptr; - struct Client *acptr; - struct ConfItem *aconf; - char stat = parc > 1 ? parv[1][0] : '\0'; - const char **infotext = statsinfo; - int i; + struct Message* mptr; + struct Client* acptr; + struct ConfItem* aconf; + char stat = parc > 1 ? parv[1][0] : '\0'; + const char** infotext = statsinfo; + int i; if (hunt_stats(cptr, sptr, parc, parv, stat) != HUNTED_ISME) return 0; @@ -768,18 +697,10 @@ int mo_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) case 'l': { int doall = 0, wilds = 0; - char *name = "*"; - if (parc > 3 && *parv[3]) - { - char *p; + char* name = "*"; + if (parc > 3 && !EmptyString(parv[3])) { name = parv[3]; - wilds = (*name == '*' || *name == '?'); - for (p = name + 1; *p; ++p) - if ((*p == '*' || *p == '?') && p[-1] != '\\') - { - wilds = 1; - break; - } + wilds = string_has_wildcards(name); } else doall = 1; @@ -824,95 +745,44 @@ int mo_stats(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) case 'h': report_configured_links(sptr, CONF_HUB | CONF_LEAF); break; + case 'K': + case 'k': /* display CONF_IPKILL as well as CONF_KILL -Kev */ + if (0 == report_klines(sptr, (parc > 3) ? parv[3] : 0, 0)) + return 0; + break; case 'I': case 'i': - case 'K': - case 'k': /* display CONF_IPKILL as well - as CONF_KILL -Kev */ - { - int wilds, count; - char *user, *host, *p; - int conf_status = (stat == 'k' || stat == 'K') ? CONF_KLINE : CONF_CLIENT; - if (parc < 4) { - report_configured_links(sptr, conf_status); - break; - } + int wilds = 0; + int count = 1000; + char* host; - wilds = 0; - for (p = parv[3]; *p; p++) - { - if (*p == '\\') - { - if (!*++p) - break; - continue; - } - if (*p == '?' || *p == '*') - { - wilds = 1; - break; - } - } + if (parc < 4) { + report_configured_links(sptr, CONF_CLIENT); + break; + } + if (EmptyString(parv[3])) + return need_more_params(sptr, "STATS I"); - count = 1000; + host = parv[3]; + wilds = string_has_wildcards(host); - if (conf_status == CONF_CLIENT) - { - user = 0; /* Not used, but to avoid compiler warning. */ - - host = parv[3]; - } - else - { - if ((host = strchr(parv[3], '@'))) - { - user = parv[3]; - *host++ = 0;; - } - else - { - user = 0; - host = parv[3]; - } - } - for (aconf = GlobalConfList; aconf; aconf = aconf->next) - { - if ((aconf->status & conf_status)) - { - if (conf_status == CONF_KLINE) - { - if ((!wilds && ((user || aconf->host[1]) && - !match(aconf->host, host) && - (!user || !match(aconf->name, user)))) || - (wilds && !mmatch(host, aconf->host) && - (!user || !mmatch(user, aconf->name)))) - { - send_reply(sptr, RPL_STATSKLINE, - (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host, - aconf->passwd, aconf->name, aconf->port, - get_conf_class(aconf)); - if (--count == 0) - break; - } - } - else if (conf_status == CONF_CLIENT) - { - if ((!wilds && (!match(aconf->host, host) || - !match(aconf->name, host))) || - (wilds && (!mmatch(host, aconf->host) || - !mmatch(host, aconf->name)))) - { - send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name, - aconf->port, get_conf_class(aconf)); - if (--count == 0) - break; - } - } - } + for (aconf = GlobalConfList; aconf; aconf = aconf->next) { + if (CONF_CLIENT == aconf->status) { + if ((!wilds && (!match(aconf->host, host) || + !match(aconf->name, host))) || + (wilds && (!mmatch(host, aconf->host) || + !mmatch(host, aconf->name)))) + { + send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name, + aconf->port, get_conf_class(aconf)); + if (--count == 0) + break; + } + } + } } break; - } case 'M': #if !defined(NDEBUG) send_reply(sptr, RPL_STATMEMTOT, fda_get_byte_count(), diff --git a/ircd/s_conf.c b/ircd/s_conf.c index b9a8525..da8ad14 100644 --- a/ircd/s_conf.c +++ b/ircd/s_conf.c @@ -78,38 +78,41 @@ static struct LocalConf localConf; static struct MotdConf* motdConfList; static struct CRuleConf* cruleConfList; static struct ServerConf* serverConfList; +static struct DenyConf* denyConfList; /* * output the reason for being k lined from a file - Mmmm - * sptr is server - * parv is the sender prefix + * sptr is client being dumped * filename is the file that is to be output to the K lined client */ -static void killcomment(struct Client *sptr, char *parv, char *filename) +static void killcomment(struct Client* sptr, const char* filename) { - FBFILE* file = NULL; + FBFILE* file = 0; char line[80]; - char* tmp = NULL; struct stat sb; struct tm* tm; if (NULL == (file = fbopen(filename, "r"))) { send_reply(sptr, ERR_NOMOTD); send_reply(sptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, - ":Connection from your host is refused on this server."); + ":Connection from your host is refused on this server."); return; } fbstat(&sb, file); tm = localtime((time_t*) &sb.st_mtime); /* NetBSD needs cast */ while (fbgets(line, sizeof(line) - 1, file)) { - if ((tmp = strchr(line, '\n'))) - *tmp = '\0'; - if ((tmp = strchr(line, '\r'))) - *tmp = '\0'; + char* end = line + strlen(line); + while (end > line) { + --end; + if ('\n' == *end || '\r' == *end) + *end = '\0'; + else + break; + } send_reply(sptr, RPL_MOTD, line); } send_reply(sptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, - ":Connection from your host is refused on this server."); + ":Connection from your host is refused on this server."); fbclose(file); } @@ -122,17 +125,9 @@ struct ConfItem* make_conf(void) #ifdef DEBUGMODE ++GlobalConfCount; #endif + memset(aconf, 0, sizeof(struct ConfItem)); aconf->status = CONF_ILLEGAL; - aconf->clients = 0; aconf->ipnum.s_addr = INADDR_NONE; - aconf->host = 0; - aconf->passwd = 0; - aconf->name = 0; - aconf->port = 0; - aconf->hold = 0; - aconf->dns_pending = 0; - aconf->confClass = 0; - aconf->next = 0; return aconf; } @@ -147,7 +142,7 @@ void delist_conf(struct ConfItem *aconf) ; bconf->next = aconf->next; } - aconf->next = NULL; + aconf->next = 0; } void free_conf(struct ConfItem *aconf) @@ -169,6 +164,37 @@ void free_conf(struct ConfItem *aconf) #endif } +/* + * detach_conf - Disassociate configuration from the client. + */ +static void detach_conf(struct Client* cptr, struct ConfItem* aconf) +{ + struct SLink** lp; + struct SLink* tmp; + + assert(0 != aconf); + assert(0 != cptr); + assert(0 < aconf->clients); + + lp = &(cptr->confs); + + while (*lp) { + if ((*lp)->value.aconf == aconf) { + if (aconf->conn_class && (aconf->status & CONF_CLIENT_MASK) && ConfLinks(aconf) > 0) + --ConfLinks(aconf); + + assert(0 < aconf->clients); + if (0 == --aconf->clients && IsIllegal(aconf)) + free_conf(aconf); + tmp = *lp; + *lp = tmp->next; + free_link(tmp); + return; + } + lp = &((*lp)->next); + } +} + /* * conf_dns_callback - called when resolver query finishes * if the query resulted in a successful search, hp will contain @@ -294,14 +320,16 @@ const char* conf_eval_crule(const char* name, int mask) * Remove all conf entries from the client except those which match * the status field mask. */ -void det_confs_butmask(struct Client *cptr, int mask) +void det_confs_butmask(struct Client* cptr, int mask) { - struct SLink *tmp, *tmp2; + struct SLink* link; + struct SLink* next; + assert(0 != cptr); - for (tmp = cptr->confs; tmp; tmp = tmp2) { - tmp2 = tmp->next; - if ((tmp->value.aconf->status & mask) == 0) - detach_conf(cptr, tmp->value.aconf); + for (link = cptr->confs; link; link = next) { + next = link->next; + if ((link->value.aconf->status & mask) == 0) + detach_conf(cptr, link->value.aconf); } } @@ -395,47 +423,15 @@ enum AuthorizationCheckResult attach_iline(struct Client* cptr) return ACR_NO_AUTHORIZATION; } -/* - * detach_conf - Disassociate configuration from the client. - */ -int detach_conf(struct Client *cptr, struct ConfItem *aconf) -{ - struct SLink** lp; - struct SLink* tmp; - - assert(0 != aconf); - assert(0 != cptr); - assert(0 < aconf->clients); - - lp = &(cptr->confs); - - while (*lp) { - if ((*lp)->value.aconf == aconf) { - if (aconf->confClass && (aconf->status & CONF_CLIENT_MASK) && - ConfLinks(aconf) > 0) - --ConfLinks(aconf); - if (0 == --aconf->clients && IsIllegal(aconf)) - free_conf(aconf); - tmp = *lp; - *lp = tmp->next; - free_link(tmp); - return 0; - } - else - lp = &((*lp)->next); - } - return -1; -} - static int is_attached(struct ConfItem *aconf, struct Client *cptr) { struct SLink *lp; - for (lp = cptr->confs; lp; lp = lp->next) + for (lp = cptr->confs; lp; lp = lp->next) { if (lp->value.aconf == aconf) - break; - - return (lp) ? 1 : 0; + return 1; + } + return 0; } /* @@ -553,7 +549,7 @@ struct ConfItem* find_conf_exact(const char* name, const char* user, if (match(tmp->host, userhost)) continue; if (tmp->status & (CONF_OPERATOR | CONF_LOCOP)) { - if (tmp->clients < MaxLinks(tmp->confClass)) + if (tmp->clients < MaxLinks(tmp->conn_class)) return tmp; else continue; @@ -877,7 +873,7 @@ void conf_add_server(const char* const* fields, int count) server->dns_pending = 0; server->connected = 0; server->hold = 0; - server->confClass = find_class(atoi(fields[5])); + server->conn_class = find_class(atoi(fields[5])); server->next = serverConfList; serverConfList = server; @@ -886,6 +882,79 @@ void conf_add_server(const char* const* fields, int count) // lookup_confhost(server); } +void conf_add_deny(const char* const* fields, int count, int ip_kill) +{ + struct DenyConf* conf; + + if (count < 4 || EmptyString(fields[1]) || EmptyString(fields[3])) + return; + + conf = (struct DenyConf*) MyMalloc(sizeof(struct DenyConf)); + assert(0 != conf); + memset(conf, 0, sizeof(struct DenyConf)); + + DupString(conf->hostmask, fields[1]); + collapse(conf->hostmask); + + if (!EmptyString(fields[2])) { + const char* p = fields[2]; + if ('!' == *p) { + conf->is_file = 1; + ++p; + } + DupString(conf->message, p); + } + DupString(conf->usermask, fields[3]); + collapse(conf->usermask); + + if (ip_kill) { + /* + * Here we use the same kludge as in listener.c to parse + * a.b.c.d, or a.b.c.*, or a.b.c.d/e. + */ + int c_class; + char ipname[16]; + int ad[4] = { 0 }; + int bits2 = 0; + c_class = sscanf(conf->hostmask, "%d.%d.%d.%d/%d", + &ad[0], &ad[1], &ad[2], &ad[3], &bits2); + if (c_class != 5) { + conf->bits = c_class * 8; + } + else { + conf->bits = bits2; + } + sprintf_irc(ipname, "%d.%d.%d.%d", ad[0], ad[1], ad[2], ad[3]); + + /* + * This ensures endian correctness + */ + conf->s_addr = inet_addr(ipname); + Debug((DEBUG_DEBUG, "IPkill: %s = %08x/%i (%08x)", ipname, + conf->s_addr, conf->bits, NETMASK(conf->bits))); + } + conf->next = denyConfList; + denyConfList = conf; +} + +void conf_erase_deny_list(void) +{ + struct DenyConf* next; + struct DenyConf* p = denyConfList; + for ( ; p; p = next) { + next = p->next; + MyFree(p->hostmask); + MyFree(p->usermask); + MyFree(p->message); + MyFree(p); + } + denyConfList = 0; +} + +const struct DenyConf* conf_get_deny_list(void) +{ + return denyConfList; +} /* * read_configuration_file @@ -1049,10 +1118,12 @@ int read_configuration_file(void) aconf->status = CONF_CLIENT; break; case 'K': /* Kill user line on irc.conf */ - aconf->status = CONF_KILL; + conf_add_deny(field_vector, field_count, 0); + aconf->status = CONF_ILLEGAL; break; case 'k': /* Kill user line based on IP in ircd.conf */ - aconf->status = CONF_IPKILL; + conf_add_deny(field_vector, field_count, 1); + aconf->status = CONF_ILLEGAL; break; /* Operator. Line should contain at least */ /* password and host where connection is */ @@ -1115,15 +1186,15 @@ int read_configuration_file(void) aconf->port = atoi(field_vector[4]); if (field_count > 5 && !EmptyString(field_vector[5])) - aconf->confClass = find_class(atoi(field_vector[5])); + aconf->conn_class = find_class(atoi(field_vector[5])); /* * Associate each conf line with a class by using a pointer * to the correct class record. -avalon */ if (aconf->status & CONF_CLIENT_MASK) { - if (aconf->confClass == 0) - aconf->confClass = find_class(0); + if (aconf->conn_class == 0) + aconf->conn_class = find_class(0); } if (aconf->status & CONF_CLIENT) { struct ConfItem *bconf; @@ -1140,8 +1211,8 @@ int read_configuration_file(void) aconf->passwd = 0; ConfLinks(bconf) -= bconf->clients; - bconf->confClass = aconf->confClass; - if (bconf->confClass) + bconf->conn_class = aconf->conn_class; + if (bconf->conn_class) ConfLinks(bconf) += bconf->clients; } free_conf(aconf); @@ -1161,7 +1232,7 @@ int read_configuration_file(void) len += strlen(aconf->host); newhost = (char*) MyMalloc(len); assert(0 != newhost); - ircd_snprintf(0, newhost, len, "*@%s", aconf->host); + ircd_snprintf(0, newhost, len, "*@%s", aconf->host); MyFree(aconf->host); aconf->host = newhost; } @@ -1171,31 +1242,6 @@ int read_configuration_file(void) continue; lookup_confhost(aconf); } - if (aconf->status == CONF_IPKILL) { - /* - * Here we use the same kludge as in listener.c to parse - * a.b.c.d, or a.b.c.*, or a.b.c.d/e. - */ - int class; - char ipname[16]; - int ad[4] = { 0 }; - int bits2=0; - class=sscanf(aconf->host,"%d.%d.%d.%d/%d", - &ad[0], &ad[1], &ad[2], &ad[3], &bits2); - if (class!=5) { - aconf->bits=class*8; - } - else { - aconf->bits=bits2; - } - sprintf_irc(ipname,"%d.%d.%d.%d",ad[0], ad[1], ad[2], ad[3]); - - /* This ensures endian correctness */ - aconf->ipnum.s_addr = inet_addr(ipname); - Debug((DEBUG_DEBUG,"IPkill: %s = %08x/%i (%08x)",ipname, - aconf->ipnum.s_addr,aconf->bits,NETMASK(aconf->bits))); - } - /* * Juped nicks are listed in the 'password' field of U:lines, * the list is comma separated and might be empty and/or contain @@ -1210,7 +1256,7 @@ int read_configuration_file(void) Debug((DEBUG_NOTICE, "Read Init: (%d) (%s) (%s) (%s) (%u) (%p)", aconf->status, aconf->host, aconf->passwd, - aconf->name, aconf->port, aconf->confClass)); + aconf->name, aconf->port, aconf->conn_class)); aconf->next = GlobalConfList; GlobalConfList = aconf; aconf = NULL; @@ -1241,7 +1287,7 @@ int rehash(struct Client *cptr, int sig) if (1 == sig) sendto_opmask_butone(0, SNO_OLDSNO, - "Got signal SIGHUP, reloading ircd conf. file"); + "Got signal SIGHUP, reloading ircd conf. file"); while ((tmp2 = *tmp)) { if (tmp2->clients) { @@ -1266,6 +1312,7 @@ int rehash(struct Client *cptr, int sig) } conf_erase_motd_list(&motdConfList); conf_erase_crule_list(); + conf_erase_deny_list(); /* * delete the juped nicks list @@ -1311,10 +1358,10 @@ int rehash(struct Client *cptr, int sig) */ if ((found_g = find_kill(acptr))) { sendto_opmask_butone(0, found_g == -2 ? SNO_GLINE : SNO_OPERKILL, - found_g == -2 ? "G-line active for %s%s" : - "K-line active for %s%s", - IsUnknown(acptr) ? "Unregistered Client ":"", - get_client_name(acptr, HIDE_IP)); + found_g == -2 ? "G-line active for %s%s" : + "K-line active for %s%s", + IsUnknown(acptr) ? "Unregistered Client ":"", + get_client_name(acptr, HIDE_IP)); if (exit_client(cptr, acptr, &me, found_g == -2 ? "G-lined" : "K-lined") == CPTR_KILLED) ret = CPTR_KILLED; @@ -1431,7 +1478,7 @@ int find_kill(struct Client *cptr) { const char* host; const char* name; - struct ConfItem* tmp; + struct DenyConf* deny; struct Gline* agline = NULL; assert(0 != cptr); @@ -1448,66 +1495,44 @@ int find_kill(struct Client *cptr) /* 2000-07-14: Rewrote this loop for massive speed increases. * -- Isomer */ - for (tmp = GlobalConfList; tmp; tmp = tmp->next) { - - if ((tmp->status & CONF_KLINE) == 0) - continue; - - /* - * What is this for? You can K: by port?! - * -- Isomer - */ - if (tmp->port && tmp->port != cptr->listener->port) - continue; - - if (!tmp->name || match(tmp->name, name) != 0) - continue; - - if (!tmp->host) - break; + for (deny = denyConfList; deny; deny = deny->next) { + if (0 != match(deny->usermask, name)) + continue; + + if (EmptyString(deny->hostmask)) + break; - if (tmp->status != CONF_IPKILL) { - if (match(tmp->host, host) == 0) - break; - } - else { /* k: by IP */ - Debug((DEBUG_DEBUG, "ip: %08x network: %08x/%i mask: %08x", - cptr->ip.s_addr, tmp->ipnum.s_addr, tmp->bits, - NETMASK(tmp->bits))); - if ((cptr->ip.s_addr & NETMASK(tmp->bits)) == tmp->ipnum.s_addr) - break; + if (deny->ip_kill) { /* k: by IP */ + Debug((DEBUG_DEBUG, "ip: %08x network: %08x/%i mask: %08x", + cptr->ip.s_addr, deny->s_addr, deny->bits, NETMASK(deny->bits))); + if ((cptr->ip.s_addr & NETMASK(deny->bits)) == deny->s_addr) + break; } + else if (0 == match(deny->hostmask, host)) + break; } - if (tmp) { - if (EmptyString(tmp->passwd)) + if (deny) { + if (EmptyString(deny->message)) send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, - ":Connection from your host is refused on this server."); + ":Connection from your host is refused on this server."); else { - if (*tmp->passwd == '"') { - send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%*s.", - strlen(tmp->passwd + 1) - 1, tmp->passwd + 1); - } - else if (*tmp->passwd == '!') - killcomment(cptr, cptr->name, &tmp->passwd[1]); + if (deny->is_file) + killcomment(cptr, deny->message); else -#ifdef COMMENT_IS_FILE - killcomment(cptr, cptr->name, tmp->passwd); -#else - send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s.", - tmp->passwd); -#endif + send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s.", deny->message); } } - - /* find active glines */ - /* added a check against the user's IP address to find_gline() -Kev */ - else if ((agline = gline_lookup(cptr, 0)) && GlineIsActive(agline)) - send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s.", - GlineReason(agline)); + else if ((agline = gline_lookup(cptr, 0)) && GlineIsActive(agline)) { + /* + * find active glines + * added a check against the user's IP address to find_gline() -Kev + */ + send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s.", GlineReason(agline)); + } else - agline = NULL; /* if a gline was found, it was inactive */ + agline = 0; /* if a gline was found, it was inactive */ - if (tmp) + if (deny) return -1; if (agline) return -2; @@ -1609,7 +1634,7 @@ int conf_check_server(struct Client *cptr) c_conf = find_conf_byname(lp, cptr->name, CONF_SERVER); if (!c_conf) { sendto_opmask_butone(0, SNO_OLDSNO, "Connect Error: lost C:line for %s", - cptr->name); + cptr->name); det_confs_butmask(cptr, 0); return -1; } diff --git a/ircd/s_err.c b/ircd/s_err.c index 050acd6..bf3de6d 100644 --- a/ircd/s_err.c +++ b/ircd/s_err.c @@ -467,7 +467,7 @@ static Numeric replyTable[] = { /* 215 */ { RPL_STATSILINE, "%c %s * %s %d %d", "215" }, /* 216 */ - { RPL_STATSKLINE, "%c %s %s %s %d %d", "216" }, + { RPL_STATSKLINE, "%c %s \"%s\" %s 0 0", "216" }, /* 217 */ { RPL_STATSPLINE, "P %d %d %s %s", "217" }, /* 218 */ diff --git a/ircd/s_stats.c b/ircd/s_stats.c index a26c0b2..87591d9 100644 --- a/ircd/s_stats.c +++ b/ircd/s_stats.c @@ -85,8 +85,6 @@ const char *statsinfo[] = { static unsigned int report_array[17][3] = { {CONF_SERVER, RPL_STATSCLINE, 'C'}, {CONF_CLIENT, RPL_STATSILINE, 'I'}, - {CONF_KILL, RPL_STATSKLINE, 'K'}, - {CONF_IPKILL, RPL_STATSKLINE, 'k'}, {CONF_LEAF, RPL_STATSLLINE, 'L'}, {CONF_OPERATOR, RPL_STATSOLINE, 'O'}, {CONF_HUB, RPL_STATSHLINE, 'H'}, @@ -123,9 +121,7 @@ void report_configured_links(struct Client *sptr, int mask) * displayed on STATS reply. -Vesa */ /* Special-case 'k' or 'K' lines as appropriate... -Kev */ - if ((tmp->status & CONF_KLINE)) - send_reply(sptr, p[1], c, host, pass, name, port, get_conf_class(tmp)); - else if ((tmp->status & CONF_UWORLD)) + if ((tmp->status & CONF_UWORLD)) send_reply(sptr, p[1], c, host, pass, name, port, get_conf_class(tmp)); else if ((tmp->status & (CONF_SERVER | CONF_HUB))) send_reply(sptr, p[1], c, "*", name, port, get_conf_class(tmp)); @@ -158,6 +154,18 @@ void report_crule_list(struct Client* to, int mask) } } +/* + * {CONF_KILL, RPL_STATSKLINE, 'K'}, + * {CONF_IPKILL, RPL_STATSKLINE, 'k'}, + */ +void report_deny_list(struct Client* to) +{ + const struct DenyConf* p = conf_get_deny_list(); + for ( ; p; p = p->next) + send_reply(to, RPL_STATSKLINE, (p->ip_kill) ? 'k' : 'K', + p->hostmask, p->message, p->usermask); +} + /* m_stats is so obnoxiously full of special cases that the different * hunt_server() possiblites were becoming very messy. It now uses a * switch() so as to be easier to read and update as params change.