1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
7 * <brain@chatspike.net>
8 * <Craig@chatspike.net>
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"
23 #include "commands/cmd_who.h"
25 extern ServerConfig* Config;
26 extern user_hash clientlist;
27 extern chan_hash chanlist;
28 extern std::vector<userrec*> all_opers;
30 /* get the last 'visible' chan of a user */
31 static char *getlastchanname(userrec *u)
33 for (std::vector<ucrec*>::const_iterator v = u->chans.begin(); v != u->chans.end(); v++)
35 ucrec* temp = (ucrec*)*v;
39 if (!temp->channel->IsModeSet('s'))
40 return temp->channel->name;
47 void cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
49 bool opt_viewopersonly = false;
51 std::vector<std::string> whoresults;
52 std::string initial = "352 " + std::string(user->nick) + " ";
57 const char *iter = parameters[1];
64 opt_viewopersonly = true;
73 /* who on a channel? */
74 ch = FindChan(parameters[0]);
78 /* who on a channel. */
79 CUList *cu = ch->GetUsers();
81 for (CUList::iterator i = cu->begin(); i != cu->end(); i++)
83 /* opers only, please */
84 if (opt_viewopersonly && !*(i->second)->oper)
88 std::string wholine = initial;
90 wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + i->second->dhost + " " +
91 i->second->server + " " + i->second->nick + " ";
94 if (*(i->second)->awaymsg)
104 if (*(i->second)->oper)
109 wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
110 whoresults.push_back(wholine);
115 /* uhggle. who on .. something else. */
117 // The <name> passed to WHO is matched against users' host, server, real
139 if ((IS_SINGLE(parameters[0],'0')) || (IS_SINGLE(parameters[0],'*')))
141 if ((user->chans.size()) && (((ucrec*)*(user->chans.begin()))->channel))
144 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
146 Ptr = ((ucrec*)*(i->second->chans.begin()))->channel;
147 // suggested by phidjit and FCS
148 if ((!common_channels(user,i->second)) && (isnick(i->second->nick)))
152 if (*i->second->awaymsg) {
153 charlcat(tmp, 'G', 9);
155 charlcat(tmp, 'H', 9);
157 if (*i->second->oper) { charlcat(tmp, '*', 9); }
158 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);
159 if (n_list++ > Config->MaxWhoResults)
161 WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
169 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick , parameters[0]);
173 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
177 if (parameters[0][0] == '#')
179 Ptr = FindChan(parameters[0]);
183 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
185 if ((Ptr->HasUser(i->second)) && (isnick(i->second->nick)))
187 // Fix Bug #29 - Part 2..
189 if (*i->second->awaymsg) {
190 charlcat(tmp, 'G', 9);
192 charlcat(tmp, 'H', 9);
194 if (*i->second->oper) { charlcat(tmp, '*', 9); }
195 strlcat(tmp, cmode(i->second, Ptr),5);
196 WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr->name, i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
198 if (n_list > Config->MaxWhoResults)
200 WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
206 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
210 WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
215 userrec* u = Find(parameters[0]);
218 // Bug Fix #29 -- Part 29..
221 charlcat(tmp, 'G' ,9);
223 charlcat(tmp, 'H' ,9);
225 if (*u->oper) { charlcat(tmp, '*' ,9); }
226 WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, u->chans.size() && ((ucrec*)*(u->chans.begin()))->channel ? ((ucrec*)*(u->chans.begin()))->channel->name
227 : "*", u->ident, u->dhost, u->server, u->nick, tmp, u->fullname);
229 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
234 if ((IS_SINGLE(parameters[0],'0')) || (IS_SINGLE(parameters[0],'*')) && (IS_SINGLE(parameters[1],'o')))
236 for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
238 // If i were a rich man.. I wouldn't need to me making these bugfixes..
239 // But i'm a poor bastard with nothing better to do.
242 if (*oper->awaymsg) {
243 charlcat(tmp, 'G' ,9);
245 charlcat(tmp, 'H' ,9);
247 WriteServ(user->fd,"352 %s %s %s %s %s %s %s* :0 %s", user->nick, oper->chans.size() && ((ucrec*)*(oper->chans.begin()))->channel ? ((ucrec*)*(oper->chans.begin()))->channel->name
248 : "*", oper->ident, oper->dhost, oper->server, oper->nick, tmp, oper->fullname);
250 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);