IPv6 support (hopefully with fewer future transition pains)
[ircu2.10.12-pk.git] / ircd / whocmds.c
index 25f354519fcdb43b933cbba95a09df2a4bd52598..3e40dace532f24d7b12f4f99b2ae63dbacda9cbf 100644 (file)
@@ -30,7 +30,7 @@
 #include "hash.h"
 #include "ircd.h"
 #include "ircd_chattr.h"
-#include "ircd_policy.h"
+#include "ircd_features.h"
 #include "ircd_reply.h"
 #include "ircd_snprintf.h"
 #include "ircd_string.h"
@@ -122,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(&cli_ip(acptr));
     *(p1++) = ' ';
     while ((*p2) && (*(p1++) = *(p2++)));
   }
@@ -136,7 +138,9 @@ 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);
+    const char *p2 = (feature_bool(FEAT_HIS_WHO_SERVERNAME) && !IsAnOper(sptr)) ?
+                       feature_str(FEAT_HIS_SERVERNAME) :
+                       cli_name(cli_user(acptr)->server);
     *(p1++) = ' ';
     while ((*p2) && (*(p1++) = *(p2++)));
   }
@@ -155,8 +159,7 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
       *(p1++) = 'G';
     else
       *(p1++) = 'H';
-    if (IsAnOper(acptr) &&
-       (HasPriv(acptr, PRIV_DISPLAY) || HasPriv(sptr, PRIV_SEE_OPERS)))
+    if SeeOper(sptr,acptr)
       *(p1++) = '*';
     if (fields) {
       /* If you specified flags then we assume you know how to parse
@@ -189,6 +192,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))
@@ -196,25 +201,33 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
     *p1++ = ' ';
     if (!fields)
       *p1++ = ':';              /* Place colon here for default reply */
-#ifdef HEAD_IN_SAND_WHO_HOPCOUNT
-    strcat(p1, sptr == acptr ? "0" : "3");
-    p1++;
-#else
-    /* three digit hopcount maximum */
-    p1 += ircd_snprintf(0, p1, 3, "%d", cli_hopcount(acptr));
-#endif
+    if (feature_bool(FEAT_HIS_WHO_HOPCOUNT) && !IsAnOper(sptr))
+      *p1++ = (sptr == acptr) ? '0' : '3';
+    else
+      /* three digit hopcount maximum */
+      p1 += ircd_snprintf(0, p1, 3, "%d", cli_hopcount(acptr));
   }
 
   if (fields & WHO_FIELD_IDL)
   {
     *p1++ = ' ';
-    if (MyUser(acptr)) {
-           p1 += ircd_snprintf(0, p1, 11, "%d",
-                               CurrentTime - cli_user(acptr)->last);
-    }    
-    else {
-           *p1++ = '0';
-    }
+    if (MyUser(acptr) &&
+       (IsAnOper(sptr) || !feature_bool(FEAT_HIS_WHO_SERVERNAME) ||
+        acptr == sptr))
+      p1 += ircd_snprintf(0, p1, 11, "%d",
+                          CurrentTime - cli_user(acptr)->last);
+    else
+      *p1++ = '0';
+  }
+
+  if (fields & WHO_FIELD_ACC)
+  {
+    char *p2 = cli_user(acptr)->account;
+    *(p1++) = ' ';
+    if (*p2)
+      while ((*p2) && (*(p1++) = *(p2++)));
+    else
+      *(p1++) = '0';
   }
 
   if (!fields || (fields & WHO_FIELD_REN))
@@ -248,7 +261,7 @@ count_users(char *mask)
     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))));
+                 ircd_ntoa(&cli_ip(acptr)));
 
     if (!match(mask, namebuf) || !match(mask, ipbuf))
       count++;