ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/contrib/m_flags.c
Revision: 76
Committed: Tue Oct 4 19:38:49 2005 UTC (20 years, 10 months ago) by adx
Content type: text/x-csrc
File size: 12868 byte(s)
Log Message:
- fixed contrib #includes

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     #ifndef STATIC_MODULES
60     void
61     _modinit(void)
62     {
63     mod_add_cmd(&flags_msgtab);
64     }
65    
66     void
67     _moddeinit(void)
68     {
69     mod_del_cmd(&flags_msgtab);
70     }
71    
72 knight 31 const char *_version = "$Revision$";
73 adx 30 #endif
74    
75     /* FLAGS requires it's own mini parser, since the last parameter in it can
76     * contain a number of FLAGS. CS handles FLAGS mode1 mode2 OR
77     * FLAGS :mode1 mode2, but not both mixed.
78     *
79     * The best way to match a flag to a mode is with a simple table
80     */
81    
82     static struct FlagTable
83     {
84     const char *name;
85     unsigned int mode;
86     int oper;
87     } flag_table[] = {
88     /* name mode it represents oper only? */
89     { "OWALLOPS", UMODE_OPERWALL, 1 },
90     { "SWALLOPS", UMODE_WALLOP, 0 },
91     { "STATSNOTICES", UMODE_SPY, 1 },
92     /* We don't have a separate OKILL and SKILL modes */
93     { "OKILLS", UMODE_SKILL, 0 },
94     { "SKILLS", UMODE_SKILL, 0 },
95     { "SNOTICES", UMODE_SERVNOTICE, 0 },
96     /* We don't have separate client connect and disconnect modes */
97     { "CLICONNECTS", UMODE_CCONN, 1 },
98     { "CLIDISCONNECTS", UMODE_CCONN, 1 },
99     /* I'm taking a wild guess here... */
100     { "THROTTLES", UMODE_REJ, 1 },
101     #if 0
102     /* This one is special...controlled via an oper block option */
103     { "NICKCHANGES", UMODE_NCHANGE, 1 },
104     /* NICKCHANGES must be checked for separately */
105     #endif
106     /* I'm assuming this is correct... */
107     { "IPMISMATCHES", UMODE_UNAUTH, 1 },
108     { "LWALLOPS", UMODE_LOCOPS, 1 },
109     /* These aren't separate on Hybrid */
110     { "CONNECTS", UMODE_EXTERNAL, 1 },
111     { "SQUITS", UMODE_EXTERNAL, 1 },
112     /* Now we have our Hybrid specific flags */
113     { "FULL", UMODE_FULL, 1 },
114     /* Not in CS, but we might as well put it here */
115     { "INVISIBLE", UMODE_INVISIBLE, 0 },
116     { "BOTS", UMODE_BOTS, 1 },
117     { "CALLERID", UMODE_CALLERID, 0 },
118     { "UNAUTH", UMODE_UNAUTH, 1 },
119     { "DEBUG", UMODE_DEBUG, 1 },
120     { NULL, 0, 0 }
121     };
122    
123     /* We won't control CALLERID or INVISIBLE in here */
124    
125     #define FL_ALL_USER_FLAGS (UMODE_WALLOP | UMODE_SKILL | UMODE_SERVNOTICE )
126    
127     /* and we don't control NCHANGES here either */
128    
129     #define FL_ALL_OPER_FLAGS (FL_ALL_USER_FLAGS | UMODE_CCONN | UMODE_REJ |\
130     UMODE_FULL | UMODE_SPY | UMODE_DEBUG |\
131     UMODE_OPERWALL | UMODE_BOTS | UMODE_EXTERNAL |\
132     UMODE_UNAUTH | UMODE_LOCOPS )
133    
134     /* m_flags()
135     *
136     * parv[0] = sender prefix
137     * parv[1] = parameter
138     */
139     static void
140     m_flags(struct Client *client_p, struct Client *source_p,
141     int parc, char *parv[])
142     {
143     int i,j;
144     int isadd;
145     int isgood;
146     unsigned int setflags;
147     char *p;
148     char *flag;
149    
150     if (parc < 2)
151     {
152     /* Generate a list of what flags you have and what you are missing,
153     ** and send it to the user
154     */
155     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
156     me.name, parv[0], set_flags_to_string(source_p));
157     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
158     me.name, parv[0], unset_flags_to_string(source_p));
159     return;
160     }
161    
162     /* Preserve the current flags */
163     setflags = source_p->umodes;
164    
165     /* XXX - change this to support a multiple last parameter like ISON */
166    
167     for (i = 1; i < parc; i++)
168     {
169     for (flag = strtoken(&p, parv[i], " "); flag;
170     flag = strtoken(&p, NULL, " "))
171     {
172     /* We default to being in ADD mode */
173     isadd = 1;
174    
175     /* We default to being in BAD mode */
176     isgood = 0;
177    
178     if (!isalpha(*flag))
179     {
180     if (*flag == '-')
181     isadd = 0;
182     else if (*flag == '+')
183     isadd = 1;
184     ++flag;
185     }
186    
187     /* support ALL here */
188     if (!irccmp(flag, "ALL"))
189     {
190     if (isadd)
191     source_p->umodes |= FL_ALL_USER_FLAGS;
192     else
193     source_p->umodes &= ~FL_ALL_USER_FLAGS;
194     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
195     me.name, parv[0], set_flags_to_string(source_p));
196     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
197     me.name, parv[0], unset_flags_to_string(source_p));
198     send_umode_out(client_p, source_p, setflags);
199     return;
200     }
201    
202     for (j = 0; flag_table[j].name; j++)
203     {
204     if (!flag_table[j].oper && !irccmp(flag, flag_table[j].name))
205     {
206     if (isadd)
207     source_p->umodes |= flag_table[j].mode;
208     else
209     source_p->umodes &= ~flag_table[j].mode;
210     isgood = 1;
211     continue;
212     }
213     }
214     /* This for ended without matching a valid FLAG, here is where
215     * I want to operate differently than ircd-comstud, and just ignore
216     * the invalid flag, send a warning and go on.
217     */
218     if (!isgood)
219     sendto_one(source_p, ":%s NOTICE %s :Invalid FLAGS: %s (IGNORING)",
220     me.name, parv[0], flag);
221     }
222     }
223    
224     /* All done setting the flags, print the notices out to the user
225     * telling what flags they have and what flags they are missing
226     */
227     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
228     me.name, parv[0], set_flags_to_string(source_p));
229     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
230     me.name, parv[0], unset_flags_to_string(source_p));
231    
232     send_umode_out(client_p, source_p, setflags);
233     }
234    
235     /* mo_flags()
236     *
237     * parv[0] = sender prefix
238     * parv[1] = parameter
239     */
240     static void
241     mo_flags(struct Client *client_p, struct Client *source_p,
242     int parc, char *parv[])
243     {
244     int i,j;
245     int isadd;
246     int isgood;
247     unsigned int setflags;
248     char *p;
249     char *flag;
250    
251     if (parc < 2)
252     {
253     /* Generate a list of what flags you have and what you are missing,
254     ** and send it to the user
255     */
256     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
257     me.name, parv[0], set_flags_to_string(source_p));
258     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
259     me.name, parv[0], unset_flags_to_string(source_p));
260     return;
261     }
262    
263     /* Preserve the current flags */
264     setflags = source_p->umodes;
265    
266     /* XXX - change this to support a multiple last parameter like ISON */
267    
268     for (i = 1; i < parc; i++)
269     {
270     for (flag = strtoken(&p, parv[i], " "); flag;
271     flag = strtoken(&p, NULL, " "))
272     {
273     /* We default to being in ADD mode */
274     isadd = 1;
275    
276     /* We default to being in BAD mode */
277     isgood = 0;
278    
279     if (!isalpha(*flag))
280     {
281     if (*flag == '-')
282     isadd = 0;
283     else if (*flag == '+')
284     isadd = 1;
285     ++flag;
286     }
287    
288     /* support ALL here */
289     if (!irccmp(flag, "ALL"))
290     {
291     if (isadd)
292     source_p->umodes |= FL_ALL_OPER_FLAGS;
293     else
294     source_p->umodes &= ~FL_ALL_OPER_FLAGS;
295     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
296     me.name, parv[0], set_flags_to_string(source_p));
297     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
298     me.name, parv[0], unset_flags_to_string(source_p));
299     send_umode_out(client_p, source_p, setflags);
300     return;
301     }
302    
303     if (!irccmp(flag, "NICKCHANGES"))
304     {
305     if (!IsOperN(source_p))
306     {
307     sendto_one(source_p,
308     ":%s NOTICE %s :*** You have no nick_changes flag;",
309     me.name,parv[0]);
310     continue;
311     }
312     if (isadd)
313     source_p->umodes |= UMODE_NCHANGE;
314     else
315     source_p->umodes &= ~UMODE_NCHANGE;
316     isgood = 1;
317     continue;
318     }
319    
320     for (j = 0; flag_table[j].name; j++)
321     {
322     if (!irccmp(flag, flag_table[j].name))
323     {
324     if (isadd)
325     source_p->umodes |= flag_table[j].mode;
326     else
327     source_p->umodes &= ~ (flag_table[j].mode);
328     isgood = 1;
329     continue;
330     }
331     }
332     /* This for ended without matching a valid FLAG, here is where
333     * I want to operate differently than ircd-comstud, and just ignore
334     * the invalid flag, send a warning and go on.
335     */
336     if (!isgood)
337     sendto_one(source_p, ":%s NOTICE %s :Invalid FLAGS: %s (IGNORING)",
338     me.name, parv[0], flag);
339     }
340     }
341    
342     /* All done setting the flags, print the notices out to the user
343     ** telling what flags they have and what flags they are missing
344     */
345     sendto_one(source_p, ":%s NOTICE %s :Current flags:%s",
346     me.name, parv[0], set_flags_to_string(source_p));
347     sendto_one(source_p, ":%s NOTICE %s :Current missing flags:%s",
348     me.name, parv[0], unset_flags_to_string(source_p));
349    
350     send_umode_out(client_p, source_p, setflags);
351     }
352    
353     static char *
354     set_flags_to_string(struct Client *client_p)
355     {
356     /* XXX - list all flags that we have set on the client */
357     static char setflags[IRCD_BUFSIZE + 1];
358     int i;
359    
360     /* Clear it to begin with, we'll be doing a lot of ircsprintf's */
361     setflags[0] = '\0';
362    
363     /* Unlike unset_flags_to_string(), we don't have to care about oper
364     ** flags and not showing them
365     */
366    
367     for (i = 0; flag_table[i].name; i++)
368     {
369     if (client_p->umodes & flag_table[i].mode)
370     {
371     ircsprintf(setflags, "%s %s", setflags, flag_table[i].name);
372     }
373     }
374    
375     #if 0
376     if (IsOper(client_p) && IsOperN(client_p))
377     {
378     #endif
379     /* You can only be set +NICKCHANGES if you are an oper and
380     * IsOperN(client_p) is true
381     */
382     if (client_p->umodes & UMODE_NCHANGE)
383     {
384     ircsprintf(setflags, "%s %s", setflags, "NICKCHANGES");
385     }
386     #if 0
387     }
388     #endif
389     return setflags;
390     }
391    
392     static char *
393     unset_flags_to_string(struct Client *client_p)
394     {
395     /* Inverse of above */
396     /* XXX - list all flags that we do NOT have set on the client */
397     static char setflags[IRCD_BUFSIZE + 1];
398     int i, isoper;
399    
400     /* Clear it to begin with, we'll be doing a lot of ircsprintf's */
401     setflags[0] = '\0';
402    
403     isoper = IsOper(client_p) != 0;
404    
405     for (i = 0; flag_table[i].name; i++)
406     {
407     if (!(client_p->umodes & flag_table[i].mode))
408     {
409     if (!isoper && flag_table[i].oper)
410     continue;
411    
412     ircsprintf(setflags, "%s %s", setflags,
413     flag_table[i].name);
414     }
415     }
416    
417     if (IsOper(client_p) && IsOperN(client_p))
418     {
419     if (!(client_p->umodes & UMODE_NCHANGE))
420     {
421     ircsprintf(setflags, "%s %s", setflags, "NICKCHANGES");
422     }
423     }
424    
425     return setflags;
426     }

Properties

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