1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
10 * Written by Craig Edwards, Craig McLure, and others.
11 * This program is free but copyrighted software; see
12 *the file COPYING for details.
14 * ---------------------------------------------------
17 #include "configreader.h"
23 #include "commands/cmd_who.h"
27 /* get the last 'visible' chan of a user */
28 static char *getlastchanname(userrec *u)
30 for (std::vector<ucrec*>::const_iterator v = u->chans.begin(); v != u->chans.end(); v++)
32 ucrec* temp = (ucrec*)*v;
36 if (!temp->channel->IsModeSet('s'))
37 return temp->channel->name;
44 bool whomatch(userrec* user, const char* matchtext, bool opt_realname, bool opt_showrealhost)
46 bool realhost = false;
47 bool realname = false;
49 if (user->registered != REG_ALL)
53 realname = match(user->fullname, matchtext);
56 realhost = match(user->host, matchtext);
58 return ((realname) || (realhost) || (match(user->dhost, matchtext)) || (match(user->nick, matchtext)) || (match(user->server, matchtext)));
61 void cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
65 * The <name> passed to WHO is matched against users' host, server, real
67 * Currently, we support WHO #chan, WHO nick, WHO 0, WHO *, and the addition of a 'o' flag, as per RFC.
71 bool opt_viewopersonly = false;
72 bool opt_showrealhost = false;
73 bool opt_unlimit = false;
74 bool opt_realname = false;
77 std::vector<std::string> whoresults;
78 std::string initial = "352 " + std::string(user->nick) + " ";
80 const char* matchtext = NULL;
82 /* Change '0' into '*' so the wildcard matcher can grok it */
83 matchtext = parameters[0];
84 if (!strcmp(matchtext,"0"))
90 const char *iter = parameters[1];
97 opt_viewopersonly = true;
101 opt_showrealhost = true;
117 /* who on a channel? */
118 ch = ServerInstance->FindChan(matchtext);
122 /* who on a channel. */
123 CUList *cu = ch->GetUsers();
125 for (CUList::iterator i = cu->begin(); i != cu->end(); i++)
127 /* opers only, please */
128 if (opt_viewopersonly && !*(i->second)->oper)
131 /* XXX - code duplication; this could be more efficient -- w00t */
132 std::string wholine = initial;
134 wholine = wholine + ch->name + " " + i->second->ident + " " + (opt_showrealhost ? i->second->host : i->second->dhost) + " " +
135 i->second->server + " " + i->second->nick + " ";
138 if (*(i->second)->awaymsg)
148 if (*(i->second)->oper)
153 wholine = wholine + ch->GetStatusChar(i->second) + " :0 " + i->second->fullname;
154 whoresults.push_back(wholine);
159 /* Match against wildcard of nick, server or host */
161 if (opt_viewopersonly)
163 /* Showing only opers */
164 for (std::vector<userrec*>::iterator i = ServerInstance->all_opers.begin(); i != ServerInstance->all_opers.end(); i++)
168 if (whomatch(oper, matchtext, opt_realname, opt_showrealhost))
170 std::string wholine = initial;
172 wholine = wholine + getlastchanname(oper) + " " + oper->ident + " " + (opt_showrealhost ? oper->host : oper->dhost) + " " +
173 oper->server + " " + oper->nick + " ";
191 wholine = wholine + ch->GetStatusChar(oper) + " :0 " + oper->fullname;
192 whoresults.push_back(wholine);
198 for (user_hash::iterator i = ServerInstance->clientlist.begin(); i != ServerInstance->clientlist.end(); i++)
200 if (whomatch(i->second, matchtext, opt_realname, opt_showrealhost))
202 std::string wholine = initial;
204 wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + (opt_showrealhost ? i->second->host : i->second->dhost) + " " +
205 i->second->server + " " + i->second->nick + " ";
208 if (*(i->second)->awaymsg)
218 if (*(i->second)->oper)
223 wholine = wholine + ch->GetStatusChar(i->second) + " :0 " + i->second->fullname;
224 whoresults.push_back(wholine);
229 /* Send the results out */
230 if ((whoresults.size() < (size_t)ServerInstance->Config->MaxWhoResults) && (!opt_unlimit))
232 for (std::vector<std::string>::const_iterator n = whoresults.begin(); n != whoresults.end(); n++)
234 user->WriteServ("315 %s %s :End of /WHO list.",user->nick, *parameters[0] ? parameters[0] : "*");
238 /* BZZT! Too many results. */
239 user->WriteServ("315 %s %s :Too many results",user->nick, parameters[0]);