ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/branches/newio/modules/m_who.c
Revision: 1406
Committed: Thu May 10 21:01:57 2012 UTC (11 years, 11 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_who.c
File size: 10386 byte(s)
Log Message:
- m_who(): replace two irccmp with strcmp

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_who.c: Shows who is on a channel.
4     *
5     * Copyright (C) 2002 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 michael 1011
25 adx 30 #include "stdinc.h"
26 michael 1011 #include "list.h"
27 adx 30 #include "client.h"
28     #include "channel.h"
29     #include "channel_mode.h"
30     #include "hash.h"
31     #include "ircd.h"
32     #include "numeric.h"
33     #include "s_serv.h"
34     #include "send.h"
35     #include "irc_string.h"
36     #include "sprintf_irc.h"
37 michael 1309 #include "conf.h"
38 adx 30 #include "parse.h"
39     #include "modules.h"
40    
41 michael 980 static void who_global(struct Client *, char *, int);
42     static void do_who(struct Client *, struct Client *,
43     const char *, const char *);
44     static void do_who_on_channel(struct Client *, struct Channel *,
45     const char *, int, int);
46 adx 30
47     /*
48     ** m_who
49     ** parv[0] = sender prefix
50     ** parv[1] = nickname mask list
51     ** parv[2] = additional selection flag, only 'o' for now.
52     */
53     static void
54     m_who(struct Client *client_p, struct Client *source_p,
55     int parc, char *parv[])
56     {
57     struct Client *target_p;
58     char *mask = parv[1];
59     dlink_node *lp;
60     int server_oper = parc > 2 ? (*parv[2] == 'o') : 0; /* Show OPERS only */
61     struct Channel *chptr;
62    
63     /* See if mask is there, collapse it or return if not there */
64 michael 980 if (EmptyString(mask))
65 adx 30 {
66     who_global(source_p, mask, server_oper);
67     sendto_one(source_p, form_str(RPL_ENDOFWHO),
68 michael 980 me.name, source_p->name, "*");
69 adx 30 return;
70     }
71    
72     /* mask isn't NULL at this point. repeat after me... -db */
73     collapse(mask);
74    
75     /* '/who *' */
76 michael 1406 if (!strcmp(mask, "*"))
77 adx 30 {
78     if ((lp = source_p->channel.head) != NULL)
79     {
80     struct Channel *mychannel = ((struct Membership *)lp->data)->chptr;
81 michael 1243 do_who_on_channel(source_p, mychannel, mychannel->chname, 1,
82 adx 30 server_oper);
83     }
84    
85 michael 1295 sendto_one(source_p, form_str(RPL_ENDOFWHO),
86     me.name, source_p->name, "*");
87 adx 30 return;
88     }
89    
90     /* '/who #some_channel' */
91     if (IsChanPrefix(*mask))
92     {
93     /* List all users on a given channel */
94     if ((chptr = hash_find_channel(mask)) != NULL)
95     {
96     if (IsMember(source_p, chptr))
97 michael 1243 do_who_on_channel(source_p, chptr, chptr->chname, 1, server_oper);
98 adx 30 else if (!SecretChannel(chptr))
99 michael 1243 do_who_on_channel(source_p, chptr, chptr->chname, 0, server_oper);
100 adx 30 }
101    
102     sendto_one(source_p, form_str(RPL_ENDOFWHO),
103 michael 980 me.name, source_p->name, mask);
104 adx 30 return;
105     }
106    
107     /* '/who nick' */
108 michael 1169 if (((target_p = hash_find_client(mask)) != NULL) &&
109 michael 1219 IsClient(target_p) && (!server_oper || HasUMode(target_p, UMODE_OPER)))
110 adx 30 {
111     DLINK_FOREACH(lp, target_p->channel.head)
112     {
113     chptr = ((struct Membership *) lp->data)->chptr;
114     if (PubChannel(chptr) || IsMember(source_p, chptr))
115     break;
116     }
117    
118     if (lp != NULL)
119     do_who(source_p, target_p, chptr->chname,
120 michael 1146 get_member_status(lp->data, !!HasCap(source_p, CAP_MULTI_PREFIX)));
121 adx 30 else
122     do_who(source_p, target_p, NULL, "");
123    
124     sendto_one(source_p, form_str(RPL_ENDOFWHO),
125 michael 980 me.name, source_p->name, mask);
126 adx 30 return;
127     }
128    
129     /* '/who 0' */
130 michael 1406 if (!strcmp(mask, "0"))
131 adx 30 who_global(source_p, NULL, server_oper);
132     else
133     who_global(source_p, mask, server_oper);
134    
135 michael 1146 /* Wasn't a nick, wasn't a channel, wasn't a '*' so ... */
136 adx 30 sendto_one(source_p, form_str(RPL_ENDOFWHO),
137 michael 980 me.name, source_p->name, mask);
138 adx 30 }
139    
140     /* who_common_channel
141     * inputs - pointer to client requesting who
142     * - pointer to channel member chain.
143     * - char * mask to match
144     * - int if oper on a server or not
145     * - pointer to int maxmatches
146     * output - NONE
147     * side effects - lists matching clients on specified channel,
148     * marks matched clients.
149     *
150     */
151     static void
152     who_common_channel(struct Client *source_p, struct Channel *chptr,
153     char *mask, int server_oper, int *maxmatches)
154     {
155 michael 1295 dlink_node *ptr = NULL;
156 adx 30
157     DLINK_FOREACH(ptr, chptr->members.head)
158     {
159 michael 1295 struct Client *target_p = ((struct Membership *)ptr->data)->client_p;
160 adx 30
161 michael 1219 if (!HasUMode(target_p, UMODE_INVISIBLE) || HasFlag(target_p, FLAGS_MARK))
162 adx 30 continue;
163    
164 michael 1295 if (server_oper)
165     if (!HasUMode(target_p, UMODE_OPER) ||
166     (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER)))
167     continue;
168 adx 30
169 michael 1219 AddFlag(target_p, FLAGS_MARK);
170 adx 30
171     assert(target_p->servptr != NULL);
172    
173     if ((mask == NULL) ||
174 adx 268 match(mask, target_p->name) || match(mask, target_p->username) ||
175     match(mask, target_p->host) ||
176 michael 1219 ((!ConfigServerHide.hide_servers || HasUMode(source_p, UMODE_OPER)) &&
177 adx 268 match(mask, target_p->servptr->name)) ||
178     match(mask, target_p->info))
179 adx 30 {
180     do_who(source_p, target_p, NULL, "");
181    
182     if (*maxmatches > 0)
183     {
184 adx 268 if (--(*maxmatches) == 0)
185     return;
186 adx 30 }
187     }
188     }
189     }
190    
191     /* who_global()
192     *
193     * inputs - pointer to client requesting who
194     * - char * mask to match
195     * - int if oper on a server or not
196     * output - NONE
197     * side effects - do a global scan of all clients looking for match
198     * this is slightly expensive on EFnet ...
199     */
200     static void
201     who_global(struct Client *source_p, char *mask, int server_oper)
202     {
203     struct Channel *chptr;
204     struct Client *target_p;
205     dlink_node *lp;
206     dlink_node *lp_next;
207     dlink_node *gcptr;
208     dlink_node *gcptr_next;
209     int maxmatches = 500;
210 michael 1230 static time_t last_used = 0;
211 adx 30
212 michael 1219 if (!HasUMode(source_p, UMODE_OPER))
213 adx 268 {
214     if ((last_used + ConfigFileEntry.pace_wait) > CurrentTime)
215     {
216     /* safe enough to give this on a local connect only */
217 michael 980 sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name);
218 adx 268 return;
219     }
220 michael 980
221     last_used = CurrentTime;
222 adx 268 }
223    
224 adx 30 /* first, list all matching invisible clients on common channels */
225     DLINK_FOREACH_SAFE(lp, lp_next, source_p->channel.head)
226     {
227     chptr = ((struct Membership *)lp->data)->chptr;
228     who_common_channel(source_p, chptr, mask, server_oper, &maxmatches);
229     }
230    
231     /* second, list all matching visible clients */
232     DLINK_FOREACH_SAFE(gcptr, gcptr_next, global_client_list.head)
233     {
234     target_p = gcptr->data;
235    
236     if (!IsClient(target_p))
237     continue;
238    
239 michael 1219 if (HasUMode(target_p, UMODE_INVISIBLE))
240 adx 30 {
241 michael 1219 DelFlag(target_p, FLAGS_MARK);
242 adx 30 continue;
243     }
244    
245 michael 1295 if (server_oper)
246     if (!HasUMode(target_p, UMODE_OPER) ||
247     (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER)))
248     continue;
249 adx 30
250     assert(target_p->servptr != NULL);
251    
252     if (!mask ||
253     match(mask, target_p->name) || match(mask, target_p->username) ||
254 adx 268 match(mask, target_p->host) || match(mask, target_p->servptr->name) ||
255     match(mask, target_p->info))
256 adx 30 {
257     do_who(source_p, target_p, NULL, "");
258    
259     if (maxmatches > 0)
260     {
261     if (--maxmatches == 0)
262 adx 268 return;
263 adx 30 }
264     }
265     }
266     }
267    
268     /* do_who_on_channel()
269     *
270     * inputs - pointer to client requesting who
271     * - pointer to channel to do who on
272     * - The "real name" of this channel
273     * - int if source_p is a server oper or not
274     * - int if client is member or not
275     * - int server_op flag
276     * output - NONE
277     * side effects - do a who on given channel
278     */
279     static void
280     do_who_on_channel(struct Client *source_p, struct Channel *chptr,
281     const char *chname, int member, int server_oper)
282     {
283 michael 313 dlink_node *ptr = NULL, *ptr_next = NULL;
284 adx 30 struct Client *target_p;
285     struct Membership *ms;
286    
287     DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head)
288     {
289     ms = ptr->data;
290     target_p = ms->client_p;
291    
292 michael 1219 if (member || !HasUMode(target_p, UMODE_INVISIBLE))
293 adx 30 {
294 michael 1295 if (server_oper)
295     if (!HasUMode(target_p, UMODE_OPER) ||
296     (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER)))
297     continue;
298 michael 1146 do_who(source_p, target_p, chname, get_member_status(ms, !!HasCap(source_p, CAP_MULTI_PREFIX)));
299 adx 30 }
300     }
301     }
302    
303     /* do_who()
304     *
305     * inputs - pointer to client requesting who
306     * - pointer to client to do who on
307     * - The reported name
308     * - channel flags
309     * output - NONE
310     * side effects - do a who on given person
311     */
312     static void
313     do_who(struct Client *source_p, struct Client *target_p,
314     const char *chname, const char *op_flags)
315     {
316 michael 1146 char status[8]; /* G*#@%+\0 */
317 adx 30
318 michael 1219 if (HasUMode(source_p, UMODE_OPER))
319 michael 1146 snprintf(status, sizeof(status), "%c%s%s%s", target_p->away ? 'G' : 'H',
320 michael 1219 HasUMode(target_p, UMODE_OPER) ? "*" : "",
321     IsCaptured(target_p) ? "#" : "", op_flags);
322 adx 30 else
323 michael 1146 snprintf(status, sizeof(status), "%c%s%s", target_p->away ? 'G' : 'H',
324 michael 1294 HasUMode(target_p, UMODE_OPER) &&
325     !HasUMode(target_p, UMODE_HIDDEN) ? "*" : "", op_flags);
326 adx 30
327     if (ConfigServerHide.hide_servers)
328     {
329 michael 980 sendto_one(source_p, form_str(RPL_WHOREPLY), me.name, source_p->name,
330 adx 30 (chname) ? (chname) : "*",
331 michael 980 target_p->username, target_p->host,
332 michael 1219 HasUMode(source_p, UMODE_OPER) ? target_p->servptr->name : "*",
333 adx 30 target_p->name, status, 0, target_p->info);
334     }
335     else
336     {
337 michael 980 sendto_one(source_p, form_str(RPL_WHOREPLY), me.name, source_p->name,
338     (chname) ? (chname) : "*", target_p->username,
339 adx 30 target_p->host, target_p->servptr->name, target_p->name,
340     status, target_p->hopcount, target_p->info);
341     }
342     }
343 michael 1230
344     static struct Message who_msgtab = {
345     "WHO", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
346     {m_unregistered, m_who, m_ignore, m_ignore, m_who, m_ignore}
347     };
348    
349     static void
350     module_init(void)
351     {
352     mod_add_cmd(&who_msgtab);
353     }
354    
355     static void
356     module_exit(void)
357     {
358     mod_del_cmd(&who_msgtab);
359     }
360    
361     struct module module_entry = {
362     .node = { NULL, NULL, NULL },
363     .name = NULL,
364     .version = "$Revision$",
365     .handle = NULL,
366     .modinit = module_init,
367     .modexit = module_exit,
368     .flags = 0
369     };

Properties

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