ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_whois.c
Revision: 1793
Committed: Sun Mar 31 14:06:08 2013 UTC (12 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 10913 byte(s)
Log Message:
- Replaced all occurrences of ircsprintf with sprintf/snprintf
  and killed sprintf_irc.(c|h)

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

Properties

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