]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/cmd_who.cpp
06c99ac60df27b5467f009bb87ecfedcbb88c151
[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         bool opt_viewopersonly = false;
50         chanrec *ch = NULL;
51         std::vector<std::string> whoresults;
52         std::string initial = "352 " + std::string(user->nick) + " ";
53
54         if (pcnt == 2)
55         {
56                 /* parse flags */
57                 const char *iter = parameters[1];
58
59                 while (*iter)
60                 {
61                         switch (*iter)
62                         {
63                                 case 'o':
64                                         opt_viewopersonly = true;
65                                         break;
66                         }
67
68                         *iter++;
69                 }
70         }
71
72
73         /* who on a channel? */
74         ch = FindChan(parameters[0]);
75
76         if (ch)
77         {
78                 /* who on a channel. */
79                 CUList *cu = ch->GetUsers();
80
81                 for (CUList::iterator i = cu->begin(); i != cu->end(); i++)
82                 {
83                         /* opers only, please */
84                         if (opt_viewopersonly && !*(i->second)->oper)
85                                 continue;
86
87
88                         std::string wholine = initial;
89
90                         wholine = wholine + getlastchanname(i->second) + " " + i->second->ident + " " + i->second->dhost + " " + 
91                                         i->second->server + " " + i->second->nick + " ";
92
93                         /* away? */
94                         if (*(i->second)->awaymsg)
95                         {
96                                 wholine.append("G");
97                         }
98                         else
99                         {
100                                 wholine.append("H");
101                         }
102
103                         /* oper? */
104                         if (*(i->second)->oper)
105                         {
106                                 wholine.append("*");
107                         }
108
109                         wholine = wholine + cmode(i->second, ch) + " :0 " + i->second->fullname;
110                         whoresults.push_back(wholine);
111                 }
112         }
113         else
114         {
115                 /* uhggle. who on .. something else. */
116
117 //   The <name> passed to WHO is matched against users' host, server, real
118 //   name and nickname
119
120         }
121
122
123         return;
124
125
126
127
128
129
130
131
132
133
134         chanrec* Ptr = NULL;
135         char tmp[10];
136         
137         if (pcnt == 1)
138         {
139                 if ((IS_SINGLE(parameters[0],'0')) || (IS_SINGLE(parameters[0],'*')))
140                 {
141                         if ((user->chans.size()) && (((ucrec*)*(user->chans.begin()))->channel))
142                         {
143                                 int n_list = 0;
144                                 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
145                                 {
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)))
149                                         {
150                                                 // Bug Fix #29
151                                                 *tmp = 0;
152                                                 if (*i->second->awaymsg) {
153                                                         charlcat(tmp, 'G', 9);
154                                                 } else {
155                                                         charlcat(tmp, 'H', 9);
156                                                 }
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)
160                                                 {
161                                                         WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
162                                                         break;
163                                                 }
164                                         }
165                                 }
166                         }
167                         if (Ptr)
168                         {
169                                 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick , parameters[0]);
170                         }
171                         else
172                         {
173                                 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
174                         }
175                         return;
176                 }
177                 if (parameters[0][0] == '#')
178                 {
179                         Ptr = FindChan(parameters[0]);
180                         if (Ptr)
181                         {
182                                 int n_list = 0;
183                                 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
184                                 {
185                                         if ((Ptr->HasUser(i->second)) && (isnick(i->second->nick)))
186                                         {
187                                                 // Fix Bug #29 - Part 2..
188                                                 *tmp = 0;
189                                                 if (*i->second->awaymsg) {
190                                                         charlcat(tmp, 'G', 9);
191                                                 } else {
192                                                         charlcat(tmp, 'H', 9);
193                                                 }
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);
197                                                 n_list++;
198                                                 if (n_list > Config->MaxWhoResults)
199                                                 {
200                                                         WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
201                                                         break;
202                                                 }
203
204                                         }
205                                 }
206                                 WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
207                         }
208                         else
209                         {
210                                 WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
211                         }
212                 }
213                 else
214                 {
215                         userrec* u = Find(parameters[0]);
216                         if (u)
217                         {
218                                 // Bug Fix #29 -- Part 29..
219                                 *tmp = 0;
220                                 if (*u->awaymsg) {
221                                         charlcat(tmp, 'G' ,9);
222                                 } else {
223                                         charlcat(tmp, 'H' ,9);
224                                 }
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);
228                         }
229                         WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
230                 }
231         }
232         if (pcnt == 2)
233         {
234                 if ((IS_SINGLE(parameters[0],'0')) || (IS_SINGLE(parameters[0],'*')) && (IS_SINGLE(parameters[1],'o')))
235                 {
236                         for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
237                         {
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.
240                                 userrec* oper = *i;
241                                 *tmp = 0;
242                                 if (*oper->awaymsg) {
243                                         charlcat(tmp, 'G' ,9);
244                                 } else {
245                                         charlcat(tmp, 'H' ,9);
246                                 }
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);
249                         }
250                         WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
251                         return;
252                 }
253         }
254 }