* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
- *
- * $Id$
*/
+#include "config.h"
+
#include "whocmds.h"
-#include "IPcheck.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"
!IsChannelService(acptr))
{
struct Membership* chan;
- for (chan = acptr->user->channel; chan && !chptr; chan = chan->next_channel)
+ for (chan = cli_user(acptr)->channel; chan && !chptr; chan = chan->next_channel)
if (PubChannel(chan->channel) &&
(acptr == sptr || !IsZombie(chan)))
chptr = chan->channel;
if (!fields || (fields & WHO_FIELD_UID))
{
- char *p2 = acptr->user->username;
+ char *p2 = cli_user(acptr)->username;
*(p1++) = ' ';
while ((*p2) && (*(p1++) = *(p2++)));
}
if (fields & WHO_FIELD_NIP)
{
- const char* p2 = ircd_ntoa((const char*) &acptr->ip);
+ const char* p2 = ircd_ntoa((const char*) &(cli_ip(acptr)));
*(p1++) = ' ';
while ((*p2) && (*(p1++) = *(p2++)));
}
if (!fields || (fields & WHO_FIELD_HOS))
{
- char *p2 = acptr->user->host;
+ char *p2 = cli_user(acptr)->host;
*(p1++) = ' ';
while ((*p2) && (*(p1++) = *(p2++)));
}
if (!fields || (fields & WHO_FIELD_SER))
{
- char *p2 = acptr->user->server->name;
+ char *p2 = cli_name(cli_user(acptr)->server);
*(p1++) = ' ';
while ((*p2) && (*(p1++) = *(p2++)));
}
if (!fields || (fields & WHO_FIELD_NIC))
{
- char *p2 = acptr->name;
+ char *p2 = cli_name(acptr);
*(p1++) = ' ';
while ((*p2) && (*(p1++) = *(p2++)));
}
if (!fields || (fields & WHO_FIELD_FLA))
{
*(p1++) = ' ';
- if (acptr->user->away)
+ if (cli_user(acptr)->away)
*(p1++) = 'G';
else
*(p1++) = 'H';
- if (IsAnOper(acptr))
+ if (IsAnOper(acptr) &&
+ (HasPriv(acptr, PRIV_DISPLAY) || HasPriv(sptr, PRIV_SEE_OPERS)))
*(p1++) = '*';
- if (chptr && is_chan_op(acptr, chptr))
- *(p1++) = '@';
- else if (chptr && has_voice(acptr, chptr))
- *(p1++) = '+';
- else if (chptr && is_zombie(acptr, chptr))
- *(p1++) = '!';
+ if (fields) {
+ /* If you specified flags then we assume you know how to parse
+ * multiple channel status flags, as this is currently the only
+ * way to know if someone has @'s *and* is +'d.
+ */
+ if (chptr && is_chan_op(acptr, chptr))
+ *(p1++) = '@';
+ if (chptr && has_voice(acptr, chptr))
+ *(p1++) = '+';
+ if (chptr && is_zombie(acptr, chptr))
+ *(p1++) = '!';
+ }
+ else {
+ if (chptr && is_chan_op(acptr, chptr))
+ *(p1++) = '@';
+ else if (chptr && has_voice(acptr, chptr))
+ *(p1++) = '+';
+ else if (chptr && is_zombie(acptr, chptr))
+ *(p1++) = '!';
+ }
if (IsDeaf(acptr))
*(p1++) = 'd';
if (IsAnOper(sptr))
*p1++ = ' ';
if (!fields)
*p1++ = ':'; /* Place colon here for default reply */
- p1 = sprintf_irc(p1, "%d", acptr->hopcount);
+#ifdef HEAD_IN_SAND_WHO_HOPCOUNT
+ strcat(p1, sptr == acptr ? "0" : "3");
+ p1++;
+#else
+ p1 = sprintf_irc(p1, "%d", cli_hopcount(acptr));
+#endif
+ }
+
+ if (fields & WHO_FIELD_IDL)
+ {
+ *p1++ = ' ';
+ if (MyUser(acptr)) {
+ p1 = sprintf_irc(p1, "%d", CurrentTime - cli_user(acptr)->last);
+ }
+ else {
+ *p1++ = '0';
+ }
}
if (!fields || (fields & WHO_FIELD_REN))
{
- char *p2 = acptr->info;
+ char *p2 = cli_info(acptr);
*p1++ = ' ';
if (fields)
*p1++ = ':'; /* Place colon here for special reply */
need to terminate buf1 */
*p1 = '\0';
p1 = buf1;
- sendto_one(sptr, rpl_str(fields ? RPL_WHOSPCRPL : RPL_WHOREPLY),
- me.name, sptr->name, ++p1);
+ 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;
+}