X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fm_who.c;h=49df47580c393399ab9e97ae91a50dced6cc19a6;hb=refs%2Fheads%2Fupstream;hp=a9e68e2c3cd43a24a81f28314d23343d11b4d63a;hpb=0e3c217d90ea9af230a002e06104c147c54ab01a;p=ircu2.10.12-pk.git diff --git a/ircd/m_who.c b/ircd/m_who.c index a9e68e2..49df475 100644 --- a/ircd/m_who.c +++ b/ircd/m_who.c @@ -94,16 +94,15 @@ #include "numeric.h" #include "numnicks.h" #include "send.h" -#include "support.h" #include "whocmds.h" -#include +/* #include -- Now using assert in ircd_log.h */ #include /* - * 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) @@ -144,7 +143,7 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) 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 ? @@ -175,16 +174,21 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) while (((ch = *(p++))) && (ch != '%') && (ch != ',')) switch (ch) { + case 'd': + case 'D': + bitsel |= WHOSELECT_DELAY; + continue; case 'o': case 'O': bitsel |= WHOSELECT_OPER; continue; case 'x': case 'X': - bitsel |= WHOSELECT_EXTRA; - 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]); + if (HasPriv(sptr, PRIV_WHOX) && IsAnOper(sptr)) { + bitsel |= WHOSELECT_EXTRA; + 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': @@ -268,6 +272,10 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) case 'A': fields |= WHO_FIELD_ACC; break; + case 'o': + case 'O': + fields |= WHO_FIELD_OPL; + break; default: break; } @@ -321,11 +329,12 @@ 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) && (HasPriv(acptr, PRIV_DISPLAY) || - HasPriv(sptr, PRIV_SEE_OPERS)))) + if ((bitsel & WHOSELECT_OPER) && !SeeOper(sptr,acptr)) continue; - if ((acptr != sptr) && (member->status & CHFL_ZOMBIE)) + if ((acptr != sptr) + && ((member->status & CHFL_ZOMBIE) + || ((member->status & CHFL_DELAYED) + && !(bitsel & WHOSELECT_DELAY)))) continue; if (!(isthere || (SEE_USER(sptr, acptr, bitsel)))) continue; @@ -340,9 +349,7 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) else { if ((acptr = FindUser(nick)) && - ((!(bitsel & WHOSELECT_OPER)) || - (IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) || - HasPriv(sptr, PRIV_SEE_OPERS)))) && + ((!(bitsel & WHOSELECT_OPER)) || SeeOper(sptr,acptr)) && Process(acptr) && SHOW_MORE(sptr, counter)) { do_who(sptr, acptr, 0, fields, qrt); @@ -355,12 +362,14 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) 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; @@ -372,6 +381,8 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) 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 */ @@ -386,9 +397,7 @@ 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) && (HasPriv(acptr, PRIV_DISPLAY) || - HasPriv(sptr, PRIV_SEE_OPERS)))) + if ((bitsel & WHOSELECT_OPER) && !SeeOper(sptr,acptr)) continue; if ((mask) && ((!(matchsel & WHO_FIELD_NIC)) @@ -407,9 +416,9 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) || 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; @@ -424,9 +433,7 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { if (!(IsUser(acptr) && Process(acptr))) continue; - if ((bitsel & WHOSELECT_OPER) && - !(IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) || - HasPriv(sptr, PRIV_SEE_OPERS)))) + if ((bitsel & WHOSELECT_OPER) && !SeeOper(sptr,acptr)) continue; if (!(SEE_USER(sptr, acptr, bitsel))) continue; @@ -447,9 +454,9 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) || 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; @@ -460,11 +467,10 @@ 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'; - 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; }