/[cvs]/eggdrop1.9/src/flags.c
ViewVC logotype

Contents of /eggdrop1.9/src/flags.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.42 - (show annotations) (download) (as text)
Tue Dec 16 21:45:35 2003 UTC (15 years, 11 months ago) by wcc
Branch: MAIN
CVS Tags: HEAD
Changes since 1.41: +1 -1 lines
File MIME type: text/x-chdr
FILE REMOVED
* src/ cleanups.

1 /*
2 * flags.c --
3 *
4 * all the flag matching/conversion functions in one neat package :)
5 */
6 /*
7 * Copyright (C) 1997 Robey Pointer
8 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Eggheads Development Team
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25 #ifndef lint
26 static const char rcsid[] = "$Id: flags.c,v 1.41 2003/12/11 00:49:11 wcc Exp $";
27 #endif
28
29 #include <ctype.h>
30 #include "main.h"
31 #include "logfile.h"
32 #include "chan.h" /* findchan_by_dname, */
33 #include "users.h" /* USERENTRY_BOTFL, get_user */
34 #include "dccutil.h" /* dprintf_eggdrop */
35 #include "userent.h" /* list_type_kill */
36 #include "flags.h" /* prototypes */
37
38 extern int raw_log;
39
40 typedef struct {
41 int flag;
42 char c;
43 char *type;
44 } logmode_mapping_t;
45
46 static logmode_mapping_t logmode_mappings[] = {
47 /*
48 {LOG_MSGS, 'm', "msgs"},
49 {LOG_PUBLIC, 'p', "public"},
50 {LOG_JOIN, 'j', "joins"},
51 {LOG_MODES, 'k', "kicks/modes"},
52 {LOG_CMDS, 'c', "cmds"},
53 {LOG_MISC, 'o', "misc"},
54 {LOG_BOTS, 'b', "bots"},
55 {LOG_RAW, 'r', "raw"},
56 {LOG_WALL, 'w', "wallops"},
57 {LOG_FILES, 'x', "files"},
58 {LOG_SERV, 's', "server"},
59 {LOG_DEBUG, 'd', "debug"},
60 {LOG_SRVOUT, 'v', "server output"},
61 {LOG_LEV1, '1', "level 1"},
62 {LOG_LEV2, '2', "level 2"},
63 {LOG_LEV3, '3', "level 3"},
64 {LOG_LEV4, '4', "level 4"},
65 {LOG_LEV5, '5', "level 5"},
66 {LOG_LEV6, '6', "level 6"},
67 {LOG_LEV7, '7', "level 7"},
68 {LOG_LEV8, '8', "level 8"},
69 */
70 {0}
71 };
72
73 #define NEEDS_RAW_LOG (LOG_RAW|LOG_SRVOUT|LOG_BOTNET)
74
75 int logmodes(char *s)
76 {
77 logmode_mapping_t *mapping;
78 int modes = 0;
79
80 return(0x7fffffff);
81 /*
82 while (*s) {
83 if (*s == '*') return(LOG_ALL);
84 for (mapping = logmode_mappings; mapping->type; mapping++) {
85 if (mapping->c == tolower(*s)) break;
86 }
87 if (mapping->type) modes |= mapping->flag;
88 s++;
89 }
90 return(modes);
91 */
92 }
93
94 char *masktype(int x)
95 {
96 static char s[30] = "abcdefghijklmnopqrstuvwxyz";
97 return(s);
98 /*
99 char *p = s;
100 logmode_mapping_t *mapping;
101
102 for (mapping = logmode_mappings; mapping->type; mapping++) {
103 if (x & mapping->flag) {
104 if ((mapping->flag & NEEDS_RAW_LOG) && !raw_log) continue;
105 *p++ = mapping->c;
106 }
107 }
108 if (p == s) *p++ = '-';
109 *p = 0;
110 return(s);
111 */
112 }
113
114 char *maskname(int x)
115 {
116 static char s[207]; /* Change this if you change the levels */
117 s[0] = 0;
118 return(s);
119 /*
120 logmode_mapping_t *mapping;
121 int len;
122
123 *s = 0;
124 for (mapping = logmode_mappings; mapping->type; mapping++) {
125 if (x & mapping->flag) {
126 if ((mapping->flag & NEEDS_RAW_LOG) && !raw_log) continue;
127 strcat(s, mapping->type);
128 strcat(s, ", ");
129 }
130 }
131 len = strlen(s);
132 if (len) s[len-2] = 0;
133 else strcpy(s, "none");
134 return(s);
135 */
136 }
137
138 /* Some flags are mutually exclusive -- this roots them out
139 */
140 int sanity_check(int atr)
141 {
142 if ((atr & USER_BOT) &&
143 (atr & (USER_PARTY | USER_MASTER | USER_OWNER)))
144 atr &= ~(USER_PARTY | USER_MASTER | USER_OWNER);
145 /* Can't be owner without also being master */
146 if (atr & USER_OWNER)
147 atr |= USER_MASTER;
148 /* Master implies botmaster, op and janitor */
149 if (atr & USER_MASTER)
150 atr |= USER_BOTMAST | USER_OP | USER_JANITOR;
151 /* Can't be botnet master without party-line access */
152 if (atr & USER_BOTMAST)
153 atr |= USER_PARTY;
154 /* Janitors can use the file area */
155 if (atr & USER_JANITOR)
156 atr |= USER_XFER;
157 return atr;
158 }
159
160 /* Sanity check on channel attributes
161 */
162 int chan_sanity_check(int chatr, int atr)
163 {
164 /* Can't be channel owner without also being channel master. */
165 if (chatr & USER_OWNER)
166 chatr |= USER_MASTER;
167 /* Master implies op */
168 if (chatr & USER_MASTER)
169 chatr |= USER_OP ;
170 return chatr;
171 }
172
173 /* Get icon symbol for a user (depending on access level)
174 *
175 * (*)owner on any channel
176 * (+)master on any channel
177 * (%) botnet master
178 * (@) op on any channel
179 * (-) other
180 */
181 char geticon(struct userrec *user)
182 {
183 struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
184
185 if (!user)
186 return '-';
187 get_user_flagrec(user, &fr, 0);
188 if (chan_owner(fr))
189 return '*';
190 if (chan_master(fr))
191 return '+';
192 if (glob_botmast(fr))
193 return '%';
194 if (chan_op(fr))
195 return '@';
196 return '-';
197 }
198
199 void break_down_flags(const char *string, struct flag_record *plus,
200 struct flag_record *minus)
201 {
202 struct flag_record *which = plus;
203 int mode = 0; /* 0 = glob, 1 = chan, 2 = bot */
204 int flags = plus->match;
205
206 if (!(flags & FR_GLOBAL)) {
207 if (flags & FR_BOT)
208 mode = 2;
209 else if (flags & FR_CHAN)
210 mode = 1;
211 else
212 return; /* We dont actually want any..huh? */
213 }
214 memset(plus, 0, sizeof(struct flag_record));
215
216 if (minus)
217 memset(minus, 0, sizeof(struct flag_record));
218
219 plus->match = FR_OR; /* Default binding type OR */
220 while (*string) {
221 switch (*string) {
222 case '+':
223 which = plus;
224 break;
225 case '-':
226 which = minus ? minus : plus;
227 break;
228 case '|':
229 case '&':
230 if (!mode) {
231 if (*string == '|')
232 plus->match = FR_OR;
233 else
234 plus->match = FR_AND;
235 }
236 which = plus;
237 mode++;
238 if ((mode == 2) && !(flags & (FR_CHAN | FR_BOT)))
239 string = "";
240 else if (mode == 3)
241 mode = 1;
242 break;
243 default:
244 if ((*string >= 'a') && (*string <= 'z')) {
245 switch (mode) {
246 case 0:
247 which->global |=1 << (*string - 'a');
248
249 break;
250 case 1:
251 which->chan |= 1 << (*string - 'a');
252 break;
253 case 2:
254 which->bot |= 1 << (*string - 'a');
255 }
256 } else if ((*string >= 'A') && (*string <= 'Z')) {
257 switch (mode) {
258 case 0:
259 which->udef_global |= 1 << (*string - 'A');
260 break;
261 case 1:
262 which->udef_chan |= 1 << (*string - 'A');
263 break;
264 }
265 } else if ((*string >= '0') && (*string <= '9')) {
266 switch (mode) {
267 /* Map 0->9 to A->K for glob/chan so they are not lost */
268 case 0:
269 which->udef_global |= 1 << (*string - '0');
270 break;
271 case 1:
272 which->udef_chan |= 1 << (*string - '0');
273 break;
274 case 2:
275 which->bot |= BOT_FLAG0 << (*string - '0');
276 break;
277 }
278 }
279 }
280 string++;
281 }
282 for (which = plus; which; which = (which == plus ? minus : 0)) {
283 which->global &=USER_VALID;
284
285 which->udef_global &= 0x03ffffff;
286 which->chan &= CHAN_VALID;
287 which->udef_chan &= 0x03ffffff;
288 which->bot &= BOT_VALID;
289 }
290 plus->match |= flags;
291 if (minus) {
292 minus->match |= flags;
293 if (!(plus->match & (FR_AND | FR_OR)))
294 plus->match |= FR_OR;
295 }
296 }
297
298 static int flag2str(char *string, int bot, int udef)
299 {
300 char x = 'a', *old = string;
301
302 while (bot && (x <= 'z')) {
303 if (bot & 1)
304 *string++ = x;
305 x++;
306 bot = bot >> 1;
307 }
308 x = 'A';
309 while (udef && (x <= 'Z')) {
310 if (udef & 1)
311 *string++ = x;
312 udef = udef >> 1;
313 x++;
314 }
315 if (string == old)
316 *string++ = '-';
317 return string - old;
318 }
319
320 static int bot2str(char *string, int bot)
321 {
322 char x = 'a', *old = string;
323
324 while (x < 'v') {
325 if (bot & 1)
326 *string++ = x;
327 x++;
328 bot >>= 1;
329 }
330 x = '0';
331 while (x <= '9') {
332 if (bot & 1)
333 *string++ = x;
334 x++;
335 bot >>= 1;
336 }
337 return string - old;
338 }
339
340 int build_flags(char *string, struct flag_record *plus,
341 struct flag_record *minus)
342 {
343 char *old = string;
344
345 if (plus->match & FR_GLOBAL) {
346 if (minus && (plus->global || plus->udef_global))
347 *string++ = '+';
348 string += flag2str(string, plus->global, plus->udef_global);
349
350 if (minus && (minus->global || minus->udef_global)) {
351 *string++ = '-';
352 string += flag2str(string, minus->global, minus->udef_global);
353 }
354 } else if (plus->match & FR_BOT) {
355 if (minus && plus->bot)
356 *string++ = '+';
357 string += bot2str(string, plus->bot);
358 if (minus && minus->bot) {
359 *string++ = '-';
360 string += bot2str(string, minus->bot);
361 }
362 }
363 if (plus->match & FR_CHAN) {
364 if (plus->match & (FR_GLOBAL | FR_BOT))
365 *string++ = (plus->match & FR_AND) ? '&' : '|';
366 if (minus && (plus->chan || plus->udef_chan))
367 *string++ = '+';
368 string += flag2str(string, plus->chan, plus->udef_chan);
369 if (minus && (minus->chan || minus->udef_chan)) {
370 *string++ = '-';
371 string += flag2str(string, minus->global, minus->udef_chan);
372 }
373 }
374 if ((plus->match & (FR_BOT | FR_CHAN)) == (FR_BOT | FR_CHAN)) {
375 *string++ = (plus->match & FR_AND) ? '&' : '|';
376 if (minus && plus->bot)
377 *string++ = '+';
378 string += bot2str(string, plus->bot);
379 if (minus && minus->bot) {
380 *string++ = '-';
381 string += bot2str(string, minus->bot);
382 }
383 }
384 if (string == old) {
385 *string++ = '-';
386 *string = 0;
387 return 0;
388 }
389 *string = 0;
390 return string - old;
391 }
392
393 /* Returns 1 if flags match, 0 if they don't. */
394 int flagrec_ok(struct flag_record *req,
395 struct flag_record *have)
396 {
397 if (req->match & FR_AND) {
398 return flagrec_eq(req, have);
399 } else if (req->match & FR_OR) {
400 int hav = have->global;
401
402 /* Exception 1 - global +d/+k cant use -|-, unless they are +p */
403 if (!req->chan && !req->global && !req->udef_global &&
404 !req->udef_chan) {
405 if (glob_party(*have))
406 return 1;
407 return 1;
408 }
409 if (hav & req->global)
410 return 1;
411 if (have->chan & req->chan)
412 return 1;
413 if (have->udef_global & req->udef_global)
414 return 1;
415 if (have->udef_chan & req->udef_chan)
416 return 1;
417 return 0;
418 }
419 return 0; /* fr0k3 binding, dont pass it */
420 }
421
422 /* Returns 1 if flags match, 0 if they don't. */
423 int flagrec_eq(struct flag_record *req, struct flag_record *have)
424 {
425 if (req->match & FR_AND) {
426 if (req->match & FR_GLOBAL) {
427 if ((req->global &have->global) !=req->global)
428 return 0;
429 if ((req->udef_global & have->udef_global) != req->udef_global)
430 return 0;
431 }
432 if (req->match & FR_BOT)
433 if ((req->bot & have->bot) != req->bot)
434 return 0;
435 if (req->match & FR_CHAN) {
436 if ((req->chan & have->chan) != req->chan)
437 return 0;
438 if ((req->udef_chan & have->udef_chan) != req->udef_chan)
439 return 0;
440 }
441 return 1;
442 } else if (req->match & FR_OR) {
443 if (!req->chan && !req->global && !req->udef_chan &&
444 !req->udef_global && !req->bot)
445 return 1;
446 if (req->match & FR_GLOBAL) {
447 if (have->global &req->global)
448 return 1;
449 if (have->udef_global & req->udef_global)
450 return 1;
451 }
452 if (req->match & FR_BOT)
453 if (have->bot & req->bot)
454 return 1;
455 if (req->match & FR_CHAN) {
456 if (have->chan & req->chan)
457 return 1;
458 if (have->udef_chan & req->udef_chan)
459 return 1;
460 }
461 return 0;
462 }
463 return 0; /* fr0k3 binding, dont pass it */
464 }
465
466 void set_user_flagrec(struct userrec *u, struct flag_record *fr,
467 const char *chname)
468 {
469 struct chanuserrec *cr = NULL;
470 int oldflags = fr->match;
471 char buffer[100];
472 struct chanset_t *ch;
473
474 if (!u)
475 return;
476 if (oldflags & FR_GLOBAL) {
477 u->flags = fr->global;
478 u->flags_udef = fr->udef_global;
479 }
480 if ((oldflags & FR_BOT) && (u->flags & USER_BOT))
481 set_user(&USERENTRY_BOTFL, u, (void *) fr->bot);
482 if ((oldflags & FR_CHAN) && chname) {
483 for (cr = u->chanrec; cr; cr = cr->next)
484 if (!irccmp(chname, cr->channel))
485 break;
486 ch = findchan_by_dname(chname);
487 if (!cr && ch) {
488 cr = calloc(1, sizeof(struct chanuserrec));
489 cr->next = u->chanrec;
490 u->chanrec = cr;
491 strlcpy(cr->channel, chname, sizeof cr->channel);
492 }
493 if (cr && ch) {
494 cr->flags = fr->chan;
495 cr->flags_udef = fr->udef_chan;
496 }
497 }
498 fr->match = oldflags;
499 }
500
501 /* Always pass the dname (display name) to this function for chname <cybah>
502 */
503 void get_user_flagrec(struct userrec *u, struct flag_record *fr,
504 const char *chname)
505 {
506 struct chanuserrec *cr = NULL;
507
508 if (!u) {
509 fr->global = fr->udef_global = fr->chan = fr->udef_chan = fr->bot = 0;
510 return;
511 }
512 if (fr->match & FR_GLOBAL) {
513 fr->global = u->flags;
514 fr->udef_global = u->flags_udef;
515 } else {
516 fr->global = 0;
517 fr->udef_global = 0;
518 }
519 if (fr->match & FR_BOT) {
520 fr->bot = (long) get_user(&USERENTRY_BOTFL, u);
521 } else
522 fr->bot = 0;
523 if (fr->match & FR_CHAN) {
524 if (fr->match & FR_ANYWH) {
525 fr->chan = u->flags;
526 fr->udef_chan = u->flags_udef;
527 for (cr = u->chanrec; cr; cr = cr->next)
528 if (findchan_by_dname(cr->channel)) {
529 fr->chan |= cr->flags;
530 fr->udef_chan |= cr->flags_udef;
531 }
532 } else {
533 if (chname)
534 for (cr = u->chanrec; cr; cr = cr->next)
535 if (!irccmp(chname, cr->channel))
536 break;
537 if (cr) {
538 fr->chan = cr->flags;
539 fr->udef_chan = cr->flags_udef;
540 } else {
541 fr->chan = 0;
542 fr->udef_chan = 0;
543 }
544 }
545 }
546 }
547
548 static int botfl_unpack(struct userrec *u, struct user_entry *e)
549 {
550 struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
551
552 break_down_flags(e->u.list->extra, &fr, NULL);
553 list_type_kill(e->u.list);
554 e->u.ulong = fr.bot;
555 return 1;
556 }
557
558 static int botfl_pack(struct userrec *u, struct user_entry *e)
559 {
560 char x[100];
561 struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
562
563 fr.bot = e->u.ulong;
564 e->u.list = malloc(sizeof(struct list_type));
565 e->u.list->next = NULL;
566 e->u.list->extra = malloc(build_flags(x, &fr, NULL) + 1);
567 strcpy(e->u.list->extra, x);
568 return 1;
569 }
570
571 static int botfl_kill(struct user_entry *e)
572 {
573 free(e);
574 return 1;
575 }
576
577 static int botfl_write_userfile(FILE *f, struct userrec *u,
578 struct user_entry *e)
579 {
580 char x[100];
581 struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
582
583 fr.bot = e->u.ulong;
584 build_flags(x, &fr, NULL);
585 if (fprintf(f, "--%s %s\n", e->type->name, x) == EOF)
586 return 0;
587 return 1;
588 }
589
590 static int botfl_set(struct userrec *u, struct user_entry *e, void *buf)
591 {
592 register long atr = ((long) buf & BOT_VALID);
593
594 if (!(u->flags & USER_BOT))
595 return 1; /* Don't even bother trying to set the
596 flags for a non-bot */
597
598 if ((atr & BOT_HUB) && (atr & BOT_ALT))
599 atr &= ~BOT_ALT;
600 if (atr & BOT_REJECT) {
601 if (atr & BOT_HUB)
602 atr &= ~(BOT_HUB | BOT_REJECT);
603 if (atr & BOT_ALT)
604 atr &= ~(BOT_ALT | BOT_REJECT);
605 }
606 e->u.ulong = atr;
607 return 1;
608 }
609
610 static void botfl_display(int idx, struct user_entry *e)
611 {
612 struct flag_record fr = {FR_BOT, 0, 0, 0, 0, 0};
613 char x[100];
614
615 fr.bot = e->u.ulong;
616 build_flags(x, &fr, NULL);
617 dprintf(idx, " BOT FLAGS: %s\n", x);
618 }
619
620 struct user_entry_type USERENTRY_BOTFL =
621 {
622 0, /* always 0 ;) */
623 0,
624 def_dupuser,
625 botfl_unpack,
626 botfl_pack,
627 botfl_write_userfile,
628 botfl_kill,
629 def_get,
630 botfl_set,
631 NULL,
632 NULL,
633 botfl_display,
634 "BOTFL"
635 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23