/* nc <bot> <sock> <newnick> */ static void bot_nickchange(int idx, char *par) { char *bot, *ssock, *newnick; int sock, i; if (bot_flags(dcc[idx].user) & BOT_ISOLATE) return; bot = newsplit(&par); #ifndef NO_OLD_BOTNET if (dcc[idx].u.bot->numver < NEAT_BOTNET) { fake_alert(idx, "botversion", "NEAT_BOTNET"); return; } #endif i = nextbot(bot); if (i != idx) { fake_alert(idx, "direction", bot); return; } ssock = newsplit(&par); sock = base64_to_int(ssock); newnick = newsplit(&par); i = partynick(bot, sock, newnick); if (i < 0) { fake_alert(idx, "sock#", ssock); return; } chanout_but(-1, party[i].chan, "*** (%s) Nick change: %s -> %s\n", bot, newnick, party[i].nick); botnet_send_nkch_part(idx, i, newnick); }
/* chan <from> <chan> <text> */ static void bot_chan2(int idx, char *msg) { char *from, *p; int i, chan; if (bot_flags(dcc[idx].user) & BOT_ISOLATE) return; from = newsplit(&msg); p = newsplit(&msg); #ifndef NO_OLD_BOTNET if (dcc[idx].u.bot->numver < NEAT_BOTNET) chan = atoi(p); else #endif chan = base64_to_int(p); /* Strip annoying control chars */ for (p = from; *p;) { if ((*p < 32) || (*p == 127)) strcpy(p, p + 1); else p++; } p = strchr(from, '@'); if (p) { sprintf(TBUF, "<%s> %s", from, msg); *p = 0; if (!partyidle(p + 1, from)) { *p = '@'; fake_alert(idx, "user", from); return; } *p = '@'; p++; } else { sprintf(TBUF, "*** (%s) %s", from, msg); p = from; } i = nextbot(p); if (i != idx) { fake_alert(idx, "direction", p); } else { chanout_but(-1, chan, "%s\n", TBUF); /* Send to new version bots */ if (i >= 0) botnet_send_chan(idx, from, NULL, chan, msg); if (strchr(from, '@') != NULL) check_tcl_chat(from, chan, msg); else check_tcl_bcst(from, chan, msg); } }
/* chan <from> <chan> <text> */ static void bot_chan2(int idx, char *msg) { char *from = NULL, *p = NULL; int i, chan; from = newsplit(&msg); p = newsplit(&msg); chan = base64_to_int(p); /* Strip annoying control chars */ for (p = from; *p;) { if ((*p < 32) || (*p == 127)) memmove(p, p + 1, strlen(p)); else p++; } p = strchr(from, '@'); if (p) { if (!conf.bot->hub) { /* Need to strip out the hub nick */ char *q = NULL, newfrom[HANDLEN + 9 + 1]; /* HANDLEN@[botnet] */ strlcpy(newfrom, from, sizeof(newfrom)); q = strchr(newfrom, '@'); *q = 0; simple_snprintf(TBUF, sizeof(TBUF), "<%s@[botnet]> %s", newfrom, msg); } else simple_snprintf(TBUF, sizeof(TBUF), "<%s> %s", from, msg); *p = 0; if (!partyidle(p + 1, from)) { *p = '@'; fake_alert(idx, "user", from, "chan2_i"); return; } *p = '@'; p++; } else { simple_snprintf(TBUF, sizeof(TBUF), "*** (%s) %s", from, msg); p = from; } i = nextbot(p); if (i != idx) { fake_alert(idx, "direction", p, "chan2_ii"); } else { chanout_but(-1, chan, "%s\n", TBUF); /* Send to new version bots */ if (i >= 0) botnet_send_chan(idx, from, NULL, chan, msg); } }
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! */ }
/* Used to send a direct msg from Tcl on one bot to Tcl on another * zapf <frombot> <tobot> <code [param]> */ static void bot_zapf(int idx, char *par) { char *from = NULL, *to = NULL; int i; from = newsplit(&par); to = newsplit(&par); i = nextbot(from); if (i != idx) { fake_alert(idx, "direction", from, "zapf"); return; } if (!strcasecmp(to, conf.bot->nick)) { /* For me! */ char *opcode; opcode = newsplit(&par); check_bind_bot(from, opcode, par); return; } else { i = nextbot(to); if (i >= 0) botnet_send_zapf(i, from, to, par); } }
void bot_remotereply(int idx, char *par) { char *tbot = NULL, *fbot = NULL, *fhnd = NULL, *fidx = NULL; if (par[0]) tbot = newsplit(&par); if (par[0]) fbot = newsplit(&par); if (par[0]) fhnd = newsplit(&par); if (par[0]) fidx = newsplit(&par); /* Make sure the bot is valid */ int i = nextbot(fbot); if (i != idx) { fake_alert(idx, "direction", fbot, "rr"); return; } if (!strcasecmp(tbot, conf.bot->nick)) { gotremotereply(fbot, fhnd, fidx, par); } else { if (nextbot(tbot)!= idx) botnet_send_cmdreply(fbot, tbot, fhnd, fidx, par); } }
/* actchan <from> <chan> <text> */ static void bot_actchan(int idx, char *par) { char *from = NULL, *p = NULL; int i, chan; from = newsplit(&par); p = strchr(from, '@'); if (p == NULL) { /* How can a bot do an action? */ fake_alert(idx, "user@bot", from, "actchan_i"); return; } *p = 0; if (!partyidle(p + 1, from)) { *p = '@'; fake_alert(idx, "user", from, "actchan_ii"); return; } *p = '@'; p++; i = nextbot(p); if (i != idx) { fake_alert(idx, "direction", p, "actchan_iii"); return; } p = newsplit(&par); chan = base64_to_int(p); for (p = from; *p;) { if ((*p < 32) || (*p == 127)) memmove(p, p + 1, strlen(p)); else p++; } if (!conf.bot->hub) { /* Need to strip out the hub nick */ char *q = NULL, newfrom[HANDLEN + 9 + 1]; /* HANDLEN@[botnet] */ strlcpy(newfrom, from, sizeof(newfrom)); q = strchr(newfrom, '@'); *q = 0; chanout_but(-1, chan, "* %s@[botnet] %s\n", newfrom, par); } else chanout_but(-1, chan, "* %s %s\n", from, par); botnet_send_act(idx, from, NULL, chan, par); }
/* actchan <from> <chan> <text> */ static void bot_actchan(int idx, char *par) { char *from, *p; int i, chan; if (bot_flags(dcc[idx].user) & BOT_ISOLATE) return; from = newsplit(&par); p = strchr(from, '@'); if (p == NULL) { /* How can a bot do an action? */ fake_alert(idx, "user@bot", from); return; } *p = 0; if (!partyidle(p + 1, from)) { *p = '@'; fake_alert(idx, "user", from); return; } *p = '@'; p++; i = nextbot(p); if (i != idx) { fake_alert(idx, "direction", p); return; } p = newsplit(&par); #ifndef NO_OLD_BOTNET if (dcc[idx].u.bot->numver < NEAT_BOTNET) chan = atoi(p); else #endif chan = base64_to_int(p); for (p = from; *p;) { if ((*p < 32) || (*p == 127)) strcpy(p, p + 1); else p++; } chanout_but(-1, chan, "* %s %s\n", from, par); botnet_send_act(idx, from, NULL, chan, par); check_tcl_act(from, chan, par); }
/* this is only sent to hub bots */ static void bot_chat(int idx, char *par) { char *from = NULL; int i; from = newsplit(&par); if (strchr(from, '@') != NULL) { fake_alert(idx, "bot", from, "chat_i"); return; } /* Make sure the bot is valid */ i = nextbot(from); if (i != idx) { fake_alert(idx, "direction", from, "chat_ii"); return; } chatout("*** (%s) %s\n", from, par); botnet_send_chat(idx, from, par); }
/* chat <from> <notice> -- only from bots */ static void bot_chat(int idx, char *par) { char *from; int i; if (bot_flags(dcc[idx].user) & BOT_ISOLATE) return; from = newsplit(&par); if (strchr(from, '@') != NULL) { fake_alert(idx, "bot", from); return; } /* Make sure the bot is valid */ i = nextbot(from); if (i != idx) { fake_alert(idx, "direction", from); return; } chatout("*** (%s) %s\n", from, par); botnet_send_chat(idx, from, par); check_tcl_bcst(from, -1, par); }
/* nc <bot> <sock> <newnick> */ static void bot_nickchange(int idx, char *par) { char *bot = NULL, *ssock = NULL, *newnick = NULL; int sock, i; bot = newsplit(&par); i = nextbot(bot); if (i != idx) { fake_alert(idx, "direction", bot, "nickchange_i"); return; } ssock = newsplit(&par); sock = base64_to_int(ssock); newnick = newsplit(&par); i = partynick(bot, sock, newnick); if (i < 0) { fake_alert(idx, "sock#", ssock, "nickchange_ii"); return; } chanout_but(-1, party[i].chan, "*** (%s) Nick change: %s -> %s\n", conf.bot->hub ? bot : "[botnet]", newnick, party[i].nick); botnet_send_nkch_part(idx, i, newnick); }
/* 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"); } }
/* Used to send a global msg from Tcl on one bot to every other bot * zapf-broad <frombot> <code [param]> */ static void bot_zapfbroad(int idx, char *par) { char *from = NULL, *opcode = NULL; int i; from = newsplit(&par); opcode = newsplit(&par); i = nextbot(from); if (i != idx) { fake_alert(idx, "direction", from, "zapfb"); return; } check_bind_bot(from, opcode, par); botnet_send_zapf_broad(idx, from, opcode, par); }
/* v <frombot> <tobot> <idx:nick> */ static void bot_versions(int sock, char *par) { char *frombot = newsplit(&par), *tobot = NULL, *from = NULL; if (nextbot(frombot) != sock) fake_alert(sock, "direction", frombot, "versions"); else if (strcasecmp(tobot = newsplit(&par), conf.bot->nick)) { if ((sock = nextbot(tobot)) >= 0) dprintf(sock, "v %s %s %s\n", frombot, tobot, par); } else { from = newsplit(&par); botnet_send_priv(sock, conf.bot->nick, from, frombot, "Modules loaded:\n"); /* wtf? for (me = module_list; me; me = me->next) botnet_send_priv(sock, conf.bot->nick, from, frombot, " Module: %s\n", me->name); */ botnet_send_priv(sock, conf.bot->nick, from, frombot, "End of module list.\n"); } }
/* v <frombot> <tobot> <idx:nick> */ static void bot_versions(int sock, char *par) { char *frombot = newsplit(&par), *tobot, *from; module_entry *me; if (nextbot(frombot) != sock) fake_alert(sock, "versions-direction", frombot); else if (egg_strcasecmp(tobot = newsplit(&par), botnetnick)) { if ((sock = nextbot(tobot)) >= 0) dprintf(sock, "v %s %s %s\n", frombot, tobot, par); } else { from = newsplit(&par); botnet_send_priv(sock, botnetnick, from, frombot, "Modules loaded:\n"); for (me = module_list; me; me = me->next) botnet_send_priv(sock, botnetnick, from, frombot, " Module: %s (v%d.%d)\n", me->name, me->major, me->minor); botnet_send_priv(sock, botnetnick, from, frombot, "End of module list.\n"); } }
/* priv <from> <to> <message> */ static void bot_priv(int idx, char *par) { char *from = NULL, *p = NULL, *to = TBUF, *tobot = NULL; int i; from = newsplit(&par); tobot = newsplit(&par); splitc(to, tobot, '@'); p = strchr(from, '@'); if (p != NULL) p++; else p = from; i = nextbot(p); if (i != idx) { fake_alert(idx, "direction", p, "priv_i"); return; } if (!to[0]) return; /* Silently ignore notes to '@bot' this * is legacy code */ if (!strcasecmp(tobot, conf.bot->nick)) { /* For me! */ if (p == from) add_note(to, from, par, -2, 0); else { i = add_note(to, from, par, -1, 0); if (from[0] != '@') switch (i) { case NOTE_ERROR: botnet_send_priv(idx, conf.bot->nick, from, NULL, "%s %s.", "No such user", to); break; } } } else { /* Pass it on */ i = nextbot(tobot); if (i >= 0) botnet_send_priv(i, from, to, tobot, "%s", par); } }
/* bot_log - forwards to all hubs linked directly if a hub (excluding the one who sent it) - leaf bots display and do not pass along. */ static void bot_log(int idx, char *par) { char *from = newsplit(&par); int i = nextbot(from); if (i != idx) { fake_alert(idx, "direction", from, "log"); return; } if (egg_isdigit(par[0])) { int type = atoi(newsplit(&par)); if (conf.bot->hub || conf.bot->localhub) botnet_send_log(idx, from, type, par); if (conf.bot->hub) putlog(type, "@", "(%s) %s", from, par); } else { putlog(LOG_ERRORS, "*", "Malformed HL line from %s: %s", from, par); } }
/* Used to send a direct msg from Tcl on one bot to Tcl on another * zapf <frombot> <tobot> <code [param]> */ static void bot_zapf(int idx, char *par) { char *from, *to; int i; from = newsplit(&par); to = newsplit(&par); i = nextbot(from); if (i != idx) { fake_alert(idx, "direction", from); return; } if (!egg_strcasecmp(to, botnetnick)) { /* For me! */ char *opcode; opcode = newsplit(&par); check_tcl_bot(from, opcode, par); return; } i = nextbot(to); if (i >= 0) botnet_send_zapf(i, from, to, par); }
/* reject <from> <bot> */ static void bot_reject(int idx, char *par) { char *from = NULL, *who = NULL, *destbot = NULL, *frombot = NULL; struct userrec *u = NULL; int i; from = newsplit(&par); frombot = strchr(from, '@'); if (frombot) frombot++; else frombot = from; i = nextbot(frombot); if (i != idx) { fake_alert(idx, "direction", frombot, "reject"); return; } who = newsplit(&par); if (!(destbot = strchr(who, '@'))) { /* Rejecting a bot */ i = nextbot(who); if (i < 0) { botnet_send_priv(idx, conf.bot->nick, from, NULL, "Can't unlink %s (doesn't exist)", who); } else if (!strcasecmp(dcc[i].nick, who)) { char s[1024]; /* I'm the connection to the rejected bot */ putlog(LOG_BOTS, "*", "%s rejected %s", from, dcc[i].nick); dprintf(i, "bye %s\n", par[0] ? par : "rejected"); simple_sprintf(s, "Disconnected %s (%s: %s)", dcc[i].nick, from, par[0] ? par : "rejected"); chatout("*** %s\n", s); botnet_send_unlinked(i, dcc[i].nick, s); killsock(dcc[i].sock); lostdcc(i); } else { if (i >= 0) botnet_send_reject(i, from, NULL, who, NULL, par); } } else { /* Rejecting user */ *destbot++ = 0; if (!strcasecmp(destbot, conf.bot->nick)) { /* Kick someone here! */ int ok = 0; for (i = 0; i < dcc_total; i++) { if (dcc[i].type && dcc[i].simul == -1 && !strcasecmp(who, dcc[i].nick) && (dcc[i].type->flags & DCT_CHAT)) { u = get_user_by_handle(userlist, from); if (u) { if (!whois_access(u, dcc[idx].user)) { add_note(from, conf.bot->nick, "Sorry, you cannot boot them.", -1, 0); return; } do_boot(i, from, par); putlog(LOG_CMDS, "*", "#%s# boot %s (%s)", from, who, par[0] ? par : "No reason"); ok = 1; } } } } else { i = nextbot(destbot); *--destbot = '@'; if (i >= 0) botnet_send_reject(i, from, NULL, who, NULL, par); } } }
/* priv <from> <to> <message> */ static void bot_priv(int idx, char *par) { char *from, *p, *to = TBUF, *tobot; int i; from = newsplit(&par); tobot = newsplit(&par); splitc(to, tobot, '@'); p = strchr(from, '@'); if (p != NULL) p++; else p = from; i = nextbot(p); if (i != idx) { fake_alert(idx, "direction", p); return; } if (!to[0]) return; /* Silently ignore notes to '@bot' */ if (!egg_strcasecmp(tobot, botnetnick)) { /* For me! */ if (p == from) add_note(to, from, par, -2, 0); else { i = add_note(to, from, par, -1, 0); if (from[0] != '@') switch (i) { case NOTE_ERROR: botnet_send_priv(idx, botnetnick, from, NULL, "%s %s.", BOT_NOSUCHUSER, to); break; case NOTE_STORED: botnet_send_priv(idx, botnetnick, from, NULL, "%s", BOT_NOTESTORED2); break; case NOTE_FULL: botnet_send_priv(idx, botnetnick, from, NULL, "%s", BOT_NOTEBOXFULL); break; case NOTE_AWAY: botnet_send_priv(idx, botnetnick, from, NULL, "%s %s", to, BOT_NOTEISAWAY); break; case NOTE_FWD: botnet_send_priv(idx, botnetnick, from, NULL, "%s %s", "Not online; note forwarded to:", to); break; case NOTE_REJECT: botnet_send_priv(idx, botnetnick, from, NULL, "%s %s", to, "rejected your note."); break; case NOTE_TCL: break; /* Do nothing */ case NOTE_OK: botnet_send_priv(idx, botnetnick, from, NULL, "%s %s.", BOT_NOTESENTTO, to); break; } } } else { /* Pass it on */ i = nextbot(tobot); if (i >= 0) botnet_send_priv(i, from, to, tobot, "%s", par); } }
/* reject <from> <bot> */ static void bot_reject(int idx, char *par) { char *from, *who, *destbot, *frombot; struct userrec *u; int i; if (bot_flags(dcc[idx].user) & BOT_ISOLATE) return; from = newsplit(&par); frombot = strchr(from, '@'); if (frombot) frombot++; else frombot = from; i = nextbot(frombot); if (i != idx) { fake_alert(idx, "direction", frombot); return; } who = newsplit(&par); if (!(destbot = strchr(who, '@'))) { /* Rejecting a bot */ i = nextbot(who); if (i < 0) { botnet_send_priv(idx, botnetnick, from, NULL, "%s %s (%s)", BOT_CANTUNLINK, who, BOT_DOESNTEXIST); } else if (!egg_strcasecmp(dcc[i].nick, who)) { char s[1024]; /* I'm the connection to the rejected bot */ putlog(LOG_BOTS, "*", "%s %s %s", from, MISC_REJECTED, dcc[i].nick); dprintf(i, "bye %s\n", par[0] ? par : MISC_REJECTED); simple_sprintf(s, "%s %s (%s: %s)", MISC_DISCONNECTED, dcc[i].nick, from, par[0] ? par : MISC_REJECTED); chatout("*** %s\n", s); botnet_send_unlinked(i, dcc[i].nick, s); killsock(dcc[i].sock); lostdcc(i); } else { if (i >= 0) botnet_send_reject(i, from, NULL, who, NULL, par); } } else { /* Rejecting user */ *destbot++ = 0; if (!egg_strcasecmp(destbot, botnetnick)) { /* Kick someone here! */ int ok = 0; if (remote_boots == 1) { frombot = strchr(from, '@'); if (frombot == NULL) frombot = from; else frombot++; u = get_user_by_handle(userlist, frombot); if (!(bot_flags(u) & BOT_SHARE)) { add_note(from, botnetnick, "No non sharebot boots.", -1, 0); ok = 1; } } else if (remote_boots == 0) { botnet_send_priv(idx, botnetnick, from, NULL, "%s", BOT_NOREMOTEBOOT); ok = 1; } for (i = 0; (i < dcc_total) && !ok; i++) if ((!egg_strcasecmp(who, dcc[i].nick)) && (dcc[i].type->flags & DCT_CHAT)) { u = get_user_by_handle(userlist, dcc[i].nick); if (u && (u->flags & USER_OWNER)) { add_note(from, botnetnick, BOT_NOOWNERBOOT, -1, 0); return; } do_boot(i, from, par); ok = 1; putlog(LOG_CMDS, "*", "#%s# boot %s (%s)", from, who, par[0] ? par : "No reason"); } } else { i = nextbot(destbot); *--destbot = '@'; if (i >= 0) botnet_send_reject(i, from, NULL, who, NULL, par); } } }
/* join <bot> <nick> <chan> <flag><sock> <from> */ static void bot_join(int idx, char *par) { char *bot, *nick, *x, *y; struct userrec *u; int i, sock, chan, i2, linking = 0; if (bot_flags(dcc[idx].user) & BOT_ISOLATE) return; bot = newsplit(&par); #ifndef NO_OLD_BOTNET if (dcc[idx].u.bot->numver >= NEAT_BOTNET) #endif if (bot[0] == '!') { linking = 1; bot++; } if (dcc[idx].status & BSTAT_LINKING) linking = 1; nick = newsplit(&par); x = newsplit(&par); #ifndef NO_OLD_BOTNET if (dcc[idx].u.bot->numver < NEAT_BOTNET) chan = atoi(x); else #endif 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 { #ifndef NO_OLD_BOTNET if (dcc[idx].u.bot->numver < NEAT_BOTNET) sock = atoi(y + 1); else #endif sock = base64_to_int(y + 1); } /* 1.1 bots always send a sock#, even on a channel change * so if sock# is 0, this is from an old bot and we must tread softly * grab old sock# if there is one, otherwise make up one. */ if (sock == 0) sock = partysock(bot, nick); if (sock == 0) sock = fakesock++; 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); return; } u = get_user_by_handle(userlist, nick); if (u) { sprintf(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, i); if (i != chan) { if (i >= 0) { if (dcc[idx].u.bot->numver >= NEAT_BOTNET) chanout_but(-1, i, "*** (%s) %s %s %s.\n", bot, nick, NET_LEFTTHE, i ? "channel" : "party line"); check_tcl_chpt(bot, nick, sock, i); } if ((dcc[idx].u.bot->numver >= NEAT_BOTNET) && !linking) chanout_but(-1, chan, "*** (%s) %s %s %s.\n", bot, nick, NET_JOINEDTHE, chan ? "channel" : "party line"); check_tcl_chjn(bot, nick, chan, y[0], sock, par); } }