- int n_list = 0;
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- Ptr = i->second->chans[0].channel;
- // suggested by phidjit and FCS
- if ((!common_channels(user,i->second)) && (isnick(i->second->nick)))
- {
- // Bug Fix #29
- *tmp = 0;
- if (*i->second->awaymsg) {
- strlcat(tmp, "G", 9);
- } else {
- strlcat(tmp, "H", 9);
- }
- if (strchr(i->second->modes,'o')) { strlcat(tmp, "*", 9); }
- WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr ? Ptr->name : "*", i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
- n_list++;
- if (n_list > Config->MaxWhoResults)
- {
- WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
- break;
- }
- }
- }
+ positive = true;
+ continue;
+ }
+ else if (*n == '-')
+ {
+ positive = false;
+ continue;
+ }
+ if (user->IsModeSet(*n) != positive)
+ return false;
+ }
+ return true;
+ }
+
+ if (opt_realname)
+ realname = match(user->fullname, matchtext);
+
+ if (opt_showrealhost)
+ realhost = match(user->host, matchtext);
+
+ return ((realname) || (realhost) || (match(user->dhost, matchtext)) || (match(user->nick, matchtext)) || (match(user->server, matchtext)));
+}
+
+
+
+extern "C" command_t* init_command(InspIRCd* Instance)
+{
+ return new cmd_who(Instance);
+}
+
+bool cmd_who::CanView(chanrec* chan, userrec* user)
+{
+ if (!user || !chan)
+ return false;
+
+ /* Execute items in fastest-to-execute first order */
+ if (*user->oper)
+ return true;
+ else if (!chan->IsModeSet('s') && !chan->IsModeSet('p'))
+ return true;
+ else if (chan->HasUser(user))
+ return true;
+
+ return false;
+}
+
+CmdResult cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
+{
+ /*
+ * XXX - RFC says:
+ * The <name> passed to WHO is matched against users' host, server, real
+ * name and nickname
+ * Currently, we support WHO #chan, WHO nick, WHO 0, WHO *, and the addition of a 'o' flag, as per RFC.
+ */
+
+ /* WHO options */
+ bool opt_viewopersonly = false;
+ bool opt_showrealhost = false;
+ bool opt_unlimit = false;
+ bool opt_realname = false;
+ bool opt_mode = false;
+
+ chanrec *ch = NULL;
+ std::vector<std::string> whoresults;
+ std::string initial = "352 " + std::string(user->nick) + " ";
+
+ const char* matchtext = NULL;
+
+ /* Change '0' into '*' so the wildcard matcher can grok it */
+ matchtext = parameters[0];
+ if (!strcmp(matchtext,"0"))
+ matchtext = "*";
+
+ if (pcnt > 1)
+ {
+ /* parse flags */
+ const char *iter = parameters[1];
+
+ while (*iter)
+ {
+ switch (*iter)
+ {
+ case 'o':
+ opt_viewopersonly = true;
+ break;
+ case 'h':
+ if (*user->oper)
+ opt_showrealhost = true;
+ break;
+ case 'u':
+ if (*user->oper)
+ opt_unlimit = true;
+ break;
+ case 'r':
+ opt_realname = true;
+ break;
+ case 'm':
+ opt_mode = true;
+ break;