Author: Alex Badea <vampire@p16.pub.ro> (by way of Kev <klmitch@mit.edu>)
[ircu2.10.12-pk.git] / ircd / whocmds.c
index 775ad39dcf77df1e94c7b1dbdd068b5c1f9a824e..fa8def4b5be396fc45af8c3d7f2529d9c7bc837d 100644 (file)
  *
  * $Id$
  */
+#include "config.h"
+
 #include "whocmds.h"
 #include "channel.h"
 #include "client.h"
 #include "hash.h"
 #include "ircd.h"
 #include "ircd_chattr.h"
+#include "ircd_policy.h"
 #include "ircd_reply.h"
+#include "ircd_snprintf.h"
 #include "ircd_string.h"
 #include "list.h"
 #include "match.h"
@@ -41,7 +45,6 @@
 #include "s_misc.h"
 #include "s_user.h"
 #include "send.h"
-#include "sprintf_irc.h"
 #include "struct.h"
 #include "support.h"
 #include "sys.h"
@@ -119,7 +122,9 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
 
   if (fields & WHO_FIELD_NIP)
   {
-    const char* p2 = ircd_ntoa((const char*) &(cli_ip(acptr)));
+    const char* p2 = HasHiddenHost(acptr) && !IsAnOper(sptr) ?
+      feature_str(FEAT_HIDDEN_IP) :
+      ircd_ntoa((const char*) &(cli_ip(acptr)));
     *(p1++) = ' ';
     while ((*p2) && (*(p1++) = *(p2++)));
   }
@@ -133,7 +138,15 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
 
   if (!fields || (fields & WHO_FIELD_SER))
   {
-    char *p2 = cli_name(cli_user(acptr)->server);
+    char *p2;
+#ifdef HEAD_IN_SAND_WHO_SERVERNAME
+    if (IsAnOper(sptr))
+#endif
+      p2 = cli_name(cli_user(acptr)->server);
+#ifdef HEAD_IN_SAND_WHO_SERVERNAME
+    else
+      p2 = HEAD_IN_SAND_SERVERNAME;
+#endif
     *(p1++) = ' ';
     while ((*p2) && (*(p1++) = *(p2++)));
   }
@@ -152,7 +165,8 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
       *(p1++) = 'G';
     else
       *(p1++) = 'H';
-    if (IsAnOper(acptr))
+    if (IsAnOper(acptr) &&
+       (HasPriv(acptr, PRIV_DISPLAY) || HasPriv(sptr, PRIV_SEE_OPERS)))
       *(p1++) = '*';
     if (fields) {
       /* If you specified flags then we assume you know how to parse
@@ -185,6 +199,8 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
       if (SendDebug(acptr))
         *(p1++) = 'g';
     }
+    if (HasHiddenHost(acptr))
+      *(p1++) = 'x';
   }
 
   if (!fields || (fields & WHO_FIELD_DIS))
@@ -192,14 +208,20 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
     *p1++ = ' ';
     if (!fields)
       *p1++ = ':';              /* Place colon here for default reply */
-    p1 = sprintf_irc(p1, "%d", cli_hopcount(acptr));
+#ifdef HEAD_IN_SAND_WHO_HOPCOUNT
+    *p1++ = (sptr == acptr) ? '0' : '3';
+#else
+    /* three digit hopcount maximum */
+    p1 += ircd_snprintf(0, p1, 3, "%d", cli_hopcount(acptr));
+#endif
   }
 
   if (fields & WHO_FIELD_IDL)
   {
     *p1++ = ' ';
     if (MyUser(acptr)) {
-           p1 = sprintf_irc(p1, "%d", CurrentTime - cli_user(acptr)->last);
+           p1 += ircd_snprintf(0, p1, 11, "%d",
+                               CurrentTime - cli_user(acptr)->last);
     }    
     else {
            *p1++ = '0';
@@ -222,3 +244,26 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
   send_reply(sptr, fields ? RPL_WHOSPCRPL : RPL_WHOREPLY, ++p1);
 }
 
+int
+count_users(char *mask)
+{
+  struct Client *acptr;
+  int count = 0;
+  char namebuf[USERLEN + HOSTLEN + 2];
+  char ipbuf[USERLEN + 16 + 2];
+
+  for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) {
+    if (!IsUser(acptr))
+      continue;
+
+    ircd_snprintf(0, namebuf, sizeof(namebuf), "%s@%s",
+                 cli_user(acptr)->username, cli_user(acptr)->host);
+    ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%s@%s", cli_user(acptr)->username,
+                 ircd_ntoa((const char *) &(cli_ip(acptr))));
+
+    if (!match(mask, namebuf) || !match(mask, ipbuf))
+      count++;
+  }
+
+  return count;
+}