ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/contrib/m_flags.c
Revision: 1121
Committed: Sun Jan 9 11:03:03 2011 UTC (15 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 12945 byte(s)
Log Message:
- removed all instances of STATIC_MODULES since we don't have
  static modules anymore
- removed m_mkpasswd module from contrib

File Contents

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

Properties

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