00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "main.h"
00027
00028
00029 extern int raw_log, require_p, noshare, allow_dk_cmds;
00030 extern struct dcc_t *dcc;
00031
00032
00033 int logmodes(char *s)
00034 {
00035 int i;
00036 int res = 0;
00037
00038 for (i = 0; i < strlen(s); i++)
00039 switch (s[i]) {
00040 case 'm':
00041 case 'M':
00042 res |= LOG_MSGS;
00043 break;
00044 case 'p':
00045 case 'P':
00046 res |= LOG_PUBLIC;
00047 break;
00048 case 'j':
00049 case 'J':
00050 res |= LOG_JOIN;
00051 break;
00052 case 'k':
00053 case 'K':
00054 res |= LOG_MODES;
00055 break;
00056 case 'c':
00057 case 'C':
00058 res |= LOG_CMDS;
00059 break;
00060 case 'o':
00061 case 'O':
00062 res |= LOG_MISC;
00063 break;
00064 case 'b':
00065 case 'B':
00066 res |= LOG_BOTS;
00067 break;
00068 case 'r':
00069 case 'R':
00070 res |= raw_log ? LOG_RAW : 0;
00071 break;
00072 case 'w':
00073 case 'W':
00074 res |= LOG_WALL;
00075 break;
00076 case 'x':
00077 case 'X':
00078 res |= LOG_FILES;
00079 break;
00080 case 's':
00081 case 'S':
00082 res |= LOG_SERV;
00083 break;
00084 case 'd':
00085 case 'D':
00086 res |= LOG_DEBUG;
00087 break;
00088 case 'v':
00089 case 'V':
00090 res |= raw_log ? LOG_SRVOUT : 0;
00091 break;
00092 case 't':
00093 case 'T':
00094 res |= raw_log ? LOG_BOTNET : 0;
00095 break;
00096 case 'h':
00097 case 'H':
00098 res |= raw_log ? LOG_BOTSHARE : 0;
00099 break;
00100 case '1':
00101 res |= LOG_LEV1;
00102 break;
00103 case '2':
00104 res |= LOG_LEV2;
00105 break;
00106 case '3':
00107 res |= LOG_LEV3;
00108 break;
00109 case '4':
00110 res |= LOG_LEV4;
00111 break;
00112 case '5':
00113 res |= LOG_LEV5;
00114 break;
00115 case '6':
00116 res |= LOG_LEV6;
00117 break;
00118 case '7':
00119 res |= LOG_LEV7;
00120 break;
00121 case '8':
00122 res |= LOG_LEV8;
00123 break;
00124 case '*':
00125 res |= LOG_ALL;
00126 break;
00127 }
00128 return res;
00129 }
00130
00131 char *masktype(int x)
00132 {
00133 static char s[24];
00134 char *p = s;
00135
00136 if (x & LOG_MSGS)
00137 *p++ = 'm';
00138 if (x & LOG_PUBLIC)
00139 *p++ = 'p';
00140 if (x & LOG_JOIN)
00141 *p++ = 'j';
00142 if (x & LOG_MODES)
00143 *p++ = 'k';
00144 if (x & LOG_CMDS)
00145 *p++ = 'c';
00146 if (x & LOG_MISC)
00147 *p++ = 'o';
00148 if (x & LOG_BOTS)
00149 *p++ = 'b';
00150 if ((x & LOG_RAW) && raw_log)
00151 *p++ = 'r';
00152 if (x & LOG_FILES)
00153 *p++ = 'x';
00154 if (x & LOG_SERV)
00155 *p++ = 's';
00156 if (x & LOG_DEBUG)
00157 *p++ = 'd';
00158 if (x & LOG_WALL)
00159 *p++ = 'w';
00160 if ((x & LOG_SRVOUT) && raw_log)
00161 *p++ = 'v';
00162 if ((x & LOG_BOTNET) && raw_log)
00163 *p++ = 't';
00164 if ((x & LOG_BOTSHARE) && raw_log)
00165 *p++ = 'h';
00166 if (x & LOG_LEV1)
00167 *p++ = '1';
00168 if (x & LOG_LEV2)
00169 *p++ = '2';
00170 if (x & LOG_LEV3)
00171 *p++ = '3';
00172 if (x & LOG_LEV4)
00173 *p++ = '4';
00174 if (x & LOG_LEV5)
00175 *p++ = '5';
00176 if (x & LOG_LEV6)
00177 *p++ = '6';
00178 if (x & LOG_LEV7)
00179 *p++ = '7';
00180 if (x & LOG_LEV8)
00181 *p++ = '8';
00182 if (p == s)
00183 *p++ = '-';
00184 *p = 0;
00185 return s;
00186 }
00187
00188 char *maskname(int x)
00189 {
00190 static char s[207];
00191 int i = 0;
00192
00193 s[0] = 0;
00194 if (x & LOG_MSGS)
00195 i += my_strcpy(s, "msgs, ");
00196 if (x & LOG_PUBLIC)
00197 i += my_strcpy(s + i, "public, ");
00198 if (x & LOG_JOIN)
00199 i += my_strcpy(s + i, "joins, ");
00200 if (x & LOG_MODES)
00201 i += my_strcpy(s + i, "kicks/modes, ");
00202 if (x & LOG_CMDS)
00203 i += my_strcpy(s + i, "cmds, ");
00204 if (x & LOG_MISC)
00205 i += my_strcpy(s + i, "misc, ");
00206 if (x & LOG_BOTS)
00207 i += my_strcpy(s + i, "bots, ");
00208 if ((x & LOG_RAW) && raw_log)
00209 i += my_strcpy(s + i, "raw, ");
00210 if (x & LOG_FILES)
00211 i += my_strcpy(s + i, "files, ");
00212 if (x & LOG_SERV)
00213 i += my_strcpy(s + i, "server, ");
00214 if (x & LOG_DEBUG)
00215 i += my_strcpy(s + i, "debug, ");
00216 if (x & LOG_WALL)
00217 i += my_strcpy(s + i, "wallops, ");
00218 if ((x & LOG_SRVOUT) && raw_log)
00219 i += my_strcpy(s + i, "server output, ");
00220 if ((x & LOG_BOTNET) && raw_log)
00221 i += my_strcpy(s + i, "botnet traffic, ");
00222 if ((x & LOG_BOTSHARE) && raw_log)
00223 i += my_strcpy(s + i, "share traffic, ");
00224 if (x & LOG_LEV1)
00225 i += my_strcpy(s + i, "level 1, ");
00226 if (x & LOG_LEV2)
00227 i += my_strcpy(s + i, "level 2, ");
00228 if (x & LOG_LEV3)
00229 i += my_strcpy(s + i, "level 3, ");
00230 if (x & LOG_LEV4)
00231 i += my_strcpy(s + i, "level 4, ");
00232 if (x & LOG_LEV5)
00233 i += my_strcpy(s + i, "level 5, ");
00234 if (x & LOG_LEV6)
00235 i += my_strcpy(s + i, "level 6, ");
00236 if (x & LOG_LEV7)
00237 i += my_strcpy(s + i, "level 7, ");
00238 if (x & LOG_LEV8)
00239 i += my_strcpy(s + i, "level 8, ");
00240 if (i)
00241 s[i - 2] = 0;
00242 else
00243 strcpy(s, "none");
00244 return s;
00245 }
00246
00247
00248
00249 int sanity_check(int atr)
00250 {
00251 if ((atr & USER_BOT) &&
00252 (atr & (USER_PARTY | USER_MASTER | USER_COMMON | USER_OWNER)))
00253 atr &= ~(USER_PARTY | USER_MASTER | USER_COMMON | USER_OWNER);
00254 if ((atr & USER_OP) && (atr & USER_DEOP))
00255 atr &= ~(USER_OP | USER_DEOP);
00256 if ((atr & USER_HALFOP) && (atr & USER_DEHALFOP))
00257 atr &= ~(USER_HALFOP | USER_DEHALFOP);
00258 if ((atr & USER_AUTOOP) && (atr & USER_DEOP))
00259 atr &= ~(USER_AUTOOP | USER_DEOP);
00260 if ((atr & USER_AUTOHALFOP) && (atr & USER_DEHALFOP))
00261 atr &= ~(USER_AUTOHALFOP | USER_DEHALFOP);
00262 if ((atr & USER_VOICE) && (atr & USER_QUIET))
00263 atr &= ~(USER_VOICE | USER_QUIET);
00264 if ((atr & USER_GVOICE) && (atr & USER_QUIET))
00265 atr &= ~(USER_GVOICE | USER_QUIET);
00266
00267 if (atr & USER_OWNER)
00268 atr |= USER_MASTER;
00269
00270 if (atr & USER_MASTER)
00271 atr |= USER_BOTMAST | USER_OP | USER_JANITOR;
00272
00273 if (atr & USER_BOTMAST)
00274 atr |= USER_PARTY;
00275
00276 if (atr & USER_JANITOR)
00277 atr |= USER_XFER;
00278
00279 if (atr & USER_OP)
00280 atr |= USER_HALFOP;
00281 return atr;
00282 }
00283
00284
00285
00286 int chan_sanity_check(int chatr, int atr)
00287 {
00288 if ((chatr & USER_OP) && (chatr & USER_DEOP))
00289 chatr &= ~(USER_OP | USER_DEOP);
00290 if ((chatr & USER_HALFOP) && (chatr & USER_DEHALFOP))
00291 chatr &= ~(USER_HALFOP | USER_DEHALFOP);
00292 if ((chatr & USER_AUTOOP) && (chatr & USER_DEOP))
00293 chatr &= ~(USER_AUTOOP | USER_DEOP);
00294 if ((chatr & USER_AUTOHALFOP) && (chatr & USER_DEHALFOP))
00295 chatr &= ~(USER_AUTOHALFOP | USER_DEHALFOP);
00296 if ((chatr & USER_VOICE) && (chatr & USER_QUIET))
00297 chatr &= ~(USER_VOICE | USER_QUIET);
00298 if ((chatr & USER_GVOICE) && (chatr & USER_QUIET))
00299 chatr &= ~(USER_GVOICE | USER_QUIET);
00300
00301 if (chatr & USER_OWNER)
00302 chatr |= USER_MASTER;
00303
00304 if (chatr & USER_MASTER)
00305 chatr |= USER_OP;
00306
00307 if (chatr & USER_OP)
00308 chatr |= USER_HALFOP;
00309
00310 if (!(atr & USER_BOT))
00311 chatr &= ~BOT_SHARE;
00312 return chatr;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 char geticon(int idx)
00325 {
00326 struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
00327
00328 if (!dcc[idx].user)
00329 return '-';
00330 get_user_flagrec(dcc[idx].user, &fr, 0);
00331 if (glob_owner(fr) || chan_owner(fr))
00332 return '*';
00333 if (glob_master(fr) || chan_master(fr))
00334 return '+';
00335 if (glob_botmast(fr))
00336 return '%';
00337 if (glob_op(fr) || chan_op(fr))
00338 return '@';
00339 if (glob_halfop(fr) || chan_halfop(fr))
00340 return '^';
00341 return '-';
00342 }
00343
00344 void break_down_flags(const char *string, struct flag_record *plus,
00345 struct flag_record *minus)
00346 {
00347 struct flag_record *which = plus;
00348 int mode = 0;
00349 int flags = plus->match;
00350
00351 if (!(flags & FR_GLOBAL)) {
00352 if (flags & FR_BOT)
00353 mode = 2;
00354 else if (flags & FR_CHAN)
00355 mode = 1;
00356 else
00357 return;
00358 }
00359 egg_bzero(plus, sizeof(struct flag_record));
00360
00361 if (minus)
00362 egg_bzero(minus, sizeof(struct flag_record));
00363
00364 plus->match = FR_OR;
00365 while (*string) {
00366 switch (*string) {
00367 case '+':
00368 which = plus;
00369 break;
00370 case '-':
00371 which = minus ? minus : plus;
00372 break;
00373 case '|':
00374 case '&':
00375 if (!mode) {
00376 if (*string == '|')
00377 plus->match = FR_OR;
00378 else
00379 plus->match = FR_AND;
00380 }
00381 which = plus;
00382 mode++;
00383 if ((mode == 2) && !(flags & (FR_CHAN | FR_BOT)))
00384 string = "";
00385 else if (mode == 3)
00386 mode = 1;
00387 break;
00388 default:
00389 if ((*string >= 'a') && (*string <= 'z')) {
00390 switch (mode) {
00391 case 0:
00392 which->global |=1 << (*string - 'a');
00393
00394 break;
00395 case 1:
00396 which->chan |= 1 << (*string - 'a');
00397 break;
00398 case 2:
00399 which->bot |= 1 << (*string - 'a');
00400 }
00401 } else if ((*string >= 'A') && (*string <= 'Z')) {
00402 switch (mode) {
00403 case 0:
00404 which->udef_global |= 1 << (*string - 'A');
00405 break;
00406 case 1:
00407 which->udef_chan |= 1 << (*string - 'A');
00408 break;
00409 }
00410 } else if ((*string >= '0') && (*string <= '9')) {
00411 switch (mode) {
00412
00413 case 0:
00414 which->udef_global |= 1 << (*string - '0');
00415 break;
00416 case 1:
00417 which->udef_chan |= 1 << (*string - '0');
00418 break;
00419 case 2:
00420 which->bot |= BOT_FLAG0 << (*string - '0');
00421 break;
00422 }
00423 }
00424 }
00425 string++;
00426 }
00427 for (which = plus; which; which = (which == plus ? minus : 0)) {
00428 which->global &=USER_VALID;
00429
00430 which->udef_global &= 0x03ffffff;
00431 which->chan &= CHAN_VALID;
00432 which->udef_chan &= 0x03ffffff;
00433 which->bot &= BOT_VALID;
00434 }
00435 plus->match |= flags;
00436 if (minus) {
00437 minus->match |= flags;
00438 if (!(plus->match & (FR_AND | FR_OR)))
00439 plus->match |= FR_OR;
00440 }
00441 }
00442
00443 static int flag2str(char *string, int bot, int udef)
00444 {
00445 char x = 'a', *old = string;
00446
00447 while (bot && (x <= 'z')) {
00448 if (bot & 1)
00449 *string++ = x;
00450 x++;
00451 bot = bot >> 1;
00452 }
00453 x = 'A';
00454 while (udef && (x <= 'Z')) {
00455 if (udef & 1)
00456 *string++ = x;
00457 udef = udef >> 1;
00458 x++;
00459 }
00460 if (string == old)
00461 *string++ = '-';
00462 return string - old;
00463 }
00464
00465 static int bot2str(char *string, int bot)
00466 {
00467 char x = 'a', *old = string;
00468
00469 while (x < 'v') {
00470 if (bot & 1)
00471 *string++ = x;
00472 x++;
00473 bot >>= 1;
00474 }
00475 x = '0';
00476 while (x <= '9') {
00477 if (bot & 1)
00478 *string++ = x;
00479 x++;
00480 bot >>= 1;
00481 }
00482 if (string == old)
00483 *string++ = '-';
00484 return string - old;
00485 }
00486
00487 int build_flags(char *string, struct flag_record *plus,
00488 struct flag_record *minus)
00489 {
00490 char *old = string;
00491
00492 if (plus->match & FR_GLOBAL) {
00493 if (minus && (plus->global ||plus->udef_global))
00494 *string++ = '+';
00495 string += flag2str(string, plus->global, plus->udef_global);
00496
00497 if (minus && (minus->global ||minus->udef_global)) {
00498 *string++ = '-';
00499 string += flag2str(string, minus->global, minus->udef_global);
00500 }
00501 } else if (plus->match & FR_BOT) {
00502 if (minus && plus->bot)
00503 *string++ = '+';
00504 string += bot2str(string, plus->bot);
00505 if (minus && minus->bot) {
00506 *string++ = '-';
00507 string += bot2str(string, minus->bot);
00508 }
00509 }
00510 if (plus->match & FR_CHAN) {
00511 if (plus->match & (FR_GLOBAL | FR_BOT))
00512 *string++ = (plus->match & FR_AND) ? '&' : '|';
00513 if (minus && (plus->chan || plus->udef_chan))
00514 *string++ = '+';
00515 string += flag2str(string, plus->chan, plus->udef_chan);
00516 if (minus && (minus->chan || minus->udef_chan)) {
00517 *string++ = '-';
00518 string += flag2str(string, minus->global, minus->udef_chan);
00519 }
00520 }
00521 if (string == old) {
00522 *string++ = '-';
00523 *string = 0;
00524 return 0;
00525 }
00526 *string = 0;
00527 return string - old;
00528 }
00529
00530 int flagrec_ok(struct flag_record *req, struct flag_record *have)
00531 {
00532
00533
00534
00535 if (req->match & FR_AND)
00536 return flagrec_eq(req, have);
00537 else if (req->match & FR_OR) {
00538 int hav = have->global;
00539
00540
00541 if (!req->chan && !req->global && !req->udef_global && !req->udef_chan) {
00542 if (!allow_dk_cmds) {
00543 if (glob_party(*have))
00544 return 1;
00545 if (glob_kick(*have) || chan_kick(*have))
00546 return 0;
00547 if (glob_deop(*have) || chan_deop(*have))
00548 return 0;
00549 }
00550 return 1;
00551 }
00552
00553
00554
00555 if (!require_p && ((hav & USER_OP) || (have->chan & USER_OWNER)))
00556 hav |= USER_PARTY;
00557 if (hav & req->global)
00558 return 1;
00559 if (have->chan & req->chan)
00560 return 1;
00561 if (have->udef_global & req->udef_global)
00562 return 1;
00563 if (have->udef_chan & req->udef_chan)
00564 return 1;
00565 return 0;
00566 }
00567 return 0;
00568 }
00569
00570 int flagrec_eq(struct flag_record *req, struct flag_record *have)
00571 {
00572 if (req->match & FR_AND) {
00573 if (req->match & FR_GLOBAL) {
00574 if ((req->global & have->global) !=req->global)
00575 return 0;
00576 if ((req->udef_global & have->udef_global) != req->udef_global)
00577 return 0;
00578 }
00579 if (req->match & FR_BOT)
00580 if ((req->bot & have->bot) != req->bot)
00581 return 0;
00582 if (req->match & FR_CHAN) {
00583 if ((req->chan & have->chan) != req->chan)
00584 return 0;
00585 if ((req->udef_chan & have->udef_chan) != req->udef_chan)
00586 return 0;
00587 }
00588 return 1;
00589 } else if (req->match & FR_OR) {
00590 if (!req->chan && !req->global && !req->udef_chan &&
00591 !req->udef_global && !req->bot)
00592 return 1;
00593 if (req->match & FR_GLOBAL) {
00594 if (have->global & req->global)
00595 return 1;
00596 if (have->udef_global & req->udef_global)
00597 return 1;
00598 }
00599 if (req->match & FR_BOT)
00600 if (have->bot & req->bot)
00601 return 1;
00602 if (req->match & FR_CHAN) {
00603 if (have->chan & req->chan)
00604 return 1;
00605 if (have->udef_chan & req->udef_chan)
00606 return 1;
00607 }
00608 return 0;
00609 }
00610 return 0;
00611 }
00612
00613 void set_user_flagrec(struct userrec *u, struct flag_record *fr,
00614 const char *chname)
00615 {
00616 struct chanuserrec *cr = NULL;
00617 int oldflags = fr->match;
00618 char buffer[100];
00619 struct chanset_t *ch;
00620
00621 if (!u)
00622 return;
00623 if (oldflags & FR_GLOBAL) {
00624 u->flags = fr->global;
00625
00626 u->flags_udef = fr->udef_global;
00627 if (!noshare && !(u->flags & USER_UNSHARED)) {
00628 fr->match = FR_GLOBAL;
00629 build_flags(buffer, fr, NULL);
00630 shareout(NULL, "a %s %s\n", u->handle, buffer);
00631 }
00632 }
00633 if ((oldflags & FR_BOT) && (u->flags & USER_BOT))
00634 set_user(&USERENTRY_BOTFL, u, (void *) fr->bot);
00635
00636 if ((oldflags & FR_CHAN) && chname) {
00637 for (cr = u->chanrec; cr; cr = cr->next)
00638 if (!rfc_casecmp(chname, cr->channel))
00639 break;
00640 ch = findchan_by_dname(chname);
00641 if (!cr && ch) {
00642 cr = user_malloc(sizeof(struct chanuserrec));
00643 egg_bzero(cr, sizeof(struct chanuserrec));
00644
00645 cr->next = u->chanrec;
00646 u->chanrec = cr;
00647 strncpyz(cr->channel, chname, sizeof cr->channel);
00648 }
00649 if (cr && ch) {
00650 cr->flags = fr->chan;
00651 cr->flags_udef = fr->udef_chan;
00652 if (!noshare && !(u->flags & USER_UNSHARED) && channel_shared(ch)) {
00653 fr->match = FR_CHAN;
00654 build_flags(buffer, fr, NULL);
00655 shareout(ch, "a %s %s %s\n", u->handle, buffer, chname);
00656 }
00657 }
00658 }
00659 fr->match = oldflags;
00660 }
00661
00662
00663
00664 void get_user_flagrec(struct userrec *u, struct flag_record *fr,
00665 const char *chname)
00666 {
00667 struct chanuserrec *cr = NULL;
00668
00669 if (!u) {
00670 fr->global = fr->udef_global = fr->chan = fr->udef_chan = fr->bot = 0;
00671
00672 return;
00673 }
00674 if (fr->match & FR_GLOBAL) {
00675 fr->global = u->flags;
00676
00677 fr->udef_global = u->flags_udef;
00678 } else {
00679 fr->global = 0;
00680
00681 fr->udef_global = 0;
00682 }
00683 if (fr->match & FR_BOT) {
00684 fr->bot = (long) get_user(&USERENTRY_BOTFL, u);
00685 } else
00686 fr->bot = 0;
00687 if (fr->match & FR_CHAN) {
00688 if (fr->match & FR_ANYWH) {
00689 fr->chan = u->flags;
00690 fr->udef_chan = u->flags_udef;
00691 for (cr = u->chanrec; cr; cr = cr->next)
00692 if (findchan_by_dname(cr->channel)) {
00693 fr->chan |= cr->flags;
00694 fr->udef_chan |= cr->flags_udef;
00695 }
00696 } else {
00697 if (chname)
00698 for (cr = u->chanrec; cr; cr = cr->next)
00699 if (!rfc_casecmp(chname, cr->channel))
00700 break;
00701 if (cr) {
00702 fr->chan = cr->flags;
00703 fr->udef_chan = cr->flags_udef;
00704 } else {
00705 fr->chan = 0;
00706 fr->udef_chan = 0;
00707 }
00708 }
00709 }
00710 }
00711
00712 static int botfl_unpack(struct userrec *u, struct user_entry *e)
00713 {
00714 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
00715
00716 break_down_flags(e->u.list->extra, &fr, NULL);
00717 list_type_kill(e->u.list);
00718 e->u.ulong = fr.bot;
00719 return 1;
00720 }
00721
00722 static int botfl_pack(struct userrec *u, struct user_entry *e)
00723 {
00724 char x[100];
00725 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
00726
00727 fr.bot = e->u.ulong;
00728 e->u.list = user_malloc(sizeof(struct list_type));
00729 e->u.list->next = NULL;
00730 e->u.list->extra = user_malloc(build_flags(x, &fr, NULL) + 1);
00731 strcpy(e->u.list->extra, x);
00732 return 1;
00733 }
00734
00735 static int botfl_kill(struct user_entry *e)
00736 {
00737 nfree(e);
00738 return 1;
00739 }
00740
00741 static int botfl_write_userfile(FILE *f, struct userrec *u,
00742 struct user_entry *e)
00743 {
00744 char x[100];
00745 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
00746
00747 fr.bot = e->u.ulong;
00748 build_flags(x, &fr, NULL);
00749 if (fprintf(f, "--%s %s\n", e->type->name, x) == EOF)
00750 return 0;
00751 return 1;
00752 }
00753
00754 static int botfl_set(struct userrec *u, struct user_entry *e, void *buf)
00755 {
00756 register long atr = ((long) buf & BOT_VALID);
00757
00758 if (!(u->flags & USER_BOT))
00759 return 1;
00760
00761
00762 if ((atr & BOT_HUB) && (atr & BOT_ALT))
00763 atr &= ~BOT_ALT;
00764 if (atr & BOT_REJECT) {
00765 if (atr & BOT_SHARE)
00766 atr &= ~(BOT_SHARE | BOT_REJECT);
00767 if (atr & BOT_HUB)
00768 atr &= ~(BOT_HUB | BOT_REJECT);
00769 if (atr & BOT_ALT)
00770 atr &= ~(BOT_ALT | BOT_REJECT);
00771 }
00772 if (!(atr & BOT_SHARE))
00773 atr &= ~BOT_GLOBAL;
00774 e->u.ulong = atr;
00775 return 1;
00776 }
00777
00778 static int botfl_tcl_get(Tcl_Interp *interp, struct userrec *u,
00779 struct user_entry *e, int argc, char **argv)
00780 {
00781 char x[100];
00782 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
00783
00784 fr.bot = e->u.ulong;
00785 build_flags(x, &fr, NULL);
00786 Tcl_AppendResult(interp, x, NULL);
00787 return TCL_OK;
00788 }
00789
00790 static int botfl_tcl_set(Tcl_Interp *irp, struct userrec *u,
00791 struct user_entry *e, int argc, char **argv)
00792 {
00793 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
00794
00795 BADARGS(4, 4, " handle BOTFL flags");
00796
00797 if (u->flags & USER_BOT) {
00798
00799 break_down_flags(argv[3], &fr, NULL);
00800 botfl_set(u, e, (void *) fr.bot);
00801 }
00802 return TCL_OK;
00803 }
00804
00805 static int botfl_expmem(struct user_entry *e)
00806 {
00807 return 0;
00808 }
00809
00810 static void botfl_display(int idx, struct user_entry *e)
00811 {
00812 struct flag_record fr = { FR_BOT, 0, 0, 0, 0, 0 };
00813 char x[100];
00814
00815 fr.bot = e->u.ulong;
00816 build_flags(x, &fr, NULL);
00817 dprintf(idx, " BOT FLAGS: %s\n", x);
00818 }
00819
00820 struct user_entry_type USERENTRY_BOTFL = {
00821 0,
00822 0,
00823 def_dupuser,
00824 botfl_unpack,
00825 botfl_pack,
00826 botfl_write_userfile,
00827 botfl_kill,
00828 def_get,
00829 botfl_set,
00830 botfl_tcl_get,
00831 botfl_tcl_set,
00832 botfl_expmem,
00833 botfl_display,
00834 "BOTFL"
00835 };