/[svn]/ircd-hybrid-7.2/contrib/m_flags.c
ViewVC logotype

Annotation of /ircd-hybrid-7.2/contrib/m_flags.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (hide annotations)
Sun Oct 2 20:03:27 2005 UTC (14 years, 9 months ago) by adx
Original Path: ircd-hybrid/contrib/m_flags.c
File MIME type: text/x-chdr
File size: 13033 byte(s)
- imported sources
- can be moved later according to the directory/branching scheme,
  but we need the svn up

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

Properties

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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28