]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/cmd_who.cpp
More WHO
[user/henk/code/inspircd.git] / src / cmd_who.cpp
1 /*   +------------------------------------+
2  *   | Inspire Internet Relay Chat Daemon |
3  *   +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *   E-mail:
7  *<brain@chatspike.net>
8  *<Craig@chatspike.net>
9  *
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 #include "configreader.h"
18 #include "users.h"
19 #include "message.h"
20 #include "modules.h"
21 #include "commands.h"
22 #include "helperfuncs.h"
23 #include "commands/cmd_who.h"
24
25 extern ServerConfig* Config;
26 extern user_hash clientlist;
27 extern chan_hash chanlist;
28 extern std::vector<userrec*> all_opers;
29
30 /* get the last 'visible' chan of a user */
31 static char *getlastchanname(userrec *u)
32 {
33         for (std::vector<ucrec*>::const_iterator v = u->chans.begin(); v != u->chans.end(); v++)
34         {
35                 ucrec* temp = (ucrec*)*v;
36
37                 if (temp->channel)
38                 {
39                         if (!temp->channel->IsModeSet('s'))
40                                 return temp->channel->name;
41                 }
42         }
43
44         return "*";
45 }
46
47 void cmd_who::Handle (const char** parameters, int pcnt, userrec *user)
48 {
49         /*
50          * XXX - RFC says:
51          *   The <name> passed to WHO is matched against users' host, server, real
52          *   name and nickname
53          * Currently, we support WHO #chan, WHO nick, WHO 0, WHO *, and the addition of a 'o' flag, as per RFC.
54          */
55
56         bool opt_viewopersonly = false;
57         chanrec *ch = NULL;
58         std::vector<std::string> whoresults;
59         std::string initial = "352 " + std::string(user->nick) + " ";
60
61         if (pcnt == 2)
62         {
63                 /* parse flags */
64                 const char *iter = parameters[1];
65
66                 while (*iter)
67                 {
68                         switch (*iter)
69                         {
70                                 case 'o':
71                                         opt_viewopersonly = true;
72                                         break;
73                         }
74
75                         *iter++;
76                 }
77         }
78
79
80         /* who on a channel? */
81         ch = FindChan(parameters[0]);
82
83         if (ch)
84         {
85                 /* who on a channel. */
86                 CUList *cu = ch->GetUsers();
87
88                 for (CUList::iterator i = cu->begin(); i != cu->end(); i++)
89                 {
90                         /* opers only, please */
91                         if (opt_viewopersonly && !*(i->second)->oper)
92                                 continue;
93
94
95                         /* XXX - code duplication; this could be more efficient -- w00t */
96                         std::string wholine = initial;
97
98                         wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + i->second->dhost + " " + 
99                                         i->second->server + " " + i->second->nick + " ";
100
101                         /* away? */
102                         if (*(i->second)->awaymsg)
103                         {
104                                 wholine.append("G");
105                         }
106                         else
107                         {
108                                 wholine.append("H");
109                         }
110
111                         /* oper? */
112                         if (*(i->second)->oper)
113                         {
114                                 wholine.append("*");
115                         }
116
117                         wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
118                         whoresults.push_back(wholine);
119                 }
120         }
121         else
122         {
123                 /* uhggle. who on .. something else. */
124                 userrec *u = Find(parameters[0]);
125
126                 if (u)
127                 {
128                         /* who on a single user */
129                         std::string wholine = initial;
130
131                         wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + i->second->dhost + " " + 
132                                         i->second->server + " " + i->second->nick + " ";
133
134                         /* away? */
135                         if (*(i->second)->awaymsg)
136                         {
137                                 wholine.append("G");
138                         }
139                         else
140                         {
141                                 wholine.append("H");
142                         }
143
144                         /* oper? */
145                         if (*(i->second)->oper)
146                         {
147                                 wholine.append("*");
148                         }
149
150                         wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
151                         whoresults.push_back(wholine);
152                 }
153
154                 is (*parameters[0] == '*' || *parameters[0] == '0')
155                 {
156                         if (!opt_viewopersonly && !*user->oper)
157                                 return; /* No way, jose */
158
159                         if (opt_viewopersonly)
160                         {
161                                 for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
162                                 {
163                                         std::string wholine = initial;
164
165                                         wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + i->second->dhost + " " + 
166                                                         i->second->server + " " + i->second->nick + " ";
167
168                                         /* away? */
169                                         if (*(i->second)->awaymsg)
170                                         {
171                                                 wholine.append("G");
172                                         }
173                                         else
174                                         {
175                                                 wholine.append("H");
176                                         }
177
178                                         /* oper? */
179                                         if (*(i->second)->oper)
180                                         {
181                                                 wholine.append("*");
182                                         }
183
184                                         wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
185                                         whoresults.push_back(wholine);
186                                 }
187                         }
188                         else
189                         {
190                                 for (std::vector<userrec*>::iterator i = clientlist.begin(); i != clientlist.end(); i++)
191                                 {
192                                         std::string wholine = initial;
193
194                                         wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + i->second->dhost + " " + 
195                                                         i->second->server + " " + i->second->nick + " ";
196
197                                         /* away? */
198                                         if (*(i->second)->awaymsg)
199                                         {
200                                                 wholine.append("G");
201                                         }
202                                         else
203                                         {
204                                                 wholine.append("H");
205                                         }
206
207                                         /* oper? */
208                                         if (*(i->second)->oper)
209                                         {
210                                                 wholine.append("*");
211                                         }
212
213                                         wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
214                                         whoresults.push_back(wholine);
215                                 }
216                         }
217                 }
218         }
219 }