static void bot_unlinked(int idx, char *par) { int i; char *bot = NULL; bot = newsplit(&par); i = nextbot(bot); if ((i >= 0) && (i != idx)) /* Bot is NOT downstream along idx, so * BOGUS! */ fake_alert(idx, "direction", bot, "unlinked"); else if (i >= 0) { /* Valid bot downstream of idx */ if (par[0]) /* #ifdef HUB */ chatout("*** (%s) %s\n", lastbot(bot), par); /* #else chatout("*** %s unlinked from botnet.\n", par); #endif */ botnet_send_unlinked(idx, bot, par); unvia(idx, findbot(bot)); rembot(bot); } /* Otherwise it's not even a valid bot, so just ignore! */ }
/* remove every bot linked 'via' bot <x> */ void unvia(int idx, tand_t * who) { tand_t *bot, *bot2; if (!who) return; /* safety */ rempartybot(who->bot); bot = tandbot; while (bot) { if (bot->uplink == who) { unvia(idx, bot); bot2 = bot->next; rembot(bot->bot); bot = bot2; } else bot = bot->next; } #ifndef NO_OLD_BOTNET /* every bot unvia's bots behind anyway, so why send msg's for * EVERY one? - will this break things?! */ tandout_but(idx, "unlinked %s\n", who->bot); #endif }
/* break link with a tandembot */ int botunlink(int idx, char *nick, char *reason) { char s[20]; register int i; tand_t *bot; Context; if (nick[0] == '*') dprintf(idx, "%s\n", BOT_UNLINKALL); for (i = 0; i < dcc_total; i++) { if ((nick[0] == '*') || !strcasecmp(dcc[i].nick, nick)) { if (dcc[i].type == &DCC_FORK_BOT) { if (idx >= 0) dprintf(idx, "%s: %s -> %s.\n", BOT_KILLLINKATTEMPT, dcc[i].nick, dcc[i].host); putlog(LOG_BOTS, "*", "%s: %s -> %s:%d", BOT_KILLLINKATTEMPT, dcc[i].nick, dcc[i].host, dcc[i].port); killsock(dcc[i].sock); lostdcc(i); if (nick[0] != '*') return 1; } else if (dcc[i].type == &DCC_BOT_NEW) { if (idx >= 0) dprintf(idx, "%s %s.\n", BOT_ENDLINKATTEMPT, dcc[i].nick); putlog(LOG_BOTS, "*", "%s %s @ %s:%d", "Stopped trying to link", dcc[i].nick, dcc[i].host, dcc[i].port); killsock(dcc[i].sock); lostdcc(i); if (nick[0] != '*') return 1; else i--; } else if (dcc[i].type == &DCC_BOT) { char s[1024]; Context; if (idx >= 0) dprintf(idx, "%s %s.\n", BOT_BREAKLINK, dcc[i].nick); else if ((idx == -3) && (b_status(i) & STAT_SHARE) && !share_unlinks) return -1; dprintf(i, "bye\n"); if (reason && reason[0]) { simple_sprintf(s, "%s %s (%s)", BOT_UNLINKEDFROM, dcc[i].nick, reason); } else { simple_sprintf(s, "%s %s", BOT_UNLINKEDFROM, dcc[i].nick); } chatout("*** %s\n", s); botnet_send_unlinked(i, dcc[i].nick, s); killsock(dcc[i].sock); lostdcc(i); if (nick[0] != '*') return 1; else i--; } } } Context; if ((idx >= 0) && (nick[0] != '*')) { dprintf(idx, "%s\n", BOT_NOTCONNECTED); /* The internal bot list is desynched from the dcc list * sometimes. While we still search for the bug, provide * an easy way to clear out those `ghost'-bots. -FK */ bot = findbot(nick); if (bot) { dprintf(idx, "BUG: Found bot `%s' in internal bot list! Removing.\n", nick); rembot(bot->bot); } } if (nick[0] == '*') { dprintf(idx, "%s\n", BOT_WIPEBOTTABLE); while (tandbot) rembot(tandbot->bot); while (parties) { parties--; /* Assert? */ if (party[i].chan >= 0) check_tcl_chpt(party[i].bot, party[i].nick, party[i].sock, party[i].chan); } strcpy(s, "killassoc &"); Tcl_Eval(interp, s); } return 0; }