static void zapf_assoc(char *botnick, char *code, char *par) { int idx = nextbot(botnick); char *s, *s1, *nick; int linking = 0, chan; if ((idx >= 0) && !(bot_flags(dcc[idx].user) & BOT_ISOLATE)) { if (!egg_strcasecmp(dcc[idx].nick, botnick)) linking = b_status(idx) & STAT_LINKING; s = newsplit(&par); chan = base64_to_int(s); if ((chan > 0) || (chan < GLOBAL_CHANS)) { nick = newsplit(&par); s1 = get_assoc_name(chan); if (linking && ((s1 == NULL) || (s1[0] == 0) || (((intptr_t) get_user(find_entry_type("BOTFL"), dcc[idx].user) & BOT_HUB)))) { add_assoc(par, chan); botnet_send_assoc(idx, chan, nick, par); chanout_but(-1, chan, ASSOC_CHNAME_NAMED, nick, par); } else if (par[0] == '0') { kill_assoc(chan); chanout_but(-1, chan, ASSOC_CHNAME_REM, botnick, nick); } else if (get_assoc(par) != chan) { /* New one i didn't know about -- pass it on */ s1 = get_assoc_name(chan); add_assoc(par, chan); chanout_but(-1, chan, ASSOC_CHNAME_NAMED2, botnick, nick, par); } } } }
/* away <bot> <sock> <message> * null message = unaway */ static void bot_away(int idx, char *par) { char *bot = NULL, *etc = NULL; int sock, partyidx, linking = 0; bot = newsplit(&par); if (bot[0] == '!') { linking = 1; bot++; } if (b_status(idx) & STAT_LINKING) { linking = 1; } etc = newsplit(&par); sock = base64_to_int(etc); if (par[0]) { partystat(bot, sock, PLSTAT_AWAY, 0); partyaway(bot, sock, par); } else { partystat(bot, sock, 0, PLSTAT_AWAY); } partyidx = getparty(bot, sock); if (!linking) { if (par[0]) chanout_but(-1, party[partyidx].chan, "*** (%s) %s %s: %s.\n", conf.bot->hub ? bot : "[botnet]", party[partyidx].nick, "is now away", par); else chanout_but(-1, party[partyidx].chan, "*** (%s) %s %s.\n", conf.bot->hub ? bot : "[botnet]", party[partyidx].nick, "is no longer away"); } botnet_send_away(idx, bot, sock, par, linking); }
/* join <bot> <nick> <chan> <flag><sock> <from> */ static void bot_join(int idx, char *par) { char *bot = NULL, *nick = NULL, *x = NULL, *y = NULL; struct userrec *u = NULL; int i, sock, chan, i2, linking = 0; bot = newsplit(&par); if (bot[0] == '!') { linking = 1; bot++; } if (b_status(idx) & STAT_LINKING) { linking = 1; } nick = newsplit(&par); x = newsplit(&par); chan = base64_to_int(x); y = newsplit(&par); if ((chan < 0) || !y[0]) return; /* Woops! pre 1.2.1's send .chat off'ers * too!! */ if (!y[0]) { y[0] = '-'; sock = 0; } else { sock = base64_to_int(y + 1); } i = nextbot(bot); if (i != idx) { /* Ok, garbage from a 1.0g (who uses that * now?) OR raistlin being evil :) */ fake_alert(idx, "direction", bot, "join"); return; } u = get_user_by_handle(userlist, nick); if (u) { simple_snprintf(TBUF, sizeof(TBUF), "@%s", bot); touch_laston(u, TBUF, now); } i = addparty(bot, nick, chan, y[0], sock, par, &i2); botnet_send_join_party(idx, linking, i2); if (i != chan) { if (i >= 0) { chanout_but(-1, i, "*** (%s) %s %s %s.\n", conf.bot->hub ? bot : "[botnet]", nick, "has left the", i ? "channel" : "party line"); } if (!linking) chanout_but(-1, chan, "*** (%s) %s %s %s.\n", conf.bot->hub ? bot : "[botnet]", nick, "has joined the", chan ? "channel" : "party line"); } }
/* 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; }