ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_whois.c
Revision: 5517
Committed: Mon Feb 9 20:30:41 2015 UTC (10 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 9648 byte(s)
Log Message:
- m_whois.c:whois_person(): constification

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2015 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 /*! \file m_whois.c
23 * \brief Includes required functions for processing the WHOIS command.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "client.h"
30 #include "hash.h"
31 #include "channel.h"
32 #include "channel_mode.h"
33 #include "ircd.h"
34 #include "numeric.h"
35 #include "conf.h"
36 #include "misc.h"
37 #include "server.h"
38 #include "user.h"
39 #include "send.h"
40 #include "irc_string.h"
41 #include "parse.h"
42 #include "modules.h"
43
44
45 static int
46 whois_can_see_channels(struct Channel *chptr,
47 struct Client *source_p,
48 struct Client *target_p)
49 {
50 if (PubChannel(chptr) && !HasUMode(target_p, UMODE_HIDECHANS))
51 return 1;
52
53 if (source_p == target_p || IsMember(source_p, chptr))
54 return 1;
55
56 if (HasUMode(source_p, UMODE_ADMIN))
57 return 2;
58 return 0;
59 }
60
61 /* whois_person()
62 *
63 * inputs - source_p client to report to
64 * - target_p client to report on
65 * output - NONE
66 * side effects -
67 */
68 static void
69 whois_person(struct Client *source_p, struct Client *target_p)
70 {
71 char buf[IRCD_BUFSIZE] = "";
72 const dlink_node *lp = NULL;
73 char *t = NULL;
74 int cur_len = 0;
75 int mlen = 0;
76 int tlen = 0;
77 int reply_to_send = 0;
78
79 sendto_one_numeric(source_p, &me, RPL_WHOISUSER, target_p->name,
80 target_p->username, target_p->host,
81 target_p->info);
82
83 cur_len = mlen = snprintf(buf, sizeof(buf), numeric_form(RPL_WHOISCHANNELS),
84 me.name, source_p->name, target_p->name, "");
85 t = buf + mlen;
86
87 DLINK_FOREACH(lp, target_p->channel.head)
88 {
89 const struct Membership *member = lp->data;
90 int show = whois_can_see_channels(member->chptr, source_p, target_p);
91
92 if (show)
93 {
94 if ((cur_len + 4 + strlen(member->chptr->name) + 1) > (IRCD_BUFSIZE - 2))
95 {
96 *(t - 1) = '\0';
97 sendto_one(source_p, "%s", buf);
98 cur_len = mlen;
99 t = buf + mlen;
100 }
101
102 tlen = sprintf(t, "%s%s%s ", show == 2 ? "~" : "", get_member_status(member, 1),
103 member->chptr->name);
104 t += tlen;
105 cur_len += tlen;
106 reply_to_send = 1;
107 }
108 }
109
110 if (reply_to_send)
111 {
112 *(t - 1) = '\0';
113 sendto_one(source_p, "%s", buf);
114 }
115
116 if ((ConfigServerHide.hide_servers || IsHidden(target_p->servptr)) &&
117 !(HasUMode(source_p, UMODE_OPER) || target_p == source_p))
118 sendto_one_numeric(source_p, &me, RPL_WHOISSERVER, target_p->name,
119 ConfigServerHide.hidden_name,
120 ConfigServerInfo.network_desc);
121 else
122 sendto_one_numeric(source_p, &me, RPL_WHOISSERVER, target_p->name,
123 target_p->servptr->name, target_p->servptr->info);
124
125 if (HasUMode(target_p, UMODE_REGISTERED))
126 sendto_one_numeric(source_p, &me, RPL_WHOISREGNICK, target_p->name);
127
128 if (!IsDigit(target_p->account[0]) && target_p->account[0] != '*')
129 sendto_one_numeric(source_p, &me, RPL_WHOISACCOUNT, target_p->name,
130 target_p->account, "is");
131
132 if (target_p->away[0])
133 sendto_one_numeric(source_p, &me, RPL_AWAY, target_p->name,
134 target_p->away);
135
136 if (HasUMode(target_p, UMODE_CALLERID | UMODE_SOFTCALLERID))
137 {
138 const int callerid = !!HasUMode(target_p, UMODE_CALLERID);
139
140 sendto_one_numeric(source_p, &me, RPL_TARGUMODEG, target_p->name,
141 callerid ? "+g" : "+G",
142 callerid ? "server side ignore" :
143 "server side ignore with the exception of common channels");
144 }
145
146 if (HasUMode(target_p, UMODE_OPER))
147 if (!HasUMode(target_p, UMODE_HIDDEN) || HasUMode(source_p, UMODE_OPER))
148 sendto_one_numeric(source_p, &me, RPL_WHOISOPERATOR, target_p->name,
149 HasUMode(target_p, UMODE_ADMIN) ? "is a Server Administrator" :
150 "is an IRC Operator");
151
152 if (HasUMode(target_p, UMODE_WEBIRC))
153 sendto_one_numeric(source_p, &me, RPL_WHOISTEXT, target_p->name,
154 "User connected using a webirc gateway");
155
156 if (HasUMode(source_p, UMODE_ADMIN) || source_p == target_p)
157 {
158 char *m = buf;
159 *m++ = '+';
160
161 for (const struct user_modes *tab = umode_tab; tab->c; ++tab)
162 if (HasUMode(target_p, tab->flag))
163 *m++ = tab->c;
164 *m = '\0';
165
166 sendto_one_numeric(source_p, &me, RPL_WHOISMODES, target_p->name, buf);
167 }
168
169 if (strcmp(target_p->sockhost, "0")) /* XXX: TBR */
170 if (HasUMode(source_p, UMODE_OPER) || source_p == target_p)
171 sendto_one_numeric(source_p, &me, RPL_WHOISACTUALLY, target_p->name,
172 target_p->sockhost);
173
174 if (HasUMode(target_p, UMODE_SSL))
175 sendto_one_numeric(source_p, &me, RPL_WHOISSECURE, target_p->name);
176
177 if (!EmptyString(target_p->certfp))
178 if (target_p == source_p || HasUMode(source_p, UMODE_ADMIN))
179 sendto_one_numeric(source_p, &me, RPL_WHOISCERTFP, target_p->name, target_p->certfp);
180
181 if (MyConnect(target_p))
182 if (!HasUMode(target_p, UMODE_HIDEIDLE) || HasUMode(source_p, UMODE_OPER) ||
183 source_p == target_p)
184 sendto_one_numeric(source_p, &me, RPL_WHOISIDLE, target_p->name,
185 idle_time_get(source_p, target_p),
186 target_p->connection->firsttime);
187 }
188
189 /* do_whois()
190 *
191 * inputs - pointer to /whois source
192 * - number of parameters
193 * - pointer to parameters array
194 * output - pointer to void
195 * side effects - Does whois
196 */
197 static void
198 do_whois(struct Client *source_p, const char *name)
199 {
200 struct Client *target_p = NULL;
201
202 if ((target_p = find_person(source_p, name)))
203 whois_person(source_p, target_p);
204 else if (!IsDigit(*name))
205 sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, name);
206
207 sendto_one_numeric(source_p, &me, RPL_ENDOFWHOIS, name);
208 }
209
210 /*! \brief WHOIS command handler
211 *
212 * \param source_p Pointer to allocated Client struct from which the message
213 * originally comes from. This can be a local or remote client.
214 * \param parc Integer holding the number of supplied arguments.
215 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
216 * pointers.
217 * \note Valid arguments for this command are:
218 * - parv[0] = command
219 * - parv[1] = nickname/servername
220 * - parv[2] = nickname
221 */
222 static int
223 m_whois(struct Client *source_p, int parc, char *parv[])
224 {
225 static time_t last_used = 0;
226
227 if (parc < 2 || EmptyString(parv[1]))
228 {
229 sendto_one_numeric(source_p, &me, ERR_NONICKNAMEGIVEN);
230 return 0;
231 }
232
233 if (parc > 2 && !EmptyString(parv[2]))
234 {
235 /* seeing as this is going across servers, we should limit it */
236 if ((last_used + ConfigGeneral.pace_wait_simple) > CurrentTime)
237 {
238 sendto_one_numeric(source_p, &me, RPL_LOAD2HI, "WHOIS");
239 return 0;
240 }
241
242 last_used = CurrentTime;
243
244 /*
245 * if we have serverhide enabled, they can either ask the clients
246 * server, or our server.. I don't see why they would need to ask
247 * anything else for info about the client.. --fl_
248 */
249 if (ConfigServerHide.disable_remote_commands)
250 parv[1] = parv[2];
251
252 if (hunt_server(source_p, ":%s WHOIS %s :%s", 1,
253 parc, parv) != HUNTED_ISME)
254 return 0;
255
256 parv[1] = parv[2];
257 }
258
259 do_whois(source_p, parv[1]);
260 return 0;
261 }
262
263 /*! \brief WHOIS command handler
264 *
265 * \param source_p Pointer to allocated Client struct from which the message
266 * originally comes from. This can be a local or remote client.
267 * \param parc Integer holding the number of supplied arguments.
268 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
269 * pointers.
270 * \note Valid arguments for this command are:
271 * - parv[0] = command
272 * - parv[1] = nickname/servername
273 * - parv[2] = nickname
274 */
275 static int
276 mo_whois(struct Client *source_p, int parc, char *parv[])
277 {
278 if (parc < 2 || EmptyString(parv[1]))
279 {
280 sendto_one_numeric(source_p, &me, ERR_NONICKNAMEGIVEN);
281 return 0;
282 }
283
284 if (parc > 2 && !EmptyString(parv[2]))
285 {
286 if (hunt_server(source_p, ":%s WHOIS %s :%s", 1,
287 parc, parv) != HUNTED_ISME)
288 return 0;
289
290 parv[1] = parv[2];
291 }
292
293 do_whois(source_p, parv[1]);
294 return 0;
295 }
296
297 static struct Message whois_msgtab =
298 {
299 "WHOIS", NULL, 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
300 { m_unregistered, m_whois, mo_whois, m_ignore, mo_whois, m_ignore }
301 };
302
303 static void
304 module_init(void)
305 {
306 mod_add_cmd(&whois_msgtab);
307 }
308
309 static void
310 module_exit(void)
311 {
312 mod_del_cmd(&whois_msgtab);
313 }
314
315 struct module module_entry =
316 {
317 .node = { NULL, NULL, NULL },
318 .name = NULL,
319 .version = "$Revision$",
320 .handle = NULL,
321 .modinit = module_init,
322 .modexit = module_exit,
323 .flags = 0
324 };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision