X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/c88cdb00957d1bafae4587343b5ab7df14b75f8b..08d11e34cc17e3045231729d87025a0cfa598f54:/modules/core/m_message.c?ds=sidebyside diff --git a/modules/core/m_message.c b/modules/core/m_message.c index e6fe7ef..2340bc4 100644 --- a/modules/core/m_message.c +++ b/modules/core/m_message.c @@ -44,6 +44,7 @@ #include "event.h" #include "patricia.h" #include "s_newconf.h" +#include "s_stats.h" static int m_message(int, const char *, struct Client *, struct Client *, int, const char **); static int m_privmsg(struct Client *, struct Client *, int, const char **); @@ -545,9 +546,9 @@ static void expire_tgchange(void *unused) { tgchange *target; - dlink_node *ptr, *next_ptr; + rb_dlink_node *ptr, *next_ptr; - DLINK_FOREACH_SAFE(ptr, next_ptr, tgchange_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, tgchange_list.head) { target = ptr->data; @@ -565,6 +566,7 @@ static int add_target(struct Client *source_p, struct Client *target_p) { int i, j; + uint32_t hashv; /* can msg themselves or services without using any target slots */ if(source_p == target_p || IsService(target_p)) @@ -578,13 +580,15 @@ add_target(struct Client *source_p, struct Client *target_p) if(source_p->localClient->target_last > CurrentTime && IsOper(target_p)) return 1; + hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32); + if(USED_TARGETS(source_p)) { /* hunt for an existing target */ for(i = PREV_FREE_TARGET(source_p), j = USED_TARGETS(source_p); j; --j, PREV_TARGET(i)) { - if(source_p->localClient->targets[i] == target_p) + if(source_p->localClient->targets[i] == hashv) return 1; } @@ -609,6 +613,7 @@ add_target(struct Client *source_p, struct Client *target_p) /* cant clear any, full target list */ else if(USED_TARGETS(source_p) == 10) { + ServerStats->is_tgch++; add_tgchange(source_p->sockhost); return 0; } @@ -622,7 +627,7 @@ add_target(struct Client *source_p, struct Client *target_p) SetTGChange(source_p); } - source_p->localClient->targets[FREE_TARGET(source_p)] = target_p; + source_p->localClient->targets[FREE_TARGET(source_p)] = hashv; NEXT_TARGET(FREE_TARGET(source_p)); ++USED_TARGETS(source_p); return 1; @@ -781,7 +786,7 @@ flood_attack_client(int p_or_n, struct Client *source_p, struct Client *target_p { if(target_p->localClient->flood_noticed == 0) { - sendto_realops_snomask(SNO_BOTS, L_ALL, + sendto_realops_snomask(SNO_BOTS, L_NETWIDE, "Possible Flooder %s[%s@%s] on %s target: %s", source_p->name, source_p->username, source_p->orighost, @@ -836,7 +841,7 @@ flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr, { if(chptr->flood_noticed == 0) { - sendto_realops_snomask(SNO_BOTS, L_ALL, + sendto_realops_snomask(SNO_BOTS, *chptr->chname == '&' ? L_ALL : L_NETWIDE, "Possible Flooder %s[%s@%s] on %s target: %s", source_p->name, source_p->username, source_p->orighost, @@ -972,6 +977,13 @@ handle_special(int p_or_n, const char *command, struct Client *client_p, return; } + if(MyClient(source_p) && !IsOperMassNotice(source_p)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "mass_notice"); + return; + } + if((s = strrchr(nick, '.')) == NULL) { sendto_one_numeric(source_p, ERR_NOTOPLEVEL, @@ -1012,11 +1024,11 @@ find_userhost(const char *user, const char *host, int *count) struct Client *c2ptr; struct Client *res = NULL; char *u = LOCAL_COPY(user); - dlink_node *ptr; + rb_dlink_node *ptr; *count = 0; if(collapse(u) != NULL) { - DLINK_FOREACH(ptr, global_client_list.head) + RB_DLINK_FOREACH(ptr, global_client_list.head) { c2ptr = ptr->data; if(!MyClient(c2ptr)) /* implies mine and an user */