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;
50 realname = match(user->fullname, matchtext);
53 realhost = match(user->host, matchtext);
55 return ((realname) || (realhost) || (match(user->dhost, matchtext)) || (match(user->nick, matchtext)) || (match(user->server, matchtext)));
58 void cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
62 * The <name> passed to WHO is matched against users' host, server, real
64 * Currently, we support WHO #chan, WHO nick, WHO 0, WHO *, and the addition of a 'o' flag, as per RFC.
68 bool opt_viewopersonly = false;
69 bool opt_showrealhost = false;
70 bool opt_unlimit = false;
71 bool opt_realname = false;
74 std::vector<std::string> whoresults;
75 std::string initial = "352 " + std::string(user->nick) + " ";
77 const char* matchtext = NULL;
79 /* Change '0' into '*' so the wildcard matcher can grok it */
80 matchtext = parameters[0];
81 if (!strcmp(matchtext,"0"))
87 const char *iter = parameters[1];
94 opt_viewopersonly = true;
98 opt_showrealhost = true;
114 /* who on a channel? */
115 ch = ServerInstance->FindChan(matchtext);
119 /* who on a channel. */
120 CUList *cu = ch->GetUsers();
122 for (CUList::iterator i = cu->begin(); i != cu->end(); i++)
124 /* opers only, please */
125 if (opt_viewopersonly && !*(i->second)->oper)
128 /* XXX - code duplication; this could be more efficient -- w00t */
129 std::string wholine = initial;
131 wholine = wholine + ch->name + " " + i->second->ident + " " + (opt_showrealhost ? i->second->host : i->second->dhost) + " " +
132 i->second->server + " " + i->second->nick + " ";
135 if (*(i->second)->awaymsg)
145 if (*(i->second)->oper)
150 wholine = wholine + ch->GetStatusChar(i->second) + " :0 " + i->second->fullname;
151 whoresults.push_back(wholine);
156 /* Match against wildcard of nick, server or host */
158 if (opt_viewopersonly)
160 /* Showing only opers */
161 for (std::vector<userrec*>::iterator i = ServerInstance->all_opers.begin(); i != ServerInstance->all_opers.end(); i++)
165 if (whomatch(oper, matchtext, opt_realname, opt_showrealhost))
167 std::string wholine = initial;
169 wholine = wholine + getlastchanname(oper) + " " + oper->ident + " " + (opt_showrealhost ? oper->host : oper->dhost) + " " +
170 oper->server + " " + oper->nick + " ";
188 wholine = wholine + ch->GetStatusChar(oper) + " :0 " + oper->fullname;
189 whoresults.push_back(wholine);
195 for (user_hash::iterator i = ServerInstance->clientlist.begin(); i != ServerInstance->clientlist.end(); i++)
197 if (whomatch(i->second, matchtext, opt_realname, opt_showrealhost))
199 std::string wholine = initial;
201 wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + (opt_showrealhost ? i->second->host : i->second->dhost) + " " +
202 i->second->server + " " + i->second->nick + " ";
205 if (*(i->second)->awaymsg)
215 if (*(i->second)->oper)
220 wholine = wholine + ch->GetStatusChar(i->second) + " :0 " + i->second->fullname;
221 whoresults.push_back(wholine);
226 /* Send the results out */
227 if ((whoresults.size() < (size_t)ServerInstance->Config->MaxWhoResults) && (!opt_unlimit))
229 for (std::vector<std::string>::const_iterator n = whoresults.begin(); n != whoresults.end(); n++)
231 user->WriteServ("315 %s %s :End of /WHO list.",user->nick, parameters[0]);
235 /* BZZT! Too many results. */
236 user->WriteServ("315 %s %s :Too many results",user->nick, parameters[0]);