Author: Kev <klmitch@mit.edu>
[ircu2.10.12-pk.git] / ircd / m_who.c
index a658fbd1c758e98d8645b890219f0ede7e983a8e..ecb27b4dc302e3a8239d1e6dbc7ebb5aaccd168f 100644 (file)
@@ -119,15 +119,15 @@ static void move_marker(void)
     struct Client *cptr = GlobalClientList;
     while (cptr)
     {
-      cptr->marker = 0;
-      cptr = cptr->next;
+      cli_marker(cptr) = 0;
+      cptr = cli_next(cptr);
     }
     who_marker++;
   }
 }
 
 #define CheckMark(x, y) ((x == y) ? 0 : (x = y))
-#define Process(cptr) CheckMark(cptr->marker, who_marker)
+#define Process(cptr) CheckMark(cli_marker(cptr), who_marker)
 
 /*
  * m_who - generic message handler
@@ -188,12 +188,9 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
         case 'x':
         case 'X':
           bitsel |= WHOSELECT_EXTRA;
-#ifdef WPATH
-          if (IsAnOper(sptr))
-            write_log(WPATH, "# " TIME_T_FMT " %s!%s@%s WHO %s %s\n",
-                CurrentTime, sptr->name, sptr->user->username, sptr->user->host,
-                (BadPtr(parv[3]) ? parv[1] : parv[3]), parv[2]);
-#endif /* WPATH */
+          if (HasPriv(sptr, PRIV_WHOX))
+           log_write(LS_WHO, L_INFO, LOG_NOSNOTICE, "%#C WHO %s %s", sptr,
+                     (BadPtr(parv[3]) ? parv[1] : parv[3]), parv[2]);
           continue;
         case 'n':
         case 'N':
@@ -319,7 +316,9 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
           for (member = chptr->members; member; member = member->next_member)
           {
             acptr = member->user;
-            if ((bitsel & WHOSELECT_OPER) && !(IsAnOper(acptr)))
+            if ((bitsel & WHOSELECT_OPER) &&
+               !(IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) ||
+                                     HasPriv(sptr, PRIV_SEE_OPERS))))
               continue;
             if ((acptr != sptr) && (member->status & CHFL_ZOMBIE))
               continue;
@@ -336,7 +335,9 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
       else
       {
         if ((acptr = FindUser(nick)) &&
-            ((!(bitsel & WHOSELECT_OPER)) || IsAnOper(acptr)) &&
+            ((!(bitsel & WHOSELECT_OPER)) ||
+            (IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) ||
+                                 HasPriv(sptr, PRIV_SEE_OPERS)))) &&
             Process(acptr) && SHOW_MORE(sptr, counter))
         {
           do_who(sptr, acptr, 0, fields, qrt);
@@ -372,7 +373,7 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     if ((!(counter < 1)) && matchsel) {
       struct Membership* member;
       struct Membership* chan;
-      for (chan = sptr->user->channel; chan; chan = chan->next_channel) {
+      for (chan = cli_user(sptr)->channel; chan; chan = chan->next_channel) {
         chptr = chan->channel;
         for (member = chptr->members; member; member = member->next_member)
         {
@@ -380,23 +381,25 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
           if (!(IsUser(acptr) && Process(acptr)))
             continue;           /* Now Process() is at the beginning, if we fail
                                    we'll never have to show this acptr in this query */
-          if ((bitsel & WHOSELECT_OPER) && !IsAnOper(acptr))
-            continue;
+         if ((bitsel & WHOSELECT_OPER) &&
+             !(IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) ||
+                                   HasPriv(sptr, PRIV_SEE_OPERS))))
+           continue;
           if ((mask) &&
               ((!(matchsel & WHO_FIELD_NIC))
-              || matchexec(acptr->name, mymask, minlen))
+              || matchexec(cli_name(acptr), mymask, minlen))
               && ((!(matchsel & WHO_FIELD_UID))
-              || matchexec(acptr->user->username, mymask, minlen))
+              || matchexec(cli_user(acptr)->username, mymask, minlen))
               && ((!(matchsel & WHO_FIELD_SER))
-              || (!(acptr->user->server->flags & FLAGS_MAP)))
+              || (!(cli_flags(cli_user(acptr)->server) & FLAGS_MAP)))
               && ((!(matchsel & WHO_FIELD_HOS))
-              || matchexec(acptr->user->host, mymask, minlen))
+              || matchexec(cli_user(acptr)->host, mymask, minlen))
               && ((!(matchsel & WHO_FIELD_REN))
-              || matchexec(acptr->info, mymask, minlen))
+              || matchexec(cli_info(acptr), mymask, minlen))
               && ((!(matchsel & WHO_FIELD_NIP))
-              || ((((acptr->ip.s_addr & imask.mask.s_addr) !=
+              || ((((cli_ip(acptr).s_addr & imask.mask.s_addr) !=
               imask.bits.s_addr)) || (imask.fall
-              && matchexec(ircd_ntoa((const char*) &acptr->ip), mymask, minlen)))))
+              && matchexec(ircd_ntoa((const char*) &(cli_ip(acptr))), mymask, minlen)))))
             continue;
           if (!SHOW_MORE(sptr, counter))
             break;
@@ -407,29 +410,31 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     /* Loop through all clients :-\, if we still have something to match to 
        and we can show more clients */
     if ((!(counter < 1)) && matchsel)
-      for (acptr = me.prev; acptr; acptr = acptr->prev)
+      for (acptr = cli_prev(&me); acptr; acptr = cli_prev(acptr))
       {
         if (!(IsUser(acptr) && Process(acptr)))
           continue;
-        if ((bitsel & WHOSELECT_OPER) && !IsAnOper(acptr))
-          continue;
+       if ((bitsel & WHOSELECT_OPER) &&
+           !(IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) ||
+                                 HasPriv(sptr, PRIV_SEE_OPERS))))
+         continue;
         if (!(SEE_USER(sptr, acptr, bitsel)))
           continue;
         if ((mask) &&
             ((!(matchsel & WHO_FIELD_NIC))
-            || matchexec(acptr->name, mymask, minlen))
+            || matchexec(cli_name(acptr), mymask, minlen))
             && ((!(matchsel & WHO_FIELD_UID))
-            || matchexec(acptr->user->username, mymask, minlen))
+            || matchexec(cli_user(acptr)->username, mymask, minlen))
             && ((!(matchsel & WHO_FIELD_SER))
-            || (!(acptr->user->server->flags & FLAGS_MAP)))
+            || (!(cli_flags(cli_user(acptr)->server) & FLAGS_MAP)))
             && ((!(matchsel & WHO_FIELD_HOS))
-            || matchexec(acptr->user->host, mymask, minlen))
+            || matchexec(cli_user(acptr)->host, mymask, minlen))
             && ((!(matchsel & WHO_FIELD_REN))
-            || matchexec(acptr->info, mymask, minlen))
+            || matchexec(cli_info(acptr), mymask, minlen))
             && ((!(matchsel & WHO_FIELD_NIP))
-            || ((((acptr->ip.s_addr & imask.mask.s_addr) != imask.bits.s_addr))
+            || ((((cli_ip(acptr).s_addr & imask.mask.s_addr) != imask.bits.s_addr))
             || (imask.fall
-            && matchexec(ircd_ntoa((const char*) &acptr->ip), mymask, minlen)))))
+            && matchexec(ircd_ntoa((const char*) &(cli_ip(acptr))), mymask, minlen)))))
           continue;
         if (!SHOW_MORE(sptr, counter))
           break;
@@ -440,12 +445,11 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   /* Make a clean mask suitable to be sent in the "end of" */
   if (mask && (p = strchr(mask, ' ')))
     *p = '\0';
-  sendto_one(sptr, rpl_str(RPL_ENDOFWHO),
-      me.name, parv[0], BadPtr(mask) ? "*" : mask);
+  send_reply(sptr, RPL_ENDOFWHO, BadPtr(mask) ? "*" : mask);
 
   /* Notify the user if we decided that his query was too long */
   if (counter < 0)
-    sendto_one(sptr, err_str(ERR_QUERYTOOLONG), me.name, parv[0], "WHO");
+    send_reply(sptr, ERR_QUERYTOOLONG, "WHO");
 
   return 0;
 }
@@ -514,7 +518,7 @@ int m_who(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
           bitsel |= WHOSELECT_EXTRA;
 #ifdef WPATH
           if (IsAnOper(sptr))
-            write_log(WPATH, "# " TIME_T_FMT " %s!%s@%s WHO %s %s\n",
+            write_log(WPATH, "# " TIME_T_FMT " %s!%s@%s WHO %s %s\n", /* XXX DEAD */
                 CurrentTime, sptr->name, sptr->user->username, sptr->user->host,
                 (BadPtr(parv[3]) ? parv[1] : parv[3]), parv[2]);
 #endif /* WPATH */
@@ -761,12 +765,12 @@ int m_who(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
   /* Make a clean mask suitable to be sent in the "end of" */
   if (mask && (p = strchr(mask, ' ')))
     *p = '\0';
-  sendto_one(sptr, rpl_str(RPL_ENDOFWHO),
+  sendto_one(sptr, rpl_str(RPL_ENDOFWHO), /* XXX DEAD */
       me.name, parv[0], BadPtr(mask) ? "*" : mask);
 
   /* Notify the user if we decided that his query was too long */
   if (counter < 0)
-    sendto_one(sptr, err_str(ERR_QUERYTOOLONG), me.name, parv[0], "WHO");
+    sendto_one(sptr, err_str(ERR_QUERYTOOLONG), me.name, parv[0], "WHO"); /* XXX DEAD */
 
   return 0;
 }