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

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

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


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

1 simple 1.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