Author: Ghostwolf <foxxe@wtfs.net>
[ircu2.10.12-pk.git] / ircd / send.c
index 8f17ee6cfbd5c07c5beb95dd85d18b966393787b..2ba06e4993977d84dd347b159dbe57a833f607e9 100644 (file)
@@ -26,6 +26,7 @@
 #include "class.h"
 #include "client.h"
 #include "ircd.h"
+#include "ircd_policy.h"
 #include "ircd_snprintf.h"
 #include "ircd_string.h"
 #include "list.h"
@@ -215,12 +216,13 @@ void send_buffer(struct Client* to, struct MsgBuf* buf, int prio)
  *  addition -- Armin, 8jun90 (gruner@informatik.tu-muenchen.de)
  */
 
-static int match_it(struct Client *one, const char *mask, int what)
+static int match_it(struct Client *from, struct Client *one, const char *mask, int what)
 {
   switch (what)
   {
     case MATCH_HOST:
-      return (match(mask, cli_user(one)->host) == 0);
+      return (match(mask, cli_user(one)->host) == 0 ||
+        (HasHiddenHost(one) && match(mask, cli_user(one)->realhost) == 0));
     case MATCH_SERVER:
     default:
       return (match(mask, cli_name(cli_user(one)->server)) == 0);
@@ -330,6 +332,8 @@ void sendcmdto_serv_butone(struct Client *from, const char *cmd,
  * Send a (prefix) command originating from <from> to all channels
  * <from> is locally on.  <from> must be a user. <tok> is ignored in
  * this function.
+ *
+ * Update: don't send to 'one', if any. --Vampire
  */
 /* XXX sentalong_marker used XXX
  *
@@ -343,8 +347,9 @@ void sendcmdto_serv_butone(struct Client *from, const char *cmd,
  * message to, and then a final loop through the connected servers
  * to delete the flag. -Kev
  */
-void sendcmdto_common_channels(struct Client *from, const char *cmd,
-                              const char *tok, const char *pattern, ...)
+void sendcmdto_common_channels_butone(struct Client *from, const char *cmd,
+                                     const char *tok, struct Client *one,
+                                     const char *pattern, ...)
 {
   struct VarData vd;
   struct MsgBuf *mb;
@@ -370,16 +375,20 @@ void sendcmdto_common_channels(struct Client *from, const char *cmd,
   /*
    * loop through from's channels, and the members on their channels
    */
-  for (chan = cli_user(from)->channel; chan; chan = chan->next_channel)
+  for (chan = cli_user(from)->channel; chan; chan = chan->next_channel) {
+    if (IsZombie(chan))
+      continue;
     for (member = chan->channel->members; member;
         member = member->next_member)
       if (MyConnect(member->user) && -1 < cli_fd(cli_from(member->user)) &&
+          member->user != one &&
          sentalong[cli_fd(cli_from(member->user))] != sentalong_marker) {
        sentalong[cli_fd(cli_from(member->user))] = sentalong_marker;
        send_buffer(member->user, mb, 0);
       }
+  }
 
-  if (MyConnect(from))
+  if (MyConnect(from) && from != one)
     send_buffer(from, mb, 0);
 
   msgq_clean(mb);
@@ -388,10 +397,13 @@ void sendcmdto_common_channels(struct Client *from, const char *cmd,
 /*
  * Send a (prefixed) command to all local users on the channel specified
  * by <to>; <tok> is ignored by this function
+ *
+ * Update: don't send to 'one', if any. --Vampire
  */
-void sendcmdto_channel_butserv(struct Client *from, const char *cmd,
-                              const char *tok, struct Channel *to,
-                              const char *pattern, ...)
+void sendcmdto_channel_butserv_butone(struct Client *from, const char *cmd,
+                                     const char *tok, struct Channel *to,
+                                     struct Client *one, const char *pattern,
+                                     ...)
 {
   struct VarData vd;
   struct MsgBuf *mb;
@@ -406,7 +418,7 @@ void sendcmdto_channel_butserv(struct Client *from, const char *cmd,
 
   /* send the buffer to each local channel member */
   for (member = to->members; member; member = member->next_member) {
-    if (MyConnect(member->user) && !IsZombie(member))
+    if (MyConnect(member->user) && member->user != one && !IsZombie(member))
       send_buffer(member->user, mb, 0);
   }
 
@@ -519,7 +531,12 @@ void sendwallto_group_butone(struct Client *from, int type, struct Client *one,
     if (!(cptr = LocalClientArray[i]) ||
        (cli_fd(cli_from(cptr)) < 0) ||
        (type == WALL_DESYNCH && !(cli_flags(cptr) & FLAGS_DEBUG)) ||
+#ifdef HEAD_IN_SAND_WALLOPS
+       (type == WALL_WALLOPS && (!(cli_flags(cptr) & FLAGS_WALLOP) ||
+                                 !IsAnOper(cptr))) ||
+#else
        (type == WALL_WALLOPS && !(cli_flags(cptr) & FLAGS_WALLOP)) ||
+#endif
         (type == WALL_WALLUSERS && !(cli_flags(cptr) & FLAGS_WALLOP)))
       continue; /* skip it */
     send_buffer(cptr, mb, 1);
@@ -586,7 +603,7 @@ void sendcmdto_match_butone(struct Client *from, const char *cmd,
   sentalong_marker++;
   for (cptr = GlobalClientList; cptr; cptr = cli_next(cptr)) {
     if (!IsRegistered(cptr) || cli_from(cptr) == one || IsServer(cptr) ||
-       IsMe(cptr) || !match_it(cptr, to, who) || cli_fd(cli_from(cptr)) < 0 ||
+       IsMe(cptr) || !match_it(from, cptr, to, who) || cli_fd(cli_from(cptr)) < 0 ||
        sentalong[cli_fd(cli_from(cptr))] == sentalong_marker)
       continue; /* skip it */
     sentalong[cli_fd(cli_from(cptr))] = sentalong_marker;