]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/core/m_message.c
Fix m_kick so that it checks if you're trying to kick the target, not yourself.
[irc/rqf/shadowircd.git] / modules / core / m_message.c
index 2b7a750ca33fbdba6194c19f66074d7f5f15063b..1ac0cfb4bd9d728698ca92f313f0dab4beb08b36 100644 (file)
@@ -43,6 +43,7 @@
 #include "send.h"
 #include "s_newconf.h"
 #include "s_stats.h"
+#include "tgchange.h"
 #include "inline/stringops.h"
 
 static int m_message(int, const char *, struct Client *, struct Client *, int, const char **);
@@ -90,7 +91,6 @@ static int build_target_list(int p_or_n, const char *command,
                             struct Client *client_p,
                             struct Client *source_p, const char *nicks_channels, const char *text);
 
-static struct Channel *find_allowing_channel(struct Client *source_p, struct Client *target_p);
 static int flood_attack_client(int p_or_n, struct Client *source_p, struct Client *target_p);
 static int flood_attack_channel(int p_or_n, struct Client *source_p,
                                struct Channel *chptr, char *chname);
@@ -361,7 +361,7 @@ build_target_list(int p_or_n, const char *command, struct Client *client_p,
 
                                msptr = find_channel_membership(chptr, source_p);
 
-                               if(!IsServer(source_p) && !IsService(source_p) && !is_chanop_voiced(msptr))
+                               if(!IsServer(source_p) && !IsService(source_p) && !is_chanop_voiced(msptr) && !IsOverride(source_p))
                                {
                                        sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                                                   get_id(&me, source_p),
@@ -484,6 +484,9 @@ msg_channel(int p_or_n, const char *command,
 {
        int result;
        char text2[BUFSIZE];
+       int contor;
+       int caps = 0;
+       int len = 0;
 
        if(MyClient(source_p))
        {
@@ -513,6 +516,34 @@ msg_channel(int p_or_n, const char *command,
                if(result == CAN_SEND_OPV ||
                   !flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
                {
+                       if (strlen(text) > 10 && chptr->mode.mode & MODE_NOCAPS)
+                       {
+                               for(contor=0; contor < strlen(text); contor++)
+                               {
+                                       if(IsUpper(text[contor]) && !isdigit(text[contor]))
+                                               caps++; 
+                                       len++;
+                               }
+                               if(((caps*100)/(len)) >= 50)
+                               {
+                                       sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
+                                                       form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
+                                       return;
+                               }
+                       }
+                       if (p_or_n != PRIVMSG && chptr->mode.mode & MODE_NONOTICE)
+                       {
+                               sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
+                                               form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
+                               return;
+                       }
+                       if (p_or_n != NOTICE && chptr->mode.mode & MODE_NOACTION &&
+                                       !strncasecmp(text + 1, "ACTION", 6))
+                       {
+                               sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
+                                               form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
+                               return;
+                       }
                        if (p_or_n != NOTICE && *text == '\001' &&
                                        strncasecmp(text + 1, "ACTION", 6))
                        {
@@ -662,121 +693,6 @@ expire_tgchange(void *unused)
        }
 }
 
-/* checks if source_p is allowed to send to target_p */
-static int
-add_target(struct Client *source_p, struct Client *target_p)
-{
-       int i, j;
-       uint32_t hashv;
-       uint32_t *targets;
-
-       /* can msg themselves or services without using any target slots */
-       if(source_p == target_p || IsService(target_p))
-               return 1;
-
-       /* special condition for those who have had PRIVMSG crippled to allow them
-        * to talk to IRCops still.
-        *
-        * XXX: is this controversial?
-        */
-       if(source_p->localClient->target_last > rb_current_time() && IsOper(target_p))
-               return 1;
-
-       hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32);
-       targets = source_p->localClient->targets;
-
-       /* check for existing target, and move it to the head */
-       for(i = 0; i < TGCHANGE_NUM + TGCHANGE_REPLY; i++)
-       {
-               if(targets[i] == hashv)
-               {
-                       for(j = i; j > 0; j--)
-                               targets[j] = targets[j - 1];
-                       targets[0] = hashv;
-                       return 1;
-               }
-       }
-
-       if(source_p->localClient->targets_free < TGCHANGE_NUM)
-       {
-               /* first message after connect, we may only start clearing
-                * slots after this message --anfl
-                */
-               if(!IsTGChange(source_p))
-               {
-                       SetTGChange(source_p);
-                       source_p->localClient->target_last = rb_current_time();
-               }
-               /* clear as many targets as we can */
-               else if((i = (rb_current_time() - source_p->localClient->target_last) / 60))
-               {
-                       if(i + source_p->localClient->targets_free > TGCHANGE_NUM)
-                               source_p->localClient->targets_free = TGCHANGE_NUM;
-                       else
-                               source_p->localClient->targets_free += i;
-
-                       source_p->localClient->target_last = rb_current_time();
-               }
-               /* cant clear any, full target list */
-               else if(source_p->localClient->targets_free == 0)
-               {
-                       ServerStats.is_tgch++;
-                       add_tgchange(source_p->sockhost);
-                       return 0;
-               }
-       }
-       /* no targets in use, reset their target_last so that they cant
-        * abuse a long idle to get targets back more quickly
-        */
-       else
-       {
-               source_p->localClient->target_last = rb_current_time();
-               SetTGChange(source_p);
-       }
-
-       for(i = TGCHANGE_NUM + TGCHANGE_REPLY - 1; i > 0; i--)
-               targets[i] = targets[i - 1];
-       targets[0] = hashv;
-       source_p->localClient->targets_free--;
-       return 1;
-}
-
-/* allows source_p to send to target_p */
-static void
-add_reply_target(struct Client *source_p, struct Client *target_p)
-{
-       int i, j;
-       uint32_t hashv;
-       uint32_t *targets;
-
-       /* can msg themselves or services without using any target slots */
-       if(source_p == target_p || IsService(target_p))
-               return;
-
-       hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32);
-       targets = source_p->localClient->targets;
-
-       /* check for existing target, and move it to the first reply slot
-        * if it is in a reply slot
-        */
-       for(i = 0; i < TGCHANGE_NUM + TGCHANGE_REPLY; i++)
-       {
-               if(targets[i] == hashv)
-               {
-                       if(i > TGCHANGE_NUM)
-                       {
-                               for(j = i; j > TGCHANGE_NUM; j--)
-                                       targets[j] = targets[j - 1];
-                               targets[TGCHANGE_NUM] = hashv;
-                       }
-                       return;
-               }
-       }
-       for(i = TGCHANGE_NUM + TGCHANGE_REPLY - 1; i > TGCHANGE_NUM; i--)
-               targets[i] = targets[i - 1];
-       targets[TGCHANGE_NUM] = hashv;
-}
-
 /*
  * msg_client
  *
@@ -843,8 +759,15 @@ msg_client(int p_or_n, const char *command,
 
        if(MyClient(target_p))
        {
+               if (IsSetNoCTCP(target_p) && p_or_n != NOTICE && *text == '\001' && strncasecmp(text + 1, "ACTION", 6))
+               {   
+                           sendto_one_numeric(source_p, ERR_NOCTCP,
+                                   form_str(ERR_NOCTCP),
+                                   target_p->name);
+               }
                /* XXX Controversial? allow opers always to send through a +g */
-               if(!IsServer(source_p) && (IsSetCallerId(target_p) ||
+               else if(!IsServer(source_p) && (IsSetCallerId(target_p) ||
+                                       (IsSetSCallerId(target_p) && !has_common_channel(source_p, target_p)) ||
                                        (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])))
                {
                        /* Here is the anti-flood bot/spambot code -db */
@@ -863,6 +786,13 @@ msg_client(int p_or_n, const char *command,
                                                        form_str(ERR_NONONREG),
                                                        target_p->name);
                        }
+                       else if (IsSetSCallerId(target_p) && !has_common_channel(source_p, target_p))
+                       {
+                               if (p_or_n != NOTICE)
+                                       sendto_one_numeric(source_p, ERR_NOCOMMONCHAN,
+                                                       form_str(ERR_NOCOMMONCHAN),
+                                                       target_p->name);
+                       }
                        else
                        {
                                /* check for accept, flag recipient incoming message */
@@ -902,21 +832,6 @@ msg_client(int p_or_n, const char *command,
        return;
 }
 
-static struct Channel *
-find_allowing_channel(struct Client *source_p, struct Client *target_p)
-{
-       rb_dlink_node *ptr;
-       struct membership *msptr;
-
-       RB_DLINK_FOREACH(ptr, source_p->user->channel.head)
-       {
-               msptr = ptr->data;
-               if (is_chanop_voiced(msptr) && IsMember(target_p, msptr->chptr))
-                       return msptr->chptr;
-       }
-       return NULL;
-}
-
 /*
  * flood_attack_client
  * inputs       - flag 0 if PRIVMSG 1 if NOTICE. RFC