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

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

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


Revision 1.1 - (show annotations) (download) (as text)
Mon Jul 26 21:11:06 2010 UTC (8 years, 9 months ago) by simple
Branch point for: eggheads, MAIN
File MIME type: text/x-chdr
Initial revision

1 /*
2 * flags.c -- handles:
3 * all the flag matching/conversion functions in one neat package :)
4 *
5 * $Id: flags.c,v 1.36 2010/01/03 13:27:32 pseudo Exp $
6 */
7 /*
8 * Copyright (C) 1997 Robey Pointer
9 * Copyright (C) 1999 - 2010 Eggheads Development Team
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */
25
26 #include "main.h"
27
28
29 extern int raw_log, require_p, noshare, allow_dk_cmds;
30 extern struct dcc_t *dcc;
31
32
33 int logmodes(char *s)
34 {
35 int i;
36 int res = 0;
37
38 for (i = 0; i < strlen(s); i++)
39 switch (s[i]) {
40 case 'm':
41 case 'M':
42 res |= LOG_MSGS;
43 break;
44 case 'p':
45 case 'P':
46 res |= LOG_PUBLIC;
47 break;
48 case 'j':
49 case 'J':
50 res |= LOG_JOIN;
51 break;
52 case 'k':
53 case 'K':
54 res |= LOG_MODES;
55 break;
56 case 'c':
57 case 'C':
58 res |= LOG_CMDS;
59 break;
60 case 'o':
61 case 'O':
62 res |= LOG_MISC;
63 break;
64 case 'b':
65 case 'B':
66 res |= LOG_BOTS;
67 break;
68 case 'r':
69 case 'R':
70 res |= raw_log ? LOG_RAW : 0;
71 break;
72 case 'w':
73 case 'W':
74 res |= LOG_WALL;
75 break;
76 case 'x':
77 case 'X':
78 res |= LOG_FILES;
79 break;
80 case 's':
81 case 'S':
82 res |= LOG_SERV;
83 break;
84 case 'd':
85 case 'D':
86 res |= LOG_DEBUG;
87 break;
88 case 'v':
89 case 'V':
90 res |= raw_log ? LOG_SRVOUT : 0;
91 break;
92 case 't':
93 case 'T':
94 res |= raw_log ? LOG_BOTNET : 0;
95 break;
96 case 'h':
97 case 'H':
98 res |= raw_log ? LOG_BOTSHARE : 0;
99 break;
100 case '1':
101 res |= LOG_LEV1;
102 break;
103 case '2':
104 res |= LOG_LEV2;
105 break;
106 case '3':
107 res |= LOG_LEV3;
108 break;
109 case '4':
110 res |= LOG_LEV4;
111 break;
112 case '5':
113 res |= LOG_LEV5;
114 break;
115 case '6':
116 res |= LOG_LEV6;
117 break;
118 case '7':
119 res |= LOG_LEV7;
120 break;
121 case '8':
122 res |= LOG_LEV8;
123 break;
124 case '*':
125 res |= LOG_ALL;
126 break;
127 }
128 return res;
129 }
130
131 char *masktype(int x)
132 {
133 static char s[24]; /* Change this if you change the levels */
134 char *p = s;
135
136 if (x & LOG_MSGS)
137 *p++ = 'm';
138 if (x & LOG_PUBLIC)
139 *p++ = 'p';
140 if (x & LOG_JOIN)
141 *p++ = 'j';
142 if (x & LOG_MODES)
143 *p++ = 'k';
144 if (x & LOG_CMDS)
145 *p++ = 'c';
146 if (x & LOG_MISC)
147 *p++ = 'o';
148 if (x & LOG_BOTS)
149 *p++ = 'b';
150 if ((x & LOG_RAW) && raw_log)
151 *p++ = 'r';
152 if (x & LOG_FILES)
153 *p++ = 'x';
154 if (x & LOG_SERV)
155 *p++ = 's';
156 if (x & LOG_DEBUG)
157 *p++ = 'd';
158 if (x & LOG_WALL)
159 *p++ = 'w';
160 if ((x & LOG_SRVOUT) && raw_log)
161 *p++ = 'v';
162 if ((x & LOG_BOTNET) && raw_log)
163 *p++ = 't';
164 if ((x & LOG_BOTSHARE) && raw_log)
165 *p++ = 'h';
166 if (x & LOG_LEV1)
167 *p++ = '1';
168 if (x & LOG_LEV2)
169 *p++ = '2';
170 if (x & LOG_LEV3)
171 *p++ = '3';
172 if (x & LOG_LEV4)
173 *p++ = '4';
174 if (x & LOG_LEV5)
175 *p++ = '5';
176 if (x & LOG_LEV6)
177 *p++ = '6';
178 if (x & LOG_LEV7)
179 *p++ = '7';
180 if (x & LOG_LEV8)
181 *p++ = '8';
182 if (p == s)
183 *p++ = '-';
184 *p = 0;
185 return s;
186 }
187
188 char *maskname(int x)
189 {
190 static char s[207]; /* Change this if you change the levels */
191 int i = 0;
192
193 s[0] = 0;
194 if (x & LOG_MSGS)
195 i += my_strcpy(s, "msgs, ");
196 if (x & LOG_PUBLIC)
197 i += my_strcpy(s + i, "public, ");
198 if (x & LOG_JOIN)
199 i += my_strcpy(s + i, "joins, ");
200 if (x & LOG_MODES)
201 i += my_strcpy(s + i, "kicks/modes, ");
202 if (x & LOG_CMDS)
203 i += my_strcpy(s + i, "cmds, ");
204 if (x & LOG_MISC)
205 i += my_strcpy(s + i, "misc, ");
206 if (x & LOG_BOTS)
207 i += my_strcpy(s + i, "bots, ");
208 if ((x & LOG_RAW) && raw_log)
209 i += my_strcpy(s + i, "raw, ");
210 if (x & LOG_FILES)
211 i += my_strcpy(s + i, "files, ");
212 if (x & LOG_SERV)
213 i += my_strcpy(s + i, "server, ");
214 if (x & LOG_DEBUG)
215 i += my_strcpy(s + i, "debug, ");
216 if (x & LOG_WALL)
217 i += my_strcpy(s + i, "wallops, ");
218 if ((x & LOG_SRVOUT) && raw_log)
219 i += my_strcpy(s + i, "server output, ");
220 if ((x & LOG_BOTNET) && raw_log)
221 i += my_strcpy(s + i, "botnet traffic, ");
222 if ((x & LOG_BOTSHARE) && raw_log)
223 i += my_strcpy(s + i, "share traffic, ");
224 if (x & LOG_LEV1)
225 i += my_strcpy(s + i, "level 1, ");
226 if (x & LOG_LEV2)
227 i += my_strcpy(s + i, "level 2, ");
228 if (x & LOG_LEV3)
229 i += my_strcpy(s + i, "level 3, ");
230 if (x & LOG_LEV4)
231 i += my_strcpy(s + i, "level 4, ");
232 if (x & LOG_LEV5)
233 i += my_strcpy(s + i, "level 5, ");
234 if (x & LOG_LEV6)
235 i += my_strcpy(s + i, "level 6, ");
236 if (x & LOG_LEV7)
237 i += my_strcpy(s + i, "level 7, ");
238 if (x & LOG_LEV8)
239 i += my_strcpy(s + i, "level 8, ");
240 if (i)
241 s[i - 2] = 0;
242 else
243 strcpy(s, "none");
244 return s;
245 }
246
247 /* Some flags are mutually exclusive -- this roots them out
248 */
249 int sanity_check(int atr)
250 {
251 if ((atr & USER_BOT) &&
252 (atr & (USER_PARTY | USER_MASTER | USER_COMMON | USER_OWNER)))
253 atr &= ~(USER_PARTY | USER_MASTER | USER_COMMON | USER_OWNER);
254 if ((atr & USER_OP) && (atr & USER_DEOP))
255 atr &= ~(USER_OP | USER_DEOP);
256 if ((atr & USER_HALFOP) && (atr & USER_DEHALFOP))
257 atr &= ~(USER_HALFOP | USER_DEHALFOP);
258 if ((atr & USER_AUTOOP) && (atr & USER_DEOP))
259 atr &= ~(USER_AUTOOP | USER_DEOP);
260 if ((atr & USER_AUTOHALFOP) && (atr & USER_DEHALFOP))
261 atr &= ~(USER_AUTOHALFOP | USER_DEHALFOP);
262 if ((atr & USER_VOICE) && (atr & USER_QUIET))
263 atr &= ~(USER_VOICE | USER_QUIET);
264 if ((atr & USER_GVOICE) && (atr & USER_QUIET))
265 atr &= ~(USER_GVOICE | USER_QUIET);
266 /* Can't be owner without also being master */
267 if (atr & USER_OWNER)
268 atr |= USER_MASTER;
269 /* Master implies botmaster, op and janitor */
270 if (atr & USER_MASTER)
271 atr |= USER_BOTMAST | USER_OP | USER_JANITOR;
272 /* Can't be botnet master without party-line access */
273 if (atr & USER_BOTMAST)
274 atr |= USER_PARTY;
275 /* Janitors can use the file area */
276 if (atr & USER_JANITOR)
277 atr |= USER_XFER;
278 /* Ops should be halfops */
279 if (atr & USER_OP)
280 atr |= USER_HALFOP;
281 return atr;
282 }
283
284 /* Sanity check on channel attributes
285 */
286 int chan_sanity_check(int chatr, int atr)
287 {
288 if ((chatr & USER_OP) && (chatr & USER_DEOP))
289 chatr &= ~(USER_OP | USER_DEOP);
290 if ((chatr & USER_HALFOP) && (chatr & USER_DEHALFOP))
291 chatr &= ~(USER_HALFOP | USER_DEHALFOP);
292 if ((chatr & USER_AUTOOP) && (chatr & USER_DEOP))
293 chatr &= ~(USER_AUTOOP | USER_DEOP);
294 if ((chatr & USER_AUTOHALFOP) && (chatr & USER_DEHALFOP))
295 chatr &= ~(USER_AUTOHALFOP | USER_DEHALFOP);
296 if ((chatr & USER_VOICE) && (chatr & USER_QUIET))
297 chatr &= ~(USER_VOICE | USER_QUIET);
298 if ((chatr & USER_GVOICE) && (chatr & USER_QUIET))
299 chatr &= ~(USER_GVOICE | USER_QUIET);
300 /* Can't be channel owner without also being channel master */
301 if (chatr & USER_OWNER)
302 chatr |= USER_MASTER;
303 /* Master implies op */
304 if (chatr & USER_MASTER)
305 chatr |= USER_OP;
306 /* Op implies halfop */
307 if (chatr & USER_OP)
308 chatr |= USER_HALFOP;
309 /* Can't be +s on chan unless you're a bot */
310 if (!(atr & USER_BOT))
311 chatr &= ~BOT_SHARE;
312 return chatr;
313 }
314
315 /* Get icon symbol for a user (depending on access level)
316 *
317 * (*) owner on any channel
318 * (+) master on any channel
319 * (%) botnet master
320 * (@) op on any channel
321 * (^) halfop on any channel
322 * (-) other
323 */
324 char geticon(int idx)
325 {
326 struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
327
328 if (!dcc[idx].user)
329 return '-';
330 get_user_flagrec(dcc[idx].user, &fr, 0);
331 if (glob_owner(fr) || chan_owner(fr))
332 return '*';
333 if (glob_master(fr) || chan_master(fr))
334 return '+';
335 if (glob_botmast(fr))
336 return '%';
337 if (glob_op(fr) || chan_op(fr))
338 return '@';
339 if (glob_halfop(fr) || chan_halfop(fr))
340 return '^';
341 return '-';
342 }
343
344 void break_down_flags(const char *string, struct flag_record *plus,
345 struct flag_record *minus)
346 {
347 struct flag_record *which = plus;
348 int mode = 0; /* 0 = glob, 1 = chan, 2 = bot */
349 int flags = plus->match;
350
351 if (!(flags & FR_GLOBAL)) {
352 if (flags & FR_BOT)
353 mode = 2;
354 else if (flags & FR_CHAN)
355 mode = 1;
356 else
357 return; /* We dont actually want any..huh? */
358 }
359 egg_bzero(plus, sizeof(struct flag_record));
360
361 if (minus)
362 egg_bzero(minus, sizeof(struct flag_record));
363
364 plus->match = FR_OR; /* Default binding type OR */
365 while (*string) {
366 switch (*string) {
367 case '+':
368 which = plus;
369 break;
370 case '-':
371 which = minus ? minus : plus;
372 break;
373 case '|':
374 case '&':
375 if (!mode) {
376 if (*string == '|')
377 plus->match = FR_OR;
378 else
379 plus->match = FR_AND;
380 }
381 which = plus;
382 mode++;
383 if ((mode == 2) && !(flags & (FR_CHAN | FR_BOT)))
384 string = "";
385 else if (mode == 3)
386 mode = 1;
387 break;
388 default:
389 if ((*string >= 'a') && (*string <= 'z')) {
390 switch (mode) {
391 case 0:
392 which->global |=1 << (*string - 'a');
393
394 break;
395 case 1:
396 which->chan |= 1 << (*string - 'a');
397 break;
398 case 2:
399 which->bot |= 1 << (*string - 'a');
400 }
401 } else if ((*string >= 'A') && (*string <= 'Z')) {
402 switch (mode) {
403 case 0:
404 which->udef_global |= 1 << (*string - 'A');
405 break;
406 case 1:
407 which->udef_chan |= 1 << (*string - 'A');
408 break;
409 }
410 } else if ((*string >= '0') && (*string <= '9')) {
411 switch (mode) {
412 /* Map 0->9 to A->K for glob/chan so they are not lost */
413 case 0:
414 which->udef_global |= 1 << (*string - '0');
415 break;
416 case 1:
417 which->udef_chan |= 1 << (*string - '0');
418 break;
419 case 2:
420 which->bot |= BOT_FLAG0 << (*string - '0');
421 break;
422 }
423 }
424 }
425 string++;
426 }
427 for (which = plus; which; which = (which == plus ? minus : 0)) {
428 which->global &=USER_VALID;
429
430 which->udef_global &= 0x03ffffff;
431 which->chan &= CHAN_VALID;
432 which->udef_chan &= 0x03ffffff;
433 which->bot &= BOT_VALID;
434 }
435 plus->match |= flags;
436 if (minus) {
437 minus->match |= flags;
438 if (!(plus->match & (FR_AND | FR_OR)))
439 plus->match |= FR_OR;
440 }
441 }
442
443 static int flag2str(char *string, int bot, int udef)
444 {
445 char x = 'a', *old = string;
446
447 while (bot && (x <= 'z')) {
448 if (bot & 1)
449 *string++ = x;
450 x++;
451 bot = bot >> 1;
452 }
453 x = 'A';
454 while (udef && (x <= 'Z')) {
455 if (udef & 1)
456 *string++ = x;
457 udef = udef >> 1;
458 x++;
459 }
460 if (string == old)
461 *string++ = '-';
462 return string - old;
463 }
464
465 static int bot2str(char *string, int bot)
466 {
467 char x = 'a', *old = string;
468
469 while (x < 'v') {
470 if (bot & 1)
471 *string++ = x;
472 x++;
473 bot >>= 1;
474 }
475 x = '0';
476 while (x <= '9') {
477 if (bot & 1)
478 *string++ = x;
479 x++;
480 bot >>= 1;
481 }
482 if (string == old)
483 *string++ = '-';
484 return string - old;
485 }
486
487 int build_flags(char *string, struct flag_record *plus,
488 struct flag_record *minus)
489 {
490 char *old = string;
491
492 if (plus->match & FR_GLOBAL) {
493 if (minus && (plus->global ||plus->udef_global))
494 *string++ = '+';
495 string += flag2str(string, plus->global, plus->udef_global);
496
497 if (minus && (minus->global ||minus->udef_global)) {
498 *string++ = '-';
499 string += flag2str(string, minus->global, minus->udef_global);
500 }
501 } else if (plus->match & FR_BOT) {
502 if (minus && plus->bot)
503 *string++ = '+';
504 string += bot2str(string, plus->bot);
505 if (minus && minus->bot) {
506 *string++ = '-';
507 string += bot2str(string, minus->bot);
508 }
509 }
510 if (plus->match & FR_CHAN) {
511 if (plus->match & (FR_GLOBAL | FR_BOT))
512 *string++ = (plus->match & FR_AND) ? '&' : '|';
513 if (minus && (plus->chan || plus->udef_chan))
514 *string++ = '+';
515 string += flag2str(string, plus->chan, plus->udef_chan);
516 if (minus && (minus->chan || minus->udef_chan)) {
517 *string++ = '-';
518 string += flag2str(string, minus->global, minus->udef_chan);
519 }
520 }
521 if (string == old) {
522 *string++ = '-';
523 *string = 0;
524 return 0;
525 }
526 *string = 0;
527 return string - old;
528 }
529
530 int flagrec_ok(struct flag_record *req, struct flag_record *have)
531 {
532 /* FIXME: flag masks with '&' in them won't be subject to
533 * further tests below. Example: 'o&j'
534 */
535 if (req->match & FR_AND)
536 return flagrec_eq(req, have);
537 else if (req->match & FR_OR) {
538 int hav = have->global;
539
540 /* Exception 1 - global +d/+k cant use -|-, unless they are +p */
541 if (!req->chan && !req->global && !req->udef_global && !req->udef_chan) {
542 if (!allow_dk_cmds) {
543 if (glob_party(*have))
544 return 1;
545 if (glob_kick(*have) || chan_kick(*have))
546 return 0; /* +k cant use -|- commands */
547 if (glob_deop(*have) || chan_deop(*have))
548 return 0; /* neither can +d's */
549 }
550 return 1;
551 }
552 /* The +n/+m checks aren't needed anymore because +n/+m
553 * automatically adds lower flags
554 */
555 if (!require_p && ((hav & USER_OP) || (have->chan & USER_OWNER)))
556 hav |= USER_PARTY;
557 if (hav & req->global)
558 return 1;
559 if (have->chan & req->chan)
560 return 1;
561 if (have->udef_global & req->udef_global)
562 return 1;
563 if (have->udef_chan & req->udef_chan)
564 return 1;
565 return 0;
566 }
567 return 0; /* fr0k3 binding, dont pass it */
568 }
569
570 int flagrec_eq(struct flag_record *req, struct flag_record *have)
571 {
572 if (req->match & FR_AND) {
573 if (req->match & FR_GLOBAL) {
574 if ((req->global & have->global) !=req->global)
575 return 0;
576 if ((req->udef_global & have->udef_global) != req->udef_global)
577 return 0;
578 }
579 if (req->match & FR_BOT)
580 if ((req->bot & have->bot) != req->bot)
581 return 0;
582 if (req->match & FR_CHAN) {
583 if ((req->chan & have->chan) != req->chan)
584 return 0;
585 if ((req->udef_chan & have->udef_chan) != req->udef_chan)
586 return 0;
587 }
588 return 1;
589 } else if (req->match & FR_OR) {
590 if (!req->chan && !req->global && !req->udef_chan &&
591 !req->udef_global && !req->bot)
592 return 1;
593 if (req->match & FR_GLOBAL) {
594 if (have->global & req->global)
595 return 1;
596 if (have->udef_global & req->udef_global)
597 return 1;
598 }
599 if (req->match & FR_BOT)
600 if (have->bot & req->bot)
601 return 1;
602 if (req->match & FR_CHAN) {
603 if (have->chan & req->chan)
604 return 1;
605 if (have->udef_chan & req->udef_chan)
606 return 1;
607 }
608 return 0;
609 }
610 return 0; /* fr0k3 binding, dont pass it */
611 }
612
613 void set_user_flagrec(struct userrec *u, struct flag_record *fr,
614 const char *chname)
615 {
616 struct chanuserrec *cr = NULL;
617 int oldflags = fr->match;
618 char buffer[100];
619 struct chanset_t *ch;
620
621 if (!u)
622 return;
623 if (oldflags & FR_GLOBAL) {
624 u->flags = fr->global;
625
626 u->flags_udef = fr->udef_global;
627 if (!noshare && !(u->flags & USER_UNSHARED)) {
628 fr->match = FR_GLOBAL;
629 build_flags(buffer, fr, NULL);
630 shareout(NULL, "a %s %s\n", u->handle, buffer);
631 }
632 }
633 if ((oldflags & FR_BOT) && (u->flags & USER_BOT))
634 set_user(&USERENTRY_BOTFL, u, (void *) fr->bot);
635 /* Don't share bot attrs */
636 if ((oldflags & FR_CHAN) && chname) {
637 for (cr = u->chanrec; cr; cr = cr->next)
638 if (!rfc_casecmp(chname, cr->channel))
639 break;
640 ch = findchan_by_dname(chname);
641 if (!cr && ch) {
642 cr = user_malloc(sizeof(struct chanuserrec));
643 egg_bzero(cr, sizeof(struct chanuserrec));
644
645 cr->next = u->chanrec;
646 u->chanrec = cr;
647 strncpyz(cr->channel, chname, sizeof cr->channel);
648 }
649 if (cr && ch) {
650 cr->flags = fr->chan;
651 cr->flags_udef = fr->udef_chan;
652 if (!noshare && !(u->flags & USER_UNSHARED) && channel_shared(ch)) {
653 fr->match = FR_CHAN;
654 build_flags(buffer, fr, NULL);
655 shareout(ch, "a %s %s %s\n", u->handle, buffer, chname);
656 }
657 }
658 }
659 fr->match = oldflags;
660 }
661
662 /* Always pass the dname (display name) to this function for chname <cybah>
663 */
664 void get_user_flagrec(struct userrec *u, struct flag_record *fr,
665 const char *chname)
666 {
667 struct chanuserrec *cr = NULL;
668
669 if (!u) {
670 fr->global = fr->udef_global = fr->chan = fr->udef_chan = fr->bot = 0;
671
672 return;
673 }
674 if (fr->match & FR_GLOBAL) {
675 fr->global = u->flags;
676
677 fr->udef_global = u->flags_udef;
678 } else {
679 fr->global = 0;
680
681 fr->udef_global = 0;
682 }
683 if (fr->match & FR_BOT) {
684 fr->bot = (long) get_user(&USERENTRY_BOTFL, u);
685 } else
686 fr->bot = 0;
687 if (fr->match & FR_CHAN) {
688 if (fr->match & FR_ANYWH) {
689 fr->chan = u->flags;
690 fr->udef_chan = u->flags_udef;
691 for (cr = u->chanrec; cr; cr = cr->next)
692 if (findchan_by_dname(cr->channel)) {
693 fr->chan |= cr->flags;
694 fr->udef_chan |= cr->flags_udef;
695 }
696 } else {
697 if (chname)
698 for (cr = u->chanrec; cr; cr = cr->next)
699 if (!rfc_casecmp(chname, cr->channel))
700 break;
701 if (cr) {
702 fr->chan = cr->flags;
703 fr->udef_chan = cr->flags_udef;
704 } else {
705 fr->chan = 0;
706 fr->udef_chan = 0;
707 }
708 }
709 }
710 }
711
712 static int botfl_unpack(struct userrec *u, struct user_entry *e)
713 {
714 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
715
716 break_down_flags(e->u.list->extra, &fr, NULL);
717 list_type_kill(e->u.list);
718 e->u.ulong = fr.bot;
719 return 1;
720 }
721
722 static int botfl_pack(struct userrec *u, struct user_entry *e)
723 {
724 char x[100];
725 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
726
727 fr.bot = e->u.ulong;
728 e->u.list = user_malloc(sizeof(struct list_type));
729 e->u.list->next = NULL;
730 e->u.list->extra = user_malloc(build_flags(x, &fr, NULL) + 1);
731 strcpy(e->u.list->extra, x);
732 return 1;
733 }
734
735 static int botfl_kill(struct user_entry *e)
736 {
737 nfree(e);
738 return 1;
739 }
740
741 static int botfl_write_userfile(FILE *f, struct userrec *u,
742 struct user_entry *e)
743 {
744 char x[100];
745 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
746
747 fr.bot = e->u.ulong;
748 build_flags(x, &fr, NULL);
749 if (fprintf(f, "--%s %s\n", e->type->name, x) == EOF)
750 return 0;
751 return 1;
752 }
753
754 static int botfl_set(struct userrec *u, struct user_entry *e, void *buf)
755 {
756 register long atr = ((long) buf & BOT_VALID);
757
758 if (!(u->flags & USER_BOT))
759 return 1; /* Don't even bother trying to set the
760 * flags for a non-bot */
761
762 if ((atr & BOT_HUB) && (atr & BOT_ALT))
763 atr &= ~BOT_ALT;
764 if (atr & BOT_REJECT) {
765 if (atr & BOT_SHARE)
766 atr &= ~(BOT_SHARE | BOT_REJECT);
767 if (atr & BOT_HUB)
768 atr &= ~(BOT_HUB | BOT_REJECT);
769 if (atr & BOT_ALT)
770 atr &= ~(BOT_ALT | BOT_REJECT);
771 }
772 if (!(atr & BOT_SHARE))
773 atr &= ~BOT_GLOBAL;
774 e->u.ulong = atr;
775 return 1;
776 }
777
778 static int botfl_tcl_get(Tcl_Interp *interp, struct userrec *u,
779 struct user_entry *e, int argc, char **argv)
780 {
781 char x[100];
782 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
783
784 fr.bot = e->u.ulong;
785 build_flags(x, &fr, NULL);
786 Tcl_AppendResult(interp, x, NULL);
787 return TCL_OK;
788 }
789
790 static int botfl_tcl_set(Tcl_Interp *irp, struct userrec *u,
791 struct user_entry *e, int argc, char **argv)
792 {
793 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
794
795 BADARGS(4, 4, " handle BOTFL flags");
796
797 if (u->flags & USER_BOT) {
798 /* Silently ignore for users */
799 break_down_flags(argv[3], &fr, NULL);
800 botfl_set(u, e, (void *) fr.bot);
801 }
802 return TCL_OK;
803 }
804
805 static int botfl_expmem(struct user_entry *e)
806 {
807 return 0;
808 }
809
810 static void botfl_display(int idx, struct user_entry *e)
811 {
812 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
813 char x[100];
814
815 fr.bot = e->u.ulong;
816 build_flags(x, &fr, NULL);
817 dprintf(idx, " BOT FLAGS: %s\n", x);
818 }
819
820 struct user_entry_type USERENTRY_BOTFL = {
821 0, /* always 0 ;) */
822 0,
823 def_dupuser,
824 botfl_unpack,
825 botfl_pack,
826 botfl_write_userfile,
827 botfl_kill,
828 def_get,
829 botfl_set,
830 botfl_tcl_get,
831 botfl_tcl_set,
832 botfl_expmem,
833 botfl_display,
834 "BOTFL"
835 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23