]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/core/m_message.c
Update NEWS.
[irc/rqf/shadowircd.git] / modules / core / m_message.c
index 16a40a4fc6af5bd223dd580254908dbcf5b70675..f22450db4aa733942597dafac9eeac1f2b6de581 100644 (file)
@@ -90,6 +90,7 @@ 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);
@@ -476,7 +477,8 @@ msg_channel(int p_or_n, const char *command,
        }
        else if(chptr->mode.mode & MODE_OPMODERATE &&
                        chptr->mode.mode & MODE_MODERATED &&
-                       IsMember(source_p, chptr))
+                       (!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
+                        IsMember(source_p, chptr)))
        {
                /* only do +z for +m channels for now, as bans/quiets
                 * aren't tested for remote clients -- jilles */
@@ -648,6 +650,8 @@ static void
 msg_client(int p_or_n, const char *command,
           struct Client *source_p, struct Client *target_p, const char *text)
 {
+       int do_floodcount = 0;
+
        if(MyClient(source_p))
        {
                /* reset idle time for message only if its not to self 
@@ -655,12 +659,16 @@ msg_client(int p_or_n, const char *command,
                if(p_or_n != NOTICE)
                        source_p->localClient->last = rb_current_time();
 
+               /* auto cprivmsg/cnotice */
+               do_floodcount = !IsOper(source_p) &&
+                       !find_allowing_channel(source_p, target_p);
+
                /* target change stuff, dont limit ctcp replies as that
                 * would allow people to start filling up random users
                 * targets just by ctcping them
                 */
                if((p_or_n != NOTICE || *text != '\001') &&
-                  ConfigFileEntry.target_change && !IsOper(source_p))
+                  ConfigFileEntry.target_change && do_floodcount)
                {
                        if(!add_target(source_p, target_p))
                        {
@@ -703,7 +711,7 @@ msg_client(int p_or_n, const char *command,
                                                        form_str(ERR_NONONREG),
                                                        target_p->name);
                                /* Only so opers can watch for floods */
-                               if (MyClient(source_p))
+                               if (do_floodcount)
                                        (void) flood_attack_client(p_or_n, source_p, target_p);
                        }
                        else
@@ -731,7 +739,7 @@ msg_client(int p_or_n, const char *command,
                                        target_p->localClient->last_caller_id_time = rb_current_time();
                                }
                                /* Only so opers can watch for floods */
-                               if (MyClient(source_p))
+                               if (do_floodcount)
                                        (void) flood_attack_client(p_or_n, source_p, target_p);
                        }
                }
@@ -742,18 +750,33 @@ msg_client(int p_or_n, const char *command,
                         * we dont give warnings.. we then check if theyre opered 
                         * (to avoid flood warnings), lastly if theyre our client
                         * and flooding    -- fl */
-                       if(!MyClient(source_p) || IsOper(source_p) ||
+                       if(!do_floodcount ||
                           !flood_attack_client(p_or_n, source_p, target_p))
                                sendto_anywhere(target_p, source_p, command, ":%s", text);
                }
        }
-       else if(!MyClient(source_p) || IsOper(source_p) ||
+       else if(!do_floodcount ||
                !flood_attack_client(p_or_n, source_p, target_p))
                sendto_anywhere(target_p, source_p, command, ":%s", text);
 
        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
@@ -894,7 +917,6 @@ handle_special(int p_or_n, const char *command, struct Client *client_p,
        struct Client *target_p;
        char *server;
        char *s;
-       int count;
 
        /* user[%host]@server addressed?
         * NOTE: users can send to user@server, but not user%host@server
@@ -909,8 +931,6 @@ handle_special(int p_or_n, const char *command, struct Client *client_p,
                        return;
                }
 
-               count = 0;
-
                if(!IsOper(source_p))
                {
                        if(strchr(nick, '%') || (strncmp(nick, "opers", 5) == 0))