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"
22 #include "helperfuncs.h"
24 #include "commands/cmd_who.h"
26 extern ServerConfig* Config;
27 extern user_hash clientlist;
28 extern chan_hash chanlist;
29 extern std::vector<userrec*> all_opers;
31 /* get the last 'visible' chan of a user */
32 static char *getlastchanname(userrec *u)
34 for (std::vector<ucrec*>::const_iterator v = u->chans.begin(); v != u->chans.end(); v++)
36 ucrec* temp = (ucrec*)*v;
40 if (!temp->channel->IsModeSet('s'))
41 return temp->channel->name;
48 bool whomatch(userrec* user, const char* matchtext, bool opt_realname, bool opt_showrealhost)
50 bool realhost = false;
51 bool realname = false;
54 realname = match(user->fullname, matchtext);
57 realhost = match(user->host, matchtext);
59 return ((realname) || (realhost) || (match(user->dhost, matchtext)) || (match(user->nick, matchtext)) || (match(user->server, matchtext)));
62 void cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
66 * The <name> passed to WHO is matched against users' host, server, real
68 * Currently, we support WHO #chan, WHO nick, WHO 0, WHO *, and the addition of a 'o' flag, as per RFC.
72 bool opt_viewopersonly = false;
73 bool opt_showrealhost = false;
74 bool opt_unlimit = false;
75 bool opt_realname = false;
78 std::vector<std::string> whoresults;
79 std::string initial = "352 " + std::string(user->nick) + " ";
81 const char* matchtext = NULL;
83 /* Change '0' into '*' so the wildcard matcher can grok it */
84 matchtext = parameters[0];
85 if (!strcmp(matchtext,"0"))
91 const char *iter = parameters[1];
98 opt_viewopersonly = true;
102 opt_showrealhost = true;
118 /* who on a channel? */
119 ch = FindChan(matchtext);
123 /* who on a channel. */
124 CUList *cu = ch->GetUsers();
126 for (CUList::iterator i = cu->begin(); i != cu->end(); i++)
128 /* opers only, please */
129 if (opt_viewopersonly && !*(i->second)->oper)
132 /* XXX - code duplication; this could be more efficient -- w00t */
133 std::string wholine = initial;
135 wholine = wholine + ch->name + " " + i->second->ident + " " + (opt_showrealhost ? i->second->host : i->second->dhost) + " " +
136 i->second->server + " " + i->second->nick + " ";
139 if (*(i->second)->awaymsg)
149 if (*(i->second)->oper)
154 wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
155 whoresults.push_back(wholine);
160 /* Match against wildcard of nick, server or host */
162 if (opt_viewopersonly)
164 /* Showing only opers */
165 for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
169 if (whomatch(oper, matchtext, opt_realname, opt_showrealhost))
171 std::string wholine = initial;
173 wholine = wholine + getlastchanname(oper) + " " + oper->ident + " " + (opt_showrealhost ? oper->host : oper->dhost) + " " +
174 oper->server + " " + oper->nick + " ";
192 wholine = wholine + cmode(oper, ch) + " :0 " + oper->fullname;
193 whoresults.push_back(wholine);
199 for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
201 if (whomatch(i->second, matchtext, opt_realname, opt_showrealhost))
203 std::string wholine = initial;
205 wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + (opt_showrealhost ? i->second->host : i->second->dhost) + " " +
206 i->second->server + " " + i->second->nick + " ";
209 if (*(i->second)->awaymsg)
219 if (*(i->second)->oper)
224 wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
225 whoresults.push_back(wholine);
230 /* Send the results out */
231 if ((whoresults.size() < (size_t)Config->MaxWhoResults) && (!opt_unlimit))
233 for (std::vector<std::string>::const_iterator n = whoresults.begin(); n != whoresults.end(); n++)
234 WriteServ_NoFormat(user->fd,n->c_str());
235 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
239 /* BZZT! Too many results. */
240 WriteServ(user->fd,"315 %s %s :Too many results",user->nick, parameters[0]);