]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/core/m_message.c
Revert all presence-related changes
[irc/rqf/shadowircd.git] / modules / core / m_message.c
index 658a2a309752742fa4655d3f086beb43010bde6b..c89325038f371b03baf279ff3df74b64b5049b6c 100644 (file)
@@ -95,10 +95,14 @@ static int flood_attack_client(int p_or_n, struct Client *source_p, struct Clien
 static int flood_attack_channel(int p_or_n, struct Client *source_p,
                                struct Channel *chptr, char *chname);
 
+/* Fifteen seconds should be plenty for a client to reply a ctcp */
+#define LARGE_CTCP_TIME 15
+
 #define ENTITY_NONE    0
 #define ENTITY_CHANNEL 1
-#define ENTITY_CHANOPS_ON_CHANNEL 2
-#define ENTITY_CLIENT  3
+#define ENTITY_CHANNEL_OPMOD 2
+#define ENTITY_CHANOPS_ON_CHANNEL 3
+#define ENTITY_CLIENT  4
 
 static struct entity targets[512];
 static int ntargets = 0;
@@ -109,6 +113,11 @@ static void msg_channel(int p_or_n, const char *command,
                        struct Client *client_p,
                        struct Client *source_p, struct Channel *chptr, const char *text);
 
+static void msg_channel_opmod(int p_or_n, const char *command,
+                             struct Client *client_p,
+                             struct Client *source_p, struct Channel *chptr,
+                             const char *text);
+
 static void msg_channel_flags(int p_or_n, const char *command,
                              struct Client *client_p,
                              struct Client *source_p,
@@ -204,6 +213,11 @@ m_message(int p_or_n,
                                    (struct Channel *) targets[i].ptr, parv[2]);
                        break;
 
+               case ENTITY_CHANNEL_OPMOD:
+                       msg_channel_opmod(p_or_n, command, client_p, source_p,
+                                  (struct Channel *) targets[i].ptr, parv[2]);
+                       break;
+
                case ENTITY_CHANOPS_ON_CHANNEL:
                        msg_channel_flags(p_or_n, command, client_p, source_p,
                                          (struct Channel *) targets[i].ptr,
@@ -350,7 +364,9 @@ build_target_list(int p_or_n, const char *command, struct Client *client_p,
                                if(!IsServer(source_p) && !IsService(source_p) && !is_chanop_voiced(msptr))
                                {
                                        sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
-                                                  me.name, source_p->name, with_prefix);
+                                                  get_id(&me, source_p),
+                                                  get_id(source_p, source_p),
+                                                  with_prefix);
                                        return (-1);
                                }
 
@@ -382,6 +398,32 @@ build_target_list(int p_or_n, const char *command, struct Client *client_p,
                        continue;
                }
 
+               if(IsServer(client_p) && *nick == '=' && nick[1] == '#')
+               {
+                       nick++;
+                       if((chptr = find_channel(nick)) != NULL)
+                       {
+                               if(!duplicate_ptr(chptr))
+                               {
+                                       if(ntargets >= ConfigFileEntry.max_targets)
+                                       {
+                                               sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
+                                                          me.name, source_p->name, nick);
+                                               return (1);
+                                       }
+                                       targets[ntargets].ptr = (void *) chptr;
+                                       targets[ntargets++].type = ENTITY_CHANNEL_OPMOD;
+                               }
+                       }
+
+                       /* non existant channel */
+                       else if(p_or_n != NOTICE)
+                               sendto_one_numeric(source_p, ERR_NOSUCHNICK,
+                                                  form_str(ERR_NOSUCHNICK), nick);
+
+                       continue;
+               }
+
                /* no matching anything found - error if not NOTICE */
                if(p_or_n != NOTICE)
                {
@@ -473,18 +515,71 @@ msg_channel(int p_or_n, const char *command,
                {
                        sendto_channel_flags(client_p, ALL_MEMBERS, source_p, chptr,
                                             "%s %s :%s", command, chptr->chname, text);
+                       if (p_or_n != NOTICE && *text == '\001' &&
+                                       rb_dlink_list_length(&chptr->locmembers) > (unsigned)(GlobalSetOptions.floodcount / 2))
+                               source_p->large_ctcp_sent = rb_current_time();
                }
        }
        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 */
                if(!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
                {
-                       sendto_channel_flags(client_p, ONLY_CHANOPS, source_p, chptr,
-                                            "%s %s :%s", command, chptr->chname, text);
+                       sendto_channel_opmod(client_p, source_p, chptr,
+                                            command, text);
+               }
+       }
+       else
+       {
+               if(p_or_n != NOTICE)
+                       sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
+                                          form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
+       }
+}
+/*
+ * msg_channel_opmod
+ *
+ * inputs      - flag privmsg or notice
+ *             - pointer to command "PRIVMSG" or "NOTICE"
+ *             - pointer to client_p
+ *             - pointer to source_p
+ *             - pointer to channel
+ * output      - NONE
+ * side effects        - message given channel ops
+ *
+ * XXX - We need to rework this a bit, it's a tad ugly. --nenolod
+ */
+static void
+msg_channel_opmod(int p_or_n, const char *command,
+                 struct Client *client_p, struct Client *source_p,
+                 struct Channel *chptr, const char *text)
+{
+       char text2[BUFSIZE];
+
+       if(chptr->mode.mode & MODE_NOCOLOR)
+       {
+               rb_strlcpy(text2, text, BUFSIZE);
+               strip_colour(text2);
+               text = text2;
+               if (EmptyString(text))
+               {
+                       /* could be empty after colour stripping and
+                        * that would cause problems later */
+                       if(p_or_n != NOTICE)
+                               sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), me.name, source_p->name);
+                       return;
+               }
+       }
+
+       if(chptr->mode.mode & MODE_OPMODERATE &&
+                       (!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
+                        IsMember(source_p, chptr)))
+       {
+               if(!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
+               {
+                       sendto_channel_opmod(client_p, source_p, chptr,
+                                            command, text);
                }
        }
        else
@@ -676,6 +771,14 @@ msg_client(int p_or_n, const char *command,
                                return;
                        }
                }
+
+               if (do_floodcount && p_or_n == NOTICE && *text == '\001' &&
+                               target_p->large_ctcp_sent + LARGE_CTCP_TIME >= rb_current_time())
+                       do_floodcount = 0;
+
+               if (do_floodcount &&
+                               flood_attack_client(p_or_n, source_p, target_p))
+                       return;
        }
        else if(source_p->from == target_p->from)
        {
@@ -709,9 +812,6 @@ msg_client(int p_or_n, const char *command,
                                        sendto_one_numeric(source_p, ERR_NONONREG,
                                                        form_str(ERR_NONONREG),
                                                        target_p->name);
-                               /* Only so opers can watch for floods */
-                               if (do_floodcount)
-                                       (void) flood_attack_client(p_or_n, source_p, target_p);
                        }
                        else
                        {
@@ -737,25 +837,12 @@ 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 (do_floodcount)
-                                       (void) flood_attack_client(p_or_n, source_p, target_p);
                        }
                }
                else
-               {
-                       /* If the client is remote, we dont perform a special check for
-                        * flooding.. as we wouldnt block their message anyway.. this means
-                        * we dont give warnings.. we then check if theyre opered 
-                        * (to avoid flood warnings), lastly if theyre our client
-                        * and flooding    -- fl */
-                       if(!do_floodcount ||
-                          !flood_attack_client(p_or_n, source_p, target_p))
-                               sendto_anywhere(target_p, source_p, command, ":%s", text);
-               }
+                       sendto_anywhere(target_p, source_p, command, ":%s", text);
        }
-       else if(!do_floodcount ||
-               !flood_attack_client(p_or_n, source_p, target_p))
+       else
                sendto_anywhere(target_p, source_p, command, ":%s", text);
 
        return;
@@ -1012,6 +1099,8 @@ handle_special(int p_or_n, const char *command, struct Client *client_p,
                                    nick + 1,
                                    (*nick == '#') ? MATCH_HOST : MATCH_SERVER,
                                    "%s $%s :%s", command, nick, text);
+               if (p_or_n != NOTICE && *text == '\001')
+                       source_p->large_ctcp_sent = rb_current_time();
                return;
        }
 }