ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_whois.c
Revision: 1011
Committed: Fri Sep 18 10:14:09 2009 UTC (14 years, 7 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/m_whois.c
File size: 11218 byte(s)
Log Message:
- move list manipulation routines from tools.c to list.c
- mem_frob() goes to memory.c
- sort out redundant/unneeded header includes

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

Properties

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