ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_whois.c
Revision: 1155
Committed: Tue Aug 9 20:27:45 2011 UTC (14 years ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/modules/m_whois.c
File size: 11380 byte(s)
Log Message:
- recreate "trunk"

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_whois.c: Shows who a user is.
4     *
5     * Copyright (C) 2005 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26 michael 1011 #include "list.h"
27 adx 30 #include "common.h"
28     #include "handlers.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 "s_conf.h"
36     #include "s_misc.h"
37     #include "s_serv.h"
38     #include "send.h"
39     #include "irc_string.h"
40     #include "sprintf_irc.h"
41     #include "msg.h"
42     #include "parse.h"
43     #include "modules.h"
44     #include "hook.h"
45    
46     static void do_whois(struct Client *, int, char **);
47     static int single_whois(struct Client *, struct Client *);
48     static void whois_person(struct Client *, struct Client *);
49     static int global_whois(struct Client *, const char *);
50    
51     static void m_whois(struct Client *, struct Client *, int, char *[]);
52     static void mo_whois(struct Client *, struct Client *, int, char *[]);
53    
54     struct Message whois_msgtab = {
55     "WHOIS", 0, 0, 0, 0, MFLG_SLOW, 0,
56     { m_unregistered, m_whois, mo_whois, m_ignore, mo_whois, m_ignore }
57     };
58    
59 knight 31 const char *_version = "$Revision$";
60 adx 30 static struct Callback *whois_cb;
61    
62     static void *
63     va_whois(va_list args)
64     {
65     struct Client *source_p = va_arg(args, struct Client *);
66     int parc = va_arg(args, int);
67     char **parv = va_arg(args, char **);
68    
69     do_whois(source_p, parc, parv);
70     return NULL;
71     }
72    
73     void
74     _modinit(void)
75     {
76     whois_cb = register_callback("doing_whois", va_whois);
77     mod_add_cmd(&whois_msgtab);
78     }
79    
80     void
81     _moddeinit(void)
82     {
83     mod_del_cmd(&whois_msgtab);
84     uninstall_hook(whois_cb, va_whois);
85     }
86    
87     /*
88     ** m_whois
89     ** parv[0] = sender prefix
90     ** parv[1] = nickname masklist
91     */
92     static void
93     m_whois(struct Client *client_p, struct Client *source_p,
94     int parc, char *parv[])
95     {
96 adx 269 static time_t last_used = 0;
97    
98 adx 30 if (parc < 2 || EmptyString(parv[1]))
99     {
100     sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
101     me.name, source_p->name);
102     return;
103     }
104    
105 michael 93 if (parc > 2 && !EmptyString(parv[2]))
106 adx 30 {
107     /* seeing as this is going across servers, we should limit it */
108     if ((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime)
109     {
110     sendto_one(source_p, form_str(RPL_LOAD2HI),
111     me.name, source_p->name);
112     return;
113     }
114    
115 michael 1121 last_used = CurrentTime;
116    
117 adx 30 /* if we have serverhide enabled, they can either ask the clients
118     * server, or our server.. I dont see why they would need to ask
119     * anything else for info about the client.. --fl_
120     */
121     if (ConfigFileEntry.disable_remote)
122     parv[1] = parv[2];
123    
124     if (hunt_server(client_p, source_p, ":%s WHOIS %s :%s", 1,
125     parc, parv) != HUNTED_ISME)
126     return;
127    
128     parv[1] = parv[2];
129     }
130    
131     execute_callback(whois_cb, source_p, parc, parv);
132     }
133    
134     /*
135     ** mo_whois
136     ** parv[0] = sender prefix
137     ** parv[1] = nickname masklist
138     */
139     static void
140     mo_whois(struct Client *client_p, struct Client *source_p,
141     int parc, char *parv[])
142     {
143     if (parc < 2 || EmptyString(parv[1]))
144     {
145     sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
146     me.name, source_p->name);
147     return;
148     }
149    
150 michael 93 if (parc > 2 && !EmptyString(parv[2]))
151 adx 30 {
152     if (hunt_server(client_p, source_p, ":%s WHOIS %s :%s", 1,
153     parc, parv) != HUNTED_ISME)
154     return;
155    
156     parv[1] = parv[2];
157     }
158    
159     execute_callback(whois_cb, source_p, parc, parv);
160     }
161    
162     /* do_whois()
163     *
164     * inputs - pointer to /whois source
165     * - number of parameters
166     * - pointer to parameters array
167     * output - pointer to void
168     * side effects - Does whois
169     */
170     static void
171     do_whois(struct Client *source_p, int parc, char **parv)
172     {
173 adx 269 static time_t last_used = 0;
174 adx 30 struct Client *target_p;
175     char *nick;
176     char *p = NULL;
177     int found = 0;
178    
179     nick = parv[1];
180     while (*nick == ',')
181     nick++;
182     if ((p = strchr(nick,',')) != NULL)
183     *p = '\0';
184    
185     if (*nick == '\0')
186     return;
187    
188     collapse(nick);
189    
190     if (strpbrk(nick, "?#*") == NULL)
191     {
192     if ((target_p = find_client(nick)) != NULL)
193     {
194     if (IsClient(target_p))
195     {
196 adx 268 whois_person(source_p, target_p);
197     found = 1;
198 adx 30 }
199     }
200     }
201     else /* wilds is true */
202     {
203 adx 268 if (!IsOper(source_p))
204     {
205     if ((last_used + ConfigFileEntry.pace_wait_simple) > CurrentTime)
206     {
207     sendto_one(source_p, form_str(RPL_LOAD2HI),
208     me.name, source_p->name);
209     return;
210     }
211     else
212     last_used = CurrentTime;
213     }
214    
215 adx 30 /* Oh-oh wilds is true so have to do it the hard expensive way */
216     if (MyClient(source_p))
217     found = global_whois(source_p, nick);
218     }
219    
220     if (!found)
221     {
222     if (!IsDigit(*nick))
223     sendto_one(source_p, form_str(ERR_NOSUCHNICK),
224     me.name, source_p->name, nick);
225     }
226    
227     sendto_one(source_p, form_str(RPL_ENDOFWHOIS),
228     me.name, source_p->name, parv[1]);
229     }
230    
231     /* global_whois()
232     *
233     * Inputs - source_p client to report to
234     * - target_p client to report on
235     * Output - if found return 1
236     * Side Effects - do a single whois on given client
237     * writing results to source_p
238     */
239     static int
240     global_whois(struct Client *source_p, const char *nick)
241     {
242     dlink_node *ptr;
243     struct Client *target_p;
244     int found = 0;
245    
246     DLINK_FOREACH(ptr, global_client_list.head)
247     {
248     target_p = ptr->data;
249    
250     if (!IsClient(target_p))
251     continue;
252    
253     if (!match(nick, target_p->name))
254     continue;
255    
256     assert(target_p->servptr != NULL);
257    
258     /* 'Rules' established for sending a WHOIS reply:
259     *
260     *
261     * - if wildcards are being used dont send a reply if
262     * the querier isnt any common channels and the
263     * client in question is invisible and wildcards are
264     * in use (allow exact matches only);
265     *
266     * - only send replies about common or public channels
267     * the target user(s) are on;
268     */
269    
270     found |= single_whois(source_p, target_p);
271     }
272    
273 michael 885 return found;
274 adx 30 }
275    
276     /* single_whois()
277     *
278     * Inputs - source_p client to report to
279     * - target_p client to report on
280     * Output - if found return 1
281     * Side Effects - do a single whois on given client
282     * writing results to source_p
283     */
284     static int
285     single_whois(struct Client *source_p, struct Client *target_p)
286     {
287 michael 1121 dlink_node *ptr = NULL;
288 adx 30
289     if (!IsInvisible(target_p) || target_p == source_p)
290     {
291     /* always show user if they are visible (no +i) */
292     whois_person(source_p, target_p);
293     return 1;
294     }
295    
296     /* target_p is +i. Check if it is on any common channels with source_p */
297     DLINK_FOREACH(ptr, target_p->channel.head)
298     {
299 michael 1121 struct Channel *chptr = ((struct Membership *) ptr->data)->chptr;
300    
301 adx 30 if (IsMember(source_p, chptr))
302     {
303     whois_person(source_p, target_p);
304     return 1;
305     }
306     }
307    
308     return 0;
309     }
310    
311     /* whois_person()
312     *
313     * inputs - source_p client to report to
314     * - target_p client to report on
315     * output - NONE
316     * side effects -
317     */
318     static void
319     whois_person(struct Client *source_p, struct Client *target_p)
320     {
321     char buf[IRCD_BUFSIZE];
322     dlink_node *lp;
323     struct Client *server_p;
324     struct Channel *chptr;
325     struct Membership *ms;
326     int cur_len = 0;
327     int mlen;
328     char *t = NULL;
329     int tlen;
330     int reply_to_send = NO;
331    
332     server_p = target_p->servptr;
333    
334     sendto_one(source_p, form_str(RPL_WHOISUSER),
335     me.name, source_p->name, target_p->name,
336     target_p->username, target_p->host, target_p->info);
337    
338     cur_len = mlen = ircsprintf(buf, form_str(RPL_WHOISCHANNELS),
339     me.name, source_p->name, target_p->name, "");
340     t = buf + mlen;
341    
342     DLINK_FOREACH(lp, target_p->channel.head)
343     {
344     ms = lp->data;
345     chptr = ms->chptr;
346    
347     if (ShowChannel(source_p, chptr))
348     {
349     /* Don't show local channels if user is doing a remote whois */
350     if (!MyConnect(source_p) && (chptr->chname[0] == '&'))
351     continue;
352    
353     if ((cur_len + 3 + strlen(chptr->chname) + 1) > (IRCD_BUFSIZE - 2))
354     {
355     *(t - 1) = '\0';
356     sendto_one(source_p, "%s", buf);
357     cur_len = mlen;
358     t = buf + mlen;
359     }
360    
361     tlen = ircsprintf(t, "%s%s ", get_member_status(ms, YES), chptr->chname);
362     t += tlen;
363     cur_len += tlen;
364     reply_to_send = YES;
365     }
366     }
367    
368     if (reply_to_send)
369     {
370     *(t - 1) = '\0';
371     sendto_one(source_p, "%s", buf);
372     }
373    
374     if (IsOper(source_p) || !ConfigServerHide.hide_servers || target_p == source_p)
375     sendto_one(source_p, form_str(RPL_WHOISSERVER),
376     me.name, source_p->name, target_p->name,
377     server_p->name, server_p->info);
378     else
379     sendto_one(source_p, form_str(RPL_WHOISSERVER),
380     me.name, source_p->name, target_p->name,
381     ConfigServerHide.hidden_name,
382     ServerInfo.network_desc);
383    
384     if (target_p->away != NULL)
385     sendto_one(source_p, form_str(RPL_AWAY),
386     me.name, source_p->name, target_p->name,
387     target_p->away);
388    
389 adx 660 if (IsSetCallerId(target_p) && !IsSoftCallerId(target_p))
390     sendto_one(source_p, form_str(RPL_TARGUMODEG),
391     me.name, source_p->name, target_p->name);
392    
393 adx 30 if (IsOper(target_p))
394     sendto_one(source_p, form_str((IsAdmin(target_p) &&
395     !IsOperHiddenAdmin(target_p)) ? RPL_WHOISADMIN :
396     RPL_WHOISOPERATOR), me.name, source_p->name, target_p->name);
397    
398     if (IsOper(source_p) && IsCaptured(target_p))
399     sendto_one(source_p, form_str(RPL_ISCAPTURED),
400     me.name, source_p->name, target_p->name);
401    
402 db 280 if (ConfigFileEntry.use_whois_actually)
403 adx 30 {
404 db 280 int show_ip = 0;
405    
406 michael 472 if ((target_p->sockhost[0] != '\0') && irccmp(target_p->sockhost, "0"))
407 db 280 {
408     if ((IsAdmin(source_p) || source_p == target_p))
409     show_ip = 1;
410     else if (IsIPSpoof(target_p))
411     show_ip = (IsOper(source_p) && !ConfigFileEntry.hide_spoof_ips);
412     else
413     show_ip = 1;
414    
415 michael 472 sendto_one(source_p, form_str(RPL_WHOISACTUALLY),
416     me.name, source_p->name, target_p->name,
417     show_ip ? target_p->sockhost : "255.255.255.255");
418 db 280 }
419 adx 30 }
420    
421     if (MyConnect(target_p)) /* Can't do any of this if not local! db */
422     {
423     #ifdef HAVE_LIBCRYPTO
424     if (target_p->localClient->fd.ssl)
425 michael 1114 sendto_one(source_p, form_str(RPL_WHOISSECURE),
426 adx 30 me.name, source_p->name, target_p->name);
427     #endif
428     sendto_one(source_p, form_str(RPL_WHOISIDLE),
429     me.name, source_p->name, target_p->name,
430     CurrentTime - target_p->localClient->last,
431     target_p->firsttime);
432 michael 1144
433     if (IsOper(target_p) && target_p != source_p)
434     if ((target_p->umodes & UMODE_SPY))
435     sendto_one(target_p, ":%s NOTICE %s :*** Notice -- %s (%s@%s) [%s] is doing "
436     "a whois on you", me.name, target_p->name, source_p->name,
437     source_p->username, source_p->host, source_p->servptr->name);
438 adx 30 }
439     }

Properties

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