00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "services.h"
00018 #include "pseudo.h"
00019
00020
00021
00022
00023 BotInfo *botlists[256];
00024 int nbots = 0;
00025
00026
00027
00028 static UserData *get_user_data(Channel * c, User * u);
00029
00030 static void check_ban(ChannelInfo * ci, User * u, int ttbtype);
00031 static void bot_kick(ChannelInfo * ci, User * u, int message, ...);
00032
00033 E void moduleAddBotServCmds(void);
00034
00035
00036
00037 void moduleAddBotServCmds(void) {
00038 modules_core_init(BotServCoreNumber, BotServCoreModules);
00039 }
00040
00041
00042
00043
00044
00045
00046 void get_botserv_stats(long *nrec, long *memuse)
00047 {
00048 long count = 0, mem = 0;
00049 int i;
00050 BotInfo *bi;
00051
00052 for (i = 0; i < 256; i++) {
00053 for (bi = botlists[i]; bi; bi = bi->next) {
00054 count++;
00055 mem += sizeof(*bi);
00056 mem += strlen(bi->nick) + 1;
00057 mem += strlen(bi->user) + 1;
00058 mem += strlen(bi->host) + 1;
00059 mem += strlen(bi->real) + 1;
00060 }
00061 }
00062
00063 *nrec = count;
00064 *memuse = mem;
00065 }
00066
00067
00068
00069
00070
00071
00072 void bs_init(void)
00073 {
00074 if (s_BotServ) {
00075 moduleAddBotServCmds();
00076 }
00077 }
00078
00079
00080
00081
00082
00083 void botserv(User * u, char *buf)
00084 {
00085 char *cmd, *s;
00086
00087 cmd = strtok(buf, " ");
00088
00089 if (!cmd) {
00090 return;
00091 } else if (stricmp(cmd, "\1PING") == 0) {
00092 if (!(s = strtok(NULL, ""))) {
00093 s = "";
00094 }
00095 anope_cmd_ctcp(s_BotServ, u->nick, "PING %s", s);
00096 } else if (skeleton) {
00097 notice_lang(s_BotServ, u, SERVICE_OFFLINE, s_BotServ);
00098 } else {
00099 mod_run_cmd(s_BotServ, u, BOTSERV, cmd);
00100 }
00101
00102 }
00103
00104
00105
00106
00107
00108 void botmsgs(User * u, BotInfo * bi, char *buf)
00109 {
00110 char *cmd = strtok(buf, " ");
00111 char *s;
00112
00113 if (!cmd || !u)
00114 return;
00115
00116 if (!stricmp(cmd, "\1PING")) {
00117 if (!(s = strtok(NULL, ""))) {
00118 s = "";
00119 }
00120 anope_cmd_ctcp(bi->nick, u->nick, "PING %s", s);
00121 }
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131 void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
00132 {
00133 int c;
00134 int16 cstatus = 0;
00135 char *cmd;
00136 UserData *ud;
00137
00138 if (!u || !buf || !ci) {
00139 return;
00140 }
00141
00142
00143 if (!strnicmp(buf, "\1PING", 5)) {
00144 anope_cmd_ctcp(ci->bi->nick, u->nick, "PING %s", buf);
00145 }
00146
00147
00148
00149
00150
00151 if (!strnicmp(buf, "\1ACTION ", 8))
00152 buf += 8;
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 if (ci->botflags & (BS_DONTKICKOPS | BS_DONTKICKVOICES))
00165 cstatus = chan_get_user_status(ci->c, u);
00166
00167 if (buf && !check_access(u, ci, CA_NOKICK) &&
00168 (!(ci->botflags & BS_DONTKICKOPS)
00169 || !(cstatus & (CUS_HALFOP | CUS_OP | CUS_OWNER | CUS_PROTECT)))
00170
00171 && (!(ci->botflags & BS_DONTKICKVOICES) || !(cstatus & CUS_VOICE))) {
00172
00173 if ((ci->botflags & BS_KICK_BOLDS) && strchr(buf, 2)) {
00174 check_ban(ci, u, TTB_BOLDS);
00175 bot_kick(ci, u, BOT_REASON_BOLD);
00176 return;
00177 }
00178
00179
00180 if ((ci->botflags & BS_KICK_COLORS) && strchr(buf, 3)) {
00181 check_ban(ci, u, TTB_COLORS);
00182 bot_kick(ci, u, BOT_REASON_COLOR);
00183 return;
00184 }
00185
00186
00187 if ((ci->botflags & BS_KICK_REVERSES) && strchr(buf, 22)) {
00188 check_ban(ci, u, TTB_REVERSES);
00189 bot_kick(ci, u, BOT_REASON_REVERSE);
00190 return;
00191 }
00192
00193
00194 if ((ci->botflags & BS_KICK_UNDERLINES) && strchr(buf, 31)) {
00195 check_ban(ci, u, TTB_UNDERLINES);
00196 bot_kick(ci, u, BOT_REASON_UNDERLINE);
00197 return;
00198 }
00199
00200
00201 if ((ci->botflags & BS_KICK_CAPS)
00202 && ((c = strlen(buf)) >= ci->capsmin)) {
00203 int i = 0;
00204 int l = 0;
00205 char *s = buf;
00206
00207 do {
00208 if (isupper(*s))
00209 i++;
00210 else if (islower(*s))
00211 l++;
00212 } while (*s++);
00213
00214
00215
00216
00217
00218
00219 if (i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent) {
00220 check_ban(ci, u, TTB_CAPS);
00221 bot_kick(ci, u, BOT_REASON_CAPS);
00222 return;
00223 }
00224 }
00225
00226
00227 if (ci->botflags & BS_KICK_BADWORDS) {
00228 int i;
00229 int mustkick = 0;
00230 char *nbuf;
00231 BadWord *bw;
00232
00233
00234 nbuf = normalizeBuffer(buf);
00235
00236 for (i = 0, bw = ci->badwords; i < ci->bwcount; i++, bw++) {
00237 if (!bw->in_use)
00238 continue;
00239
00240 if (bw->type == BW_ANY
00241 && ((BSCaseSensitive && strstr(nbuf, bw->word))
00242 || (!BSCaseSensitive && stristr(nbuf, bw->word)))) {
00243 mustkick = 1;
00244 } else if (bw->type == BW_SINGLE) {
00245 int len = strlen(bw->word);
00246
00247 if ((BSCaseSensitive && !strcmp(nbuf, bw->word))
00248 || (!BSCaseSensitive
00249 && (!stricmp(nbuf, bw->word)))) {
00250 mustkick = 1;
00251
00252 } else if ((strchr(nbuf, ' ') == nbuf + len)
00253 &&
00254 ((BSCaseSensitive
00255 && !strcmp(nbuf, bw->word))
00256 || (!BSCaseSensitive
00257 && (stristr(nbuf, bw->word) ==
00258 nbuf)))) {
00259 mustkick = 1;
00260 } else {
00261 if ((strrchr(nbuf, ' ') ==
00262 nbuf + strlen(nbuf) - len - 1)
00263 &&
00264 ((BSCaseSensitive
00265 && (strstr(nbuf, bw->word) ==
00266 nbuf + strlen(nbuf) - len))
00267 || (!BSCaseSensitive
00268 && (stristr(nbuf, bw->word) ==
00269 nbuf + strlen(nbuf) - len)))) {
00270 mustkick = 1;
00271 } else {
00272 char *wordbuf = scalloc(len + 3, 1);
00273
00274 wordbuf[0] = ' ';
00275 wordbuf[len + 1] = ' ';
00276 wordbuf[len + 2] = '\0';
00277 memcpy(wordbuf + 1, bw->word, len);
00278
00279 if ((BSCaseSensitive
00280 && (strstr(nbuf, wordbuf)))
00281 || (!BSCaseSensitive
00282 && (stristr(nbuf, wordbuf)))) {
00283 mustkick = 1;
00284 }
00285 }
00286 }
00287 } else if (bw->type == BW_START) {
00288 int len = strlen(bw->word);
00289
00290 if ((BSCaseSensitive
00291 && (!strncmp(nbuf, bw->word, len)))
00292 || (!BSCaseSensitive
00293 && (!strnicmp(nbuf, bw->word, len)))) {
00294 mustkick = 1;
00295 } else {
00296 char *wordbuf = scalloc(len + 2, 1);
00297
00298 memcpy(wordbuf + 1, bw->word, len);
00299 wordbuf[0] = ' ';
00300 wordbuf[len + 1] = '\0';
00301
00302 if ((BSCaseSensitive && (strstr(nbuf, wordbuf)))
00303 || (!BSCaseSensitive
00304 && (stristr(nbuf, wordbuf))))
00305 mustkick = 1;
00306
00307 free(wordbuf);
00308 }
00309 } else if (bw->type == BW_END) {
00310 int len = strlen(bw->word);
00311
00312 if ((BSCaseSensitive
00313 &&
00314 (!strncmp
00315 (nbuf + strlen(nbuf) - len, bw->word, len)))
00316 || (!BSCaseSensitive
00317 &&
00318 (!strnicmp
00319 (nbuf + strlen(nbuf) - len, bw->word,
00320 len)))) {
00321 mustkick = 1;
00322 } else {
00323 char *wordbuf = scalloc(len + 2, 1);
00324
00325 memcpy(wordbuf, bw->word, len);
00326 wordbuf[len] = ' ';
00327 wordbuf[len + 1] = '\0';
00328
00329 if ((BSCaseSensitive && (strstr(nbuf, wordbuf)))
00330 || (!BSCaseSensitive
00331 && (stristr(nbuf, wordbuf))))
00332 mustkick = 1;
00333
00334 free(wordbuf);
00335 }
00336 }
00337
00338 if (mustkick) {
00339 check_ban(ci, u, TTB_BADWORDS);
00340 if (BSGentleBWReason)
00341 bot_kick(ci, u, BOT_REASON_BADWORD_GENTLE);
00342 else
00343 bot_kick(ci, u, BOT_REASON_BADWORD, bw->word);
00344 return;
00345 }
00346 }
00347
00348
00349 if (nbuf)
00350 free(nbuf);
00351 }
00352
00353
00354 if (ci->botflags & BS_KICK_FLOOD) {
00355 time_t now = time(NULL);
00356
00357 ud = get_user_data(ci->c, u);
00358 if (!ud) {
00359 return;
00360 }
00361
00362 if (now - ud->last_start > ci->floodsecs) {
00363 ud->last_start = time(NULL);
00364 ud->lines = 0;
00365 }
00366
00367 ud->lines++;
00368 if (ud->lines >= ci->floodlines) {
00369 check_ban(ci, u, TTB_FLOOD);
00370 bot_kick(ci, u, BOT_REASON_FLOOD);
00371 return;
00372 }
00373 }
00374
00375
00376 if (ci->botflags & BS_KICK_REPEAT) {
00377 ud = get_user_data(ci->c, u);
00378 if (!ud) {
00379 return;
00380 }
00381 if (ud->lastline && stricmp(ud->lastline, buf)) {
00382 free(ud->lastline);
00383 ud->lastline = sstrdup(buf);
00384 ud->times = 0;
00385 } else {
00386 if (!ud->lastline)
00387 ud->lastline = sstrdup(buf);
00388 ud->times++;
00389 }
00390
00391 if (ud->times >= ci->repeattimes) {
00392 check_ban(ci, u, TTB_REPEAT);
00393 bot_kick(ci, u, BOT_REASON_REPEAT);
00394 return;
00395 }
00396 }
00397 }
00398
00399
00400
00401 if (get_ignore(u->nick) != NULL) {
00402 return;
00403 }
00404
00405
00406
00407 if (buf && (ci->botflags & BS_FANTASY) && *buf == *BSFantasyCharacter) {
00408 cmd = strtok(buf, " ");
00409
00410 if (cmd && (cmd[0] == *BSFantasyCharacter)) {
00411 char *params = strtok(NULL, "");
00412 char *event_name = EVENT_BOT_FANTASY_NO_ACCESS;
00413
00414
00415 cmd++;
00416
00417 if (check_access(u, ci, CA_FANTASIA))
00418 event_name = EVENT_BOT_FANTASY;
00419
00420 if (params)
00421 send_event(event_name, 4, cmd, u->nick, ci->name, params);
00422 else
00423 send_event(event_name, 3, cmd, u->nick, ci->name);
00424 }
00425 }
00426 }
00427
00428
00429
00430
00431
00432
00433 #define SAFE(x) do { \
00434 if ((x) < 0) { \
00435 if (!forceload) \
00436 fatal("Read error on %s", BotDBName); \
00437 failed = 1; \
00438 break; \
00439 } \
00440 } while (0)
00441
00442 void load_bs_dbase(void)
00443 {
00444 dbFILE *f;
00445 int c, ver;
00446 uint16 tmp16;
00447 uint32 tmp32;
00448 BotInfo *bi;
00449 int failed = 0;
00450
00451 if (!(f = open_db(s_BotServ, BotDBName, "r", BOT_VERSION)))
00452 return;
00453
00454 ver = get_file_version(f);
00455
00456 while (!failed && (c = getc_db(f)) != 0) {
00457 char *s;
00458
00459 if (c != 1)
00460 fatal("Invalid format in %s %d", BotDBName, c);
00461
00462 SAFE(read_string(&s, f));
00463 bi = makebot(s);
00464 free(s);
00465 SAFE(read_string(&bi->user, f));
00466 SAFE(read_string(&bi->host, f));
00467 SAFE(read_string(&bi->real, f));
00468 if (ver >= 10) {
00469 SAFE(read_int16(&tmp16, f));
00470 bi->flags = tmp16;
00471 }
00472 SAFE(read_int32(&tmp32, f));
00473 bi->created = tmp32;
00474 SAFE(read_int16(&tmp16, f));
00475 bi->chancount = tmp16;
00476 }
00477
00478 close_db(f);
00479 }
00480
00481 #undef SAFE
00482
00483
00484
00485 #define SAFE(x) do { \
00486 if ((x) < 0) { \
00487 restore_db(f); \
00488 log_perror("Write error on %s", BotDBName); \
00489 if (time(NULL) - lastwarn > WarningTimeout) { \
00490 anope_cmd_global(NULL, "Write error on %s: %s", BotDBName, \
00491 strerror(errno)); \
00492 lastwarn = time(NULL); \
00493 } \
00494 return; \
00495 } \
00496 } while (0)
00497
00498 void save_bs_dbase(void)
00499 {
00500 dbFILE *f;
00501 BotInfo *bi;
00502 static time_t lastwarn = 0;
00503 int i;
00504
00505 if (!(f = open_db(s_BotServ, BotDBName, "w", BOT_VERSION)))
00506 return;
00507
00508 for (i = 0; i < 256; i++) {
00509 for (bi = botlists[i]; bi; bi = bi->next) {
00510 SAFE(write_int8(1, f));
00511 SAFE(write_string(bi->nick, f));
00512 SAFE(write_string(bi->user, f));
00513 SAFE(write_string(bi->host, f));
00514 SAFE(write_string(bi->real, f));
00515 SAFE(write_int16(bi->flags, f));
00516 SAFE(write_int32(bi->created, f));
00517 SAFE(write_int16(bi->chancount, f));
00518 }
00519 }
00520 SAFE(write_int8(0, f));
00521
00522 close_db(f);
00523
00524 }
00525
00526 #undef SAFE
00527
00528
00529
00530 void save_bs_rdb_dbase(void)
00531 {
00532 #ifdef USE_RDB
00533 int i;
00534 BotInfo *bi;
00535
00536 if (!rdb_open())
00537 return;
00538
00539 if (rdb_tag_table("anope_bs_core") == 0) {
00540 alog("Unable to tag table 'anope_bs_core' - BotServ RDB save failed.");
00541 return;
00542 }
00543
00544 for (i = 0; i < 256; i++) {
00545 for (bi = botlists[i]; bi; bi = bi->next) {
00546 if (rdb_save_bs_core(bi) == 0) {
00547 alog("Unable to save BotInfo for %s - BotServ RDB save failed.", bi->nick);
00548 return;
00549 }
00550 }
00551 }
00552
00553 if (rdb_clean_table("anope_bs_core") == 0) {
00554 alog("Unable to clean table 'anope_bs_core' - BotServ RDB save failed.");
00555 return;
00556 }
00557
00558 rdb_close();
00559 #endif
00560 }
00561
00562
00563
00564
00565
00566 void insert_bot(BotInfo * bi)
00567 {
00568 BotInfo *ptr, *prev;
00569
00570 for (prev = NULL, ptr = botlists[tolower(*bi->nick)];
00571 ptr != NULL && stricmp(ptr->nick, bi->nick) < 0;
00572 prev = ptr, ptr = ptr->next);
00573 bi->prev = prev;
00574 bi->next = ptr;
00575 if (!prev)
00576 botlists[tolower(*bi->nick)] = bi;
00577 else
00578 prev->next = bi;
00579 if (ptr)
00580 ptr->prev = bi;
00581 }
00582
00583
00584
00585 BotInfo *makebot(char *nick)
00586 {
00587 BotInfo *bi;
00588
00589 if (!nick) {
00590 if (debug) {
00591 alog("debug: makebot called with NULL values");
00592 }
00593 return NULL;
00594 }
00595
00596 bi = scalloc(sizeof(BotInfo), 1);
00597 bi->nick = sstrdup(nick);
00598 bi->lastmsg = time(NULL);
00599 insert_bot(bi);
00600 nbots++;
00601 return bi;
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 BotInfo *findbot(char *nick)
00613 {
00614 BotInfo *bi;
00615 Uid *ud;
00616
00617
00618 ud = NULL;
00619
00620 if (!nick || !*nick)
00621 return NULL;
00622
00623 for (bi = botlists[tolower(*nick)]; bi; bi = bi->next) {
00624 if (UseTS6 && ircd->ts6) {
00625 ud = find_nickuid(nick);
00626 }
00627 if (!stricmp(nick, bi->nick)) {
00628 return bi;
00629 }
00630 if (ud && UseTS6 && ircd->ts6) {
00631 if (!stricmp(ud->nick, bi->nick)) {
00632 return bi;
00633 }
00634 }
00635 }
00636
00637 return NULL;
00638 }
00639
00640
00641
00642
00643
00644 void unassign(User * u, ChannelInfo * ci)
00645 {
00646 send_event(EVENT_BOT_UNASSIGN, 2, ci->name, ci->bi->nick);
00647
00648 if (ci->c && ci->c->usercount >= BSMinUsers) {
00649 anope_cmd_part(ci->bi->nick, ci->name, "UNASSIGN from %s",
00650 u->nick);
00651 }
00652 ci->bi->chancount--;
00653 ci->bi = NULL;
00654 }
00655
00656
00657
00658
00659
00660
00661 static BanData *get_ban_data(Channel * c, User * u)
00662 {
00663 char mask[BUFSIZE];
00664 BanData *bd, *next;
00665 time_t now = time(NULL);
00666
00667 if (!c || !u)
00668 return NULL;
00669
00670 snprintf(mask, sizeof(mask), "%s@%s", u->username,
00671 common_get_vhost(u));
00672
00673 for (bd = c->bd; bd; bd = next) {
00674 if (now - bd->last_use > BSKeepData) {
00675 if (bd->next)
00676 bd->next->prev = bd->prev;
00677 if (bd->prev)
00678 bd->prev->next = bd->next;
00679 else
00680 c->bd = bd->next;
00681 if (bd->mask)
00682 free(bd->mask);
00683 next = bd->next;
00684 free(bd);
00685 continue;
00686 }
00687 if (!stricmp(bd->mask, mask)) {
00688 bd->last_use = now;
00689 return bd;
00690 }
00691 next = bd->next;
00692 }
00693
00694
00695 bd = scalloc(sizeof(BanData), 1);
00696 bd->mask = sstrdup(mask);
00697 bd->last_use = now;
00698
00699 bd->prev = NULL;
00700 bd->next = c->bd;
00701 if (bd->next)
00702 bd->next->prev = bd;
00703 c->bd = bd;
00704
00705 return bd;
00706 }
00707
00708
00709
00710
00711
00712
00713
00714 static UserData *get_user_data(Channel * c, User * u)
00715 {
00716 struct c_userlist *user;
00717
00718 if (!c || !u)
00719 return NULL;
00720
00721 for (user = c->users; user; user = user->next) {
00722 if (user->user == u) {
00723 if (user->ud) {
00724 time_t now = time(NULL);
00725
00726
00727 if (now - user->ud->last_use > BSKeepData) {
00728 if (user->ud->lastline)
00729 free(user->ud->lastline);
00730
00731
00732 memset(user->ud, 0, sizeof(UserData));
00733 user->ud->last_use = now;
00734 }
00735
00736 return user->ud;
00737 } else {
00738 user->ud = scalloc(sizeof(UserData), 1);
00739 user->ud->last_use = time(NULL);
00740 return user->ud;
00741 }
00742 }
00743 }
00744
00745 return NULL;
00746 }
00747
00748
00749
00750
00751
00752 void bot_join(ChannelInfo * ci)
00753 {
00754 int i;
00755
00756 if (!ci || !ci->c || !ci->bi)
00757 return;
00758
00759 if (BSSmartJoin) {
00760
00761 int count = ci->c->bancount;
00762 if (count) {
00763 char botmask[BUFSIZE];
00764 char **bans = scalloc(sizeof(char *) * count, 1);
00765 char *av[3];
00766
00767 memcpy(bans, ci->c->bans, sizeof(char *) * count);
00768 snprintf(botmask, sizeof(botmask), "%s!%s@%s", ci->bi->nick,
00769 ci->bi->user, ci->bi->host);
00770
00771 av[0] = ci->c->name;
00772 av[1] = sstrdup("-b");
00773 for (i = 0; i < count; i++) {
00774 if (match_wild_nocase(ci->c->bans[i], botmask)) {
00775 anope_cmd_mode(ci->bi->nick, ci->name, "-b %s",
00776 bans[i]);
00777 av[2] = sstrdup(bans[i]);
00778 do_cmode(ci->bi->nick, 3, av);
00779 free(av[2]);
00780 }
00781 }
00782 free(av[1]);
00783 free(bans);
00784 }
00785
00786
00787 if ((ci->c->mode & anope_get_invite_mode())
00788 || (ci->c->limit && ci->c->usercount >= ci->c->limit))
00789 anope_cmd_notice_ops(NULL, ci->c->name,
00790 "%s invited %s into the channel.",
00791 ci->bi->nick, ci->bi->nick);
00792 }
00793 anope_cmd_join(ci->bi->nick, ci->c->name, ci->c->creation_time);
00794 anope_cmd_bot_chan_mode(ci->bi->nick, ci->c->name);
00795 send_event(EVENT_BOT_JOIN, 2, ci->name, ci->bi->nick);
00796 }
00797
00798
00799
00800
00801
00802
00803
00804 void bot_rejoin_all(BotInfo * bi)
00805 {
00806 int i;
00807 ChannelInfo *ci;
00808
00809 for (i = 0; i < 256; i++)
00810 for (ci = chanlists[i]; ci; ci = ci->next)
00811 if (ci->bi == bi && ci->c && (ci->c->usercount >= BSMinUsers))
00812 bot_join(ci);
00813 }
00814
00815
00816
00817
00818
00819
00820 static void check_ban(ChannelInfo * ci, User * u, int ttbtype)
00821 {
00822 BanData *bd = get_ban_data(ci->c, u);
00823
00824 if (!bd)
00825 return;
00826
00827 bd->ttb[ttbtype]++;
00828 if (bd->ttb[ttbtype] == ci->ttb[ttbtype]) {
00829 char *av[3];
00830 char mask[BUFSIZE];
00831
00832 bd->ttb[ttbtype] = 0;
00833
00834 av[0] = ci->name;
00835 av[1] = sstrdup("+b");
00836 get_idealban(ci, u, mask, sizeof(mask));
00837 av[2] = mask;
00838 anope_cmd_mode(ci->bi->nick, av[0], "+b %s", av[2]);
00839 do_cmode(ci->bi->nick, 3, av);
00840 send_event(EVENT_BOT_BAN, 3, u->nick, ci->name, mask);
00841 free(av[1]);
00842 }
00843 }
00844
00845
00846
00847
00848
00849 static void bot_kick(ChannelInfo * ci, User * u, int message, ...)
00850 {
00851 va_list args;
00852 char buf[1024];
00853 const char *fmt;
00854 char *av[3];
00855
00856 if (!ci || !ci->bi || !ci->c || !u)
00857 return;
00858
00859 va_start(args, message);
00860 fmt = getstring(u->na, message);
00861 if (!fmt)
00862 return;
00863 vsnprintf(buf, sizeof(buf), fmt, args);
00864 va_end(args);
00865
00866 av[0] = ci->name;
00867 av[1] = u->nick;
00868 av[2] = buf;
00869 anope_cmd_kick(ci->bi->nick, av[0], av[1], "%s", av[2]);
00870 do_kick(ci->bi->nick, 3, av);
00871 send_event(EVENT_BOT_KICK, 3, u->nick, ci->name, buf);
00872 }
00873
00874
00875
00876
00877
00878 void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick,
00879 char *reason)
00880 {
00881 int ac;
00882 char *av[4];
00883 char mask[BUFSIZE];
00884 char buf[BUFSIZE];
00885 User *u = finduser(nick);
00886
00887 if (!u)
00888 return;
00889
00890 if (ircd->protectedumode) {
00891 if (is_protected(u) && (requester != u)) {
00892 anope_cmd_privmsg(ci->bi->nick, ci->name, "%s",
00893 getstring2(NULL, PERMISSION_DENIED));
00894 return;
00895 }
00896 }
00897
00898 if ((ci->flags & CI_PEACE) && stricmp(requester->nick, nick)
00899 && (get_access(u, ci) >= get_access(requester, ci)))
00900 return;
00901
00902 if (ircd->except) {
00903 if (is_excepted(ci, u) == 1) {
00904 anope_cmd_privmsg(ci->bi->nick, ci->name, "%s",
00905 getstring2(NULL, BOT_EXCEPT));
00906 return;
00907 }
00908 }
00909
00910 get_idealban(ci, u, mask, sizeof(mask));
00911
00912 if (ircdcap->tsmode) {
00913 snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
00914 av[0] = ci->name;
00915 av[1] = buf;
00916 av[2] = sstrdup("+b");
00917 av[3] = mask;
00918 ac = 4;
00919 } else {
00920 av[0] = ci->name;
00921 av[1] = sstrdup("+b");
00922 av[2] = mask;
00923 ac = 3;
00924 }
00925
00926 anope_cmd_mode(ci->bi->nick, ci->name, "+b %s", mask);
00927 do_cmode(ci->bi->nick, ac, av);
00928
00929
00930 if (ircdcap->tsmode)
00931 free(av[2]);
00932 else
00933 free(av[1]);
00934
00935 av[0] = ci->name;
00936 av[1] = nick;
00937
00938 if (!reason) {
00939 av[2] = ci->bi->nick;
00940 } else {
00941 if (strlen(reason) > 200)
00942 reason[200] = '\0';
00943 av[2] = reason;
00944 }
00945
00946
00947 if ((ci->flags & CI_SIGNKICK)
00948 || ((ci->flags & CI_SIGNKICK_LEVEL)
00949 && !check_access(requester, ci, CA_SIGNKICK)))
00950 anope_cmd_kick(ci->bi->nick, av[0], av[1], "%s (%s)", av[2],
00951 requester->nick);
00952 else
00953 anope_cmd_kick(ci->bi->nick, av[0], av[1], "%s", av[2]);
00954
00955 do_kick(ci->bi->nick, 3, av);
00956 }
00957
00958
00959
00960
00961
00962 void bot_raw_kick(User * requester, ChannelInfo * ci, char *nick,
00963 char *reason)
00964 {
00965 char *av[3];
00966 User *u = finduser(nick);
00967
00968 if (!u || !is_on_chan(ci->c, u))
00969 return;
00970
00971 if (ircd->protectedumode) {
00972 if (is_protected(u) && (requester != u)) {
00973 anope_cmd_privmsg(ci->bi->nick, ci->name, "%s",
00974 getstring2(NULL, PERMISSION_DENIED));
00975 return;
00976 }
00977 }
00978
00979 if ((ci->flags & CI_PEACE) && stricmp(requester->nick, nick)
00980 && (get_access(u, ci) >= get_access(requester, ci)))
00981 return;
00982
00983 av[0] = ci->name;
00984 av[1] = nick;
00985
00986 if (!reason) {
00987 av[2] = ci->bi->nick;
00988 } else {
00989 if (strlen(reason) > 200)
00990 reason[200] = '\0';
00991 av[2] = reason;
00992 }
00993
00994 if ((ci->flags & CI_SIGNKICK)
00995 || ((ci->flags & CI_SIGNKICK_LEVEL)
00996 && !check_access(requester, ci, CA_SIGNKICK)))
00997 anope_cmd_kick(ci->bi->nick, av[0], av[1], "%s (%s)", av[2],
00998 requester->nick);
00999 else
01000 anope_cmd_kick(ci->bi->nick, av[0], av[1], "%s", av[2]);
01001 do_kick(ci->bi->nick, 3, av);
01002 }
01003
01004
01005
01006
01007
01008 void bot_raw_mode(User * requester, ChannelInfo * ci, char *mode,
01009 char *nick)
01010 {
01011 char *av[4];
01012 int ac;
01013 char buf[BUFSIZE];
01014 User *u;
01015
01016 *buf = '\0';
01017 u = finduser(nick);
01018
01019 if (!u || !is_on_chan(ci->c, u))
01020 return;
01021
01022 snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
01023
01024 if (ircd->protectedumode) {
01025 if (is_protected(u) && *mode == '-' && (requester != u)) {
01026 anope_cmd_privmsg(ci->bi->nick, ci->name, "%s",
01027 getstring2(NULL, PERMISSION_DENIED));
01028 return;
01029 }
01030 }
01031
01032 if (*mode == '-' && (ci->flags & CI_PEACE)
01033 && stricmp(requester->nick, nick)
01034 && (get_access(u, ci) >= get_access(requester, ci)))
01035 return;
01036
01037 if (ircdcap->tsmode) {
01038 av[0] = ci->name;
01039 av[1] = buf;
01040 av[2] = mode;
01041 av[3] = nick;
01042 ac = 4;
01043 anope_cmd_mode(ci->bi->nick, av[0], "%s %s", av[2], av[3]);
01044 } else {
01045 av[0] = ci->name;
01046 av[1] = mode;
01047 av[2] = nick;
01048 ac = 3;
01049 anope_cmd_mode(ci->bi->nick, av[0], "%s %s", av[1], av[2]);
01050 }
01051
01052 do_cmode(ci->bi->nick, ac, av);
01053 }
01054
01055
01061 char *normalizeBuffer(char *buf)
01062 {
01063 char *newbuf;
01064 int i, len, j = 0;
01065
01066 len = strlen(buf);
01067 newbuf = (char *) smalloc(sizeof(char) * len + 1);
01068
01069 for (i = 0; i < len; i++) {
01070 switch (buf[i]) {
01071
01072 case 1:
01073 break;
01074
01075 case 2:
01076 break;
01077
01078 case 3:
01079
01080 if (isdigit(buf[i + 1])) {
01081 i++;
01082
01083
01084
01085
01086
01087 if (isdigit(buf[i + 1])) {
01088 i++;
01089 }
01090
01091
01092
01093
01094 if (buf[i + 1] == ',') {