#include "numeric.h"
#include "numnicks.h"
#include "send.h"
-#include "support.h"
#include "whocmds.h"
-#include <assert.h>
+/* #include <assert.h> -- Now using assert in ircd_log.h */
#include <string.h>
/*
- * A little spin-marking utility to tell us wich clients we have already
- * processed and wich not
+ * A little spin-marking utility to tell us which clients we have already
+ * processed and which not
*/
static int who_marker = 0;
static void move_marker(void)
struct Client *acptr; /* Client to show */
int bitsel; /* Mask of selectors to apply */
- int matchsel; /* Wich fields the match should apply on */
+ int matchsel; /* Which fields the match should apply on */
int counter; /* Query size counter,
initially used to count fields */
int commas; /* Does our mask contain any comma ?
while (((ch = *(p++))) && (ch != '%') && (ch != ','))
switch (ch)
{
+ case 'd':
+ case 'D':
+ bitsel |= WHOSELECT_DELAY;
+ continue;
case 'o':
case 'O':
bitsel |= WHOSELECT_OPER;
case 'A':
fields |= WHO_FIELD_ACC;
break;
+ case 'o':
+ case 'O':
+ fields |= WHO_FIELD_OPL;
+ break;
default:
break;
}
acptr = member->user;
if ((bitsel & WHOSELECT_OPER) && !SeeOper(sptr,acptr))
continue;
- if ((acptr != sptr) && (member->status & (CHFL_ZOMBIE | CHFL_DELAYED)))
+ if ((acptr != sptr)
+ && ((member->status & CHFL_ZOMBIE)
+ || ((member->status & CHFL_DELAYED)
+ && !(bitsel & WHOSELECT_DELAY))))
continue;
if (!(isthere || (SEE_USER(sptr, acptr, bitsel))))
continue;
real mask and try to match all relevant fields */
if (!(commas || (counter < 1)))
{
+ struct irc_in_addr imask;
int minlen, cset;
- static struct in_mask imask;
+ unsigned char ibits;
+
if (mask)
{
matchcomp(mymask, &minlen, &cset, mask);
- if (matchcompIP(&imask, mask))
+ if (!ipmask_parse(mask, &imask, &ibits))
matchsel &= ~WHO_FIELD_NIP;
if ((minlen > NICKLEN) || !(cset & NTL_IRCNK))
matchsel &= ~WHO_FIELD_NIC;
matchsel &= ~WHO_FIELD_UID;
if ((minlen > HOSTLEN) || !(cset & NTL_IRCHN))
matchsel &= ~WHO_FIELD_HOS;
+ if ((minlen > ACCOUNTLEN))
+ matchsel &= ~WHO_FIELD_ACC;
}
/* First of all loop through the clients in common channels */
|| matchexec(cli_info(acptr), mymask, minlen))
&& ((!(matchsel & WHO_FIELD_NIP))
|| (HasHiddenHost(acptr) && !IsAnOper(sptr))
- || ((((cli_ip(acptr).s_addr & imask.mask.s_addr) !=
- imask.bits.s_addr)) || (imask.fall
- && matchexec(ircd_ntoa((const char*) &(cli_ip(acptr))), mymask, minlen)))))
+ || !ipmask_check(&cli_ip(acptr), &imask, ibits))
+ && ((!(matchsel & WHO_FIELD_ACC))
+ || matchexec(cli_user(acptr)->account, mymask, minlen)))
continue;
if (!SHOW_MORE(sptr, counter))
break;
|| matchexec(cli_info(acptr), mymask, minlen))
&& ((!(matchsel & WHO_FIELD_NIP))
|| (HasHiddenHost(acptr) && !IsAnOper(sptr))
- || ((((cli_ip(acptr).s_addr & imask.mask.s_addr) != imask.bits.s_addr))
- || (imask.fall
- && matchexec(ircd_ntoa((const char*) &(cli_ip(acptr))), mymask, minlen)))))
+ || !ipmask_check(&cli_ip(acptr), &imask, ibits))
+ && ((!(matchsel & WHO_FIELD_ACC))
+ || matchexec(cli_user(acptr)->account, mymask, minlen)))
continue;
if (!SHOW_MORE(sptr, counter))
break;
/* Make a clean mask suitable to be sent in the "end of" */
if (mask && (p = strchr(mask, ' ')))
*p = '\0';
- send_reply(sptr, RPL_ENDOFWHO, BadPtr(mask) ? "*" : mask);
-
/* Notify the user if we decided that his query was too long */
if (counter < 0)
- send_reply(sptr, ERR_QUERYTOOLONG, "WHO");
+ send_reply(sptr, ERR_QUERYTOOLONG, BadPtr(mask) ? "*" : mask);
+ send_reply(sptr, RPL_ENDOFWHO, BadPtr(mask) ? "*" : mask);
return 0;
}