ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/contrib/m_flags.c
Revision: 443
Committed: Sat Feb 11 23:37:10 2006 UTC (20 years, 6 months ago) by adx
Content type: text/x-csrc
File size: 12808 byte(s)
Log Message:
+ make it compile
+ fix contrib
+ fixed core when unloading spy_trace_notice, this one should be MFC'd
  (etrace_cb was not unhooked properly)

File Contents

# User Rev Content
1 adx 30 /*
2     * m_flags.c: Implements comstud-style mode flags.
3     *
4     * Copyright 2002 by W. Campbell and the ircd-hybrid development team
5     *
6     * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions are
8     * met:
9     *
10     * 1.Redistributions of source code must retain the above copyright notice,
11     * this list of conditions and the following disclaimer.
12     * 2.Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3.The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17     *
18     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20     * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21     * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22     * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24     * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26     * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27     * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28     * POSSIBILITY OF SUCH DAMAGE.
29     *
30 knight 31 * $Id$
31 adx 30 */
32    
33     /* List of ircd includes from ../include/ */
34     #include "stdinc.h"
35     #include "handlers.h"
36     #include "client.h"
37     #include "common.h" /* FALSE bleah */
38     #include "ircd.h"
39     #include "numeric.h"
40     #include "s_conf.h"
41     #include "s_serv.h"
42     #include "send.h"
43     #include "msg.h"
44     #include "parse.h"
45     #include "modules.h"
46     #include "s_user.h" /* send_umode_out() */
47    
48     static void m_flags(struct Client *, struct Client *, int, char *[]);
49     static void mo_flags(struct Client *, struct Client *, int, char *[]);
50    
51     static char *set_flags_to_string(struct Client *);
52     static char *unset_flags_to_string(struct Client *);
53    
54     struct Message flags_msgtab = {
55     "FLAGS", 0, 0, 0, 0, MFLG_SLOW, 0,
56     {m_unregistered, m_flags, m_ignore, m_ignore, mo_flags, m_ignore}
57     };
58    
59 adx 443 INIT_MODULE(m_flags, "$Revision$")
60 adx 30 {
61     mod_add_cmd(&flags_msgtab);
62     }
63    
64 adx 443 CLEANUP_MODULE
65 adx 30 {
66     mod_del_cmd(&flags_msgtab);
67     }
68    
69     /* FLAGS requires it's own mini parser, since the last parameter in it can
70     * contain a number of FLAGS. CS handles FLAGS mode1 mode2 OR
71     * FLAGS :mode1 mode2, but not both mixed.
72     *
73     * The best way to match a flag to a mode is with a simple table
74     */
75    
76     static struct FlagTable
77     {
78     const char *name;
79     unsigned int mode;
80     int oper;
81     } flag_table[] = {
82     /* name mode it represents oper only? */
83     { "OWALLOPS", UMODE_OPERWALL, 1 },
84     { "SWALLOPS", UMODE_WALLOP, 0 },
85     { "STATSNOTICES", UMODE_SPY, 1 },
86     /* We don't have a separate OKILL and SKILL modes */
87     { "OKILLS", UMODE_SKILL, 0 },
88     { "SKILLS", UMODE_SKILL, 0 },
89     { "SNOTICES", UMODE_SERVNOTICE, 0 },
90     /* We don't have separate client connect and disconnect modes */
91     { "CLICONNECTS", UMODE_CCONN, 1 },
92     { "CLIDISCONNECTS", UMODE_CCONN, 1 },
93     /* I'm taking a wild guess here... */
94     { "THROTTLES", UMODE_REJ, 1 },
95     #if 0
96     /* This one is special...controlled via an oper block option */
97     { "NICKCHANGES", UMODE_NCHANGE, 1 },
98     /* NICKCHANGES must be checked for separately */
99     #endif
100     /* I'm assuming this is correct... */
101     { "IPMISMATCHES", UMODE_UNAUTH, 1 },
102     { "LWALLOPS", UMODE_LOCOPS, 1 },
103     /* These aren't separate on Hybrid */
104     { "CONNECTS", UMODE_EXTERNAL, 1 },
105     { "SQUITS", UMODE_EXTERNAL, 1 },
106     /* Now we have our Hybrid specific flags */
107     { "FULL", UMODE_FULL, 1 },
108     /* Not in CS, but we might as well put it here */
109     { "INVISIBLE", UMODE_INVISIBLE, 0 },
110     { "BOTS", UMODE_BOTS, 1 },
111     { "CALLERID", UMODE_CALLERID, 0 },
112     { "UNAUTH", UMODE_UNAUTH, 1 },
113     { "DEBUG", UMODE_DEBUG, 1 },
114     { NULL, 0, 0 }
115     };
116    
117     /* We won't control CALLERID or INVISIBLE in here */
118    
119     #define FL_ALL_USER_FLAGS (UMODE_WALLOP | UMODE_SKILL | UMODE_SERVNOTICE )
120    
121     /* and we don't control NCHANGES here either */
122    
123     #define FL_ALL_OPER_FLAGS (FL_ALL_USER_FLAGS | UMODE_CCONN | UMODE_REJ |\
124     UMODE_FULL | UMODE_SPY | UMODE_DEBUG |\
125     UMODE_OPERWALL | UMODE_BOTS | UMODE_EXTERNAL |\
126     UMODE_UNAUTH | UMODE_LOCOPS )
127    
128     /* m_flags()
129     *
130     * parv[0] = sender prefix
131     * parv[1] = parameter
132     */
133     static void
134     m_flags(struct Client *client_p, struct Client *source_p,
135     int parc, char *parv[])
136     {
137     int i,j;
138     int isadd;
139     int isgood;
140     unsigned int setflags;
141     char *p;
142     char *flag;
143    
144     if (parc < 2)
145     {
146     /* Generate a list of what flags you have and what you are missing,
147     ** and send it to the user
148     */
149     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
150     me.name, parv[0], set_flags_to_string(source_p));
151     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
152     me.name, parv[0], unset_flags_to_string(source_p));
153     return;
154     }
155    
156     /* Preserve the current flags */
157     setflags = source_p->umodes;
158    
159     /* XXX - change this to support a multiple last parameter like ISON */
160    
161     for (i = 1; i < parc; i++)
162     {
163     for (flag = strtoken(&p, parv[i], " "); flag;
164     flag = strtoken(&p, NULL, " "))
165     {
166     /* We default to being in ADD mode */
167     isadd = 1;
168    
169     /* We default to being in BAD mode */
170     isgood = 0;
171    
172     if (!isalpha(*flag))
173     {
174     if (*flag == '-')
175     isadd = 0;
176     else if (*flag == '+')
177     isadd = 1;
178     ++flag;
179     }
180    
181     /* support ALL here */
182     if (!irccmp(flag, "ALL"))
183     {
184     if (isadd)
185     source_p->umodes |= FL_ALL_USER_FLAGS;
186     else
187     source_p->umodes &= ~FL_ALL_USER_FLAGS;
188     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
189     me.name, parv[0], set_flags_to_string(source_p));
190     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
191     me.name, parv[0], unset_flags_to_string(source_p));
192     send_umode_out(client_p, source_p, setflags);
193     return;
194     }
195    
196     for (j = 0; flag_table[j].name; j++)
197     {
198     if (!flag_table[j].oper && !irccmp(flag, flag_table[j].name))
199     {
200     if (isadd)
201     source_p->umodes |= flag_table[j].mode;
202     else
203     source_p->umodes &= ~flag_table[j].mode;
204     isgood = 1;
205     continue;
206     }
207     }
208     /* This for ended without matching a valid FLAG, here is where
209     * I want to operate differently than ircd-comstud, and just ignore
210     * the invalid flag, send a warning and go on.
211     */
212     if (!isgood)
213     sendto_one(source_p, ":%s NOTICE %s :Invalid FLAGS: %s (IGNORING)",
214     me.name, parv[0], flag);
215     }
216     }
217    
218     /* All done setting the flags, print the notices out to the user
219     * telling what flags they have and what flags they are missing
220     */
221     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
222     me.name, parv[0], set_flags_to_string(source_p));
223     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
224     me.name, parv[0], unset_flags_to_string(source_p));
225    
226     send_umode_out(client_p, source_p, setflags);
227     }
228    
229     /* mo_flags()
230     *
231     * parv[0] = sender prefix
232     * parv[1] = parameter
233     */
234     static void
235     mo_flags(struct Client *client_p, struct Client *source_p,
236     int parc, char *parv[])
237     {
238     int i,j;
239     int isadd;
240     int isgood;
241     unsigned int setflags;
242     char *p;
243     char *flag;
244    
245     if (parc < 2)
246     {
247     /* Generate a list of what flags you have and what you are missing,
248     ** and send it to the user
249     */
250     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
251     me.name, parv[0], set_flags_to_string(source_p));
252     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
253     me.name, parv[0], unset_flags_to_string(source_p));
254     return;
255     }
256    
257     /* Preserve the current flags */
258     setflags = source_p->umodes;
259    
260     /* XXX - change this to support a multiple last parameter like ISON */
261    
262     for (i = 1; i < parc; i++)
263     {
264     for (flag = strtoken(&p, parv[i], " "); flag;
265     flag = strtoken(&p, NULL, " "))
266     {
267     /* We default to being in ADD mode */
268     isadd = 1;
269    
270     /* We default to being in BAD mode */
271     isgood = 0;
272    
273     if (!isalpha(*flag))
274     {
275     if (*flag == '-')
276     isadd = 0;
277     else if (*flag == '+')
278     isadd = 1;
279     ++flag;
280     }
281    
282     /* support ALL here */
283     if (!irccmp(flag, "ALL"))
284     {
285     if (isadd)
286     source_p->umodes |= FL_ALL_OPER_FLAGS;
287     else
288     source_p->umodes &= ~FL_ALL_OPER_FLAGS;
289     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
290     me.name, parv[0], set_flags_to_string(source_p));
291     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
292     me.name, parv[0], unset_flags_to_string(source_p));
293     send_umode_out(client_p, source_p, setflags);
294     return;
295     }
296    
297     if (!irccmp(flag, "NICKCHANGES"))
298     {
299     if (!IsOperN(source_p))
300     {
301     sendto_one(source_p,
302     ":%s NOTICE %s :*** You have no nick_changes flag;",
303     me.name,parv[0]);
304     continue;
305     }
306     if (isadd)
307     source_p->umodes |= UMODE_NCHANGE;
308     else
309     source_p->umodes &= ~UMODE_NCHANGE;
310     isgood = 1;
311     continue;
312     }
313    
314     for (j = 0; flag_table[j].name; j++)
315     {
316     if (!irccmp(flag, flag_table[j].name))
317     {
318     if (isadd)
319     source_p->umodes |= flag_table[j].mode;
320     else
321     source_p->umodes &= ~ (flag_table[j].mode);
322     isgood = 1;
323     continue;
324     }
325     }
326     /* This for ended without matching a valid FLAG, here is where
327     * I want to operate differently than ircd-comstud, and just ignore
328     * the invalid flag, send a warning and go on.
329     */
330     if (!isgood)
331     sendto_one(source_p, ":%s NOTICE %s :Invalid FLAGS: %s (IGNORING)",
332     me.name, parv[0], flag);
333     }
334     }
335    
336     /* All done setting the flags, print the notices out to the user
337     ** telling what flags they have and what flags they are missing
338     */
339     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
340     me.name, parv[0], set_flags_to_string(source_p));
341     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
342     me.name, parv[0], unset_flags_to_string(source_p));
343    
344     send_umode_out(client_p, source_p, setflags);
345     }
346    
347     static char *
348     set_flags_to_string(struct Client *client_p)
349     {
350     /* XXX - list all flags that we have set on the client */
351     static char setflags[IRCD_BUFSIZE + 1];
352     int i;
353    
354     /* Clear it to begin with, we'll be doing a lot of ircsprintf's */
355     setflags[0] = '\0';
356    
357     /* Unlike unset_flags_to_string(), we don't have to care about oper
358     ** flags and not showing them
359     */
360    
361     for (i = 0; flag_table[i].name; i++)
362     {
363     if (client_p->umodes & flag_table[i].mode)
364     {
365     ircsprintf(setflags, "%s %s", setflags, flag_table[i].name);
366     }
367     }
368    
369     #if 0
370     if (IsOper(client_p) && IsOperN(client_p))
371     {
372     #endif
373     /* You can only be set +NICKCHANGES if you are an oper and
374     * IsOperN(client_p) is true
375     */
376     if (client_p->umodes & UMODE_NCHANGE)
377     {
378     ircsprintf(setflags, "%s %s", setflags, "NICKCHANGES");
379     }
380     #if 0
381     }
382     #endif
383     return setflags;
384     }
385    
386     static char *
387     unset_flags_to_string(struct Client *client_p)
388     {
389     /* Inverse of above */
390     /* XXX - list all flags that we do NOT have set on the client */
391     static char setflags[IRCD_BUFSIZE + 1];
392     int i, isoper;
393    
394     /* Clear it to begin with, we'll be doing a lot of ircsprintf's */
395     setflags[0] = '\0';
396    
397     isoper = IsOper(client_p) != 0;
398    
399     for (i = 0; flag_table[i].name; i++)
400     {
401     if (!(client_p->umodes & flag_table[i].mode))
402     {
403     if (!isoper && flag_table[i].oper)
404     continue;
405    
406     ircsprintf(setflags, "%s %s", setflags,
407     flag_table[i].name);
408     }
409     }
410    
411     if (IsOper(client_p) && IsOperN(client_p))
412     {
413     if (!(client_p->umodes & UMODE_NCHANGE))
414     {
415     ircsprintf(setflags, "%s %s", setflags, "NICKCHANGES");
416     }
417     }
418    
419     return setflags;
420     }

Properties

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