static void rebalance_roles() { struct bot_addr *ba = NULL; int r[5] = { 0, 0, 0, 0, 0 }; unsigned int hNdx, lNdx, i; char tmp[10] = ""; for (i = 0; i < (unsigned) dcc_total; i++) { if (dcc[i].type && dcc[i].user && dcc[i].user->bot && bot_hublevel(dcc[i].user) == 999) { ba = (struct bot_addr *) get_user(&USERENTRY_BOTADDR, dcc[i].user); if (ba && (ba->roleid > 0) && (ba->roleid < 5)) r[(ba->roleid - 1)]++; } } /* Find high & low while (high-low) > 2 move from highNdx to lowNdx */ hNdx = 0; lNdx = 0; for (i = 1; i <= 4; i++) { if (r[i] < r[lNdx]) lNdx = i; if (r[i] > r[hNdx]) hNdx = i; } while (r[hNdx] - r[lNdx] >= 2) { for (i = 0; i < (unsigned) dcc_total; i++) { if (dcc[i].type && dcc[i].user && dcc[i].user->bot && bot_hublevel(dcc[i].user) == 999) { ba = (struct bot_addr *) get_user(&USERENTRY_BOTADDR, dcc[i].user); if (ba && (ba->roleid == (hNdx + 1))) { ba->roleid = lNdx + 1; simple_snprintf(tmp, sizeof(tmp), "rl %d", lNdx + 1); putbot(dcc[i].nick, tmp); } } } r[hNdx]--; r[lNdx]++; hNdx = 0; lNdx = 0; for (i = 1; i <= 4; i++) { if (r[i] < r[lNdx]) lNdx = i; if (r[i] > r[hNdx]) hNdx = i; } } }
int whois_access(struct userrec *user, struct userrec *whois_user) { if (user == whois_user) return 1; struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 }, whois = { FR_GLOBAL | FR_CHAN, 0, 0, 0}; get_user_flagrec(user, &fr, NULL); get_user_flagrec(whois_user, &whois, NULL); /* Don't show hub bots from leaf bots. */ if (!conf.bot->hub && whois_user->bot && bot_hublevel(whois_user) < 999) return 0; if ( (isowner(whois_user->handle) && !isowner(user->handle)) || (glob_admin(whois) && !glob_admin(fr)) || (glob_owner(whois) && !glob_owner(fr)) || (glob_master(whois) && !glob_master(fr)) || (glob_bot(whois) && !glob_master(fr)) ) return 0; return 1; }
/* This will close channels if the HUB:leaf count is skewed from config setting */ static void check_should_close() { int H = close_threshold.count, L = close_threshold.time; if ((H <= 0) || (L <= 0)) return; int hc = 1, lc = 0; struct userrec *u = NULL; for (tand_t *bot = tandbot; bot; bot = bot->next) { if ((u = get_user_by_handle(userlist, bot->bot))) { if (bot_hublevel(u) < 999) hc++; else lc++; } } if ((hc >= H) && (lc <= L)) { for (struct chanset_t *chan = chanset; chan; chan = chan->next) { if (!channel_closed(chan)) { do_chanset(NULL, chan, "+closed chanmode +stni", DO_LOCAL | DO_NET); #ifdef G_BACKUP chan->channel.backup_time = now + 30; #endif /* G_BACKUP */ } } } }
/* idx nick conmask cmd par */ static void bot_rsim(char *botnick, char *code, char *msg) { int ridx = -1, idx = -1, i = 0, rconmask; unsigned long status = 0; char *nick = NULL, *cmd = NULL, *rconchan = NULL, buf[UHOSTMAX] = "", *par = NULL, *parp = NULL; struct userrec *u = get_user_by_handle(userlist, botnick); if (bot_hublevel(u) == 999) { putlog(LOG_WARN, "*", "BOTCMD received from a leaf. HIJACK."); return; } par = parp = strdup(msg); ridx = atoi(newsplit(&par)); nick = newsplit(&par); rconmask = atoi(newsplit(&par)); rconchan = newsplit(&par); if (egg_isdigit(par[0])) status = (unsigned long) atoi(newsplit(&par)); cmd = newsplit(&par); if (ridx < 0 || !nick || !cmd) { free(parp); return; } for (i = 0; i < dcc_total; i++) { /* See if we can find a simul-idx for the same ridx/nick */ if (dcc[i].type && dcc[i].simul == ridx && !strcasecmp(dcc[i].nick, nick)) { putlog(LOG_DEBUG, "*", "Simul found old idx for %s: %d (ridx: %d)", nick, i, ridx); dcc[i].simultime = now; idx = i; break; } } if (idx < 0) { idx = new_dcc(&DCC_CHAT, sizeof(struct chat_info)); putlog(LOG_DEBUG, "*", "Making new idx for %s@%s: %d ridx: %d", nick, botnick, idx, ridx); dcc[idx].sock = -1; dcc[idx].timeval = now; dcc[idx].simultime = now; dcc[idx].simul = ridx; dcc[idx].status = status; strlcpy(dcc[idx].simulbot, botnick, sizeof(dcc[idx].simulbot)); dcc[idx].u.chat->con_flags = rconmask; struct chat_info dummy; strlcpy(dcc[idx].u.chat->con_chan, rconchan, sizeof(dummy.con_chan)); dcc[idx].u.chat->strip_flags = STRIP_ALL; strlcpy(dcc[idx].nick, nick, sizeof(dcc[idx].nick)); simple_snprintf(buf, sizeof buf, "%s@%s", nick, botnick); strlcpy(dcc[idx].host, buf, sizeof(dcc[idx].host)); dcc[idx].addr = 0L; dcc[idx].user = get_user_by_handle(userlist, nick); } rmspace(par); check_bind_dcc(cmd, idx, par); free(parp); }
static void cmd_slowpart(int idx, char *par) { int intvl = 0, delay = 0, count = 1; char *chname = NULL, *p = NULL; struct chanset_t *chan = NULL; tand_t *bot = NULL; /* slowpart #chan 60 */ putlog(LOG_CMDS, "*", "#%s# slowpart %s", dcc[idx].nick, par); chname = newsplit(&par); p = newsplit(&par); intvl = atoi(p); if (!chname[0] || !p[0]) { dprintf(idx, "Usage: slowpart <channel> <interval-seconds>\n"); return; } if (intvl < 10) { dprintf(idx, "Interval must be at least 10 seconds\n"); return; } if (!(chan = findchan_by_dname(chname))) { dprintf(idx, "No such channel %s\n", chname); return; } if (conf.bot->hub) count = 0; for (bot = tandbot; bot; bot = bot->next) { char tmp[100] = ""; tmp[0] = 0; if (bot->u) { if (bot_hublevel(bot->u) < 999) { /* HUB */ simple_snprintf(tmp, sizeof(tmp), "sp %s 0", chname); } else { /* LEAF */ struct flag_record fr = { FR_CHAN|FR_GLOBAL|FR_BOT, 0, 0, 0 }; get_user_flagrec(bot->u, &fr, chname); /* Only send the 'sp' command if the bot is supposed to be in the channel (backups and such) */ if (bot_shouldjoin(bot->u, &fr, chan)) { /* Variation: 60 secs intvl should be 60 +/- 15 */ int v = (random() % (intvl / 2)) - (intvl / 4); delay += intvl; simple_snprintf(tmp, sizeof(tmp), "sp %s %i", chname, delay + v); count++; } } if (tmp[0]) putbot(bot->bot, tmp); } } remove_channel(chan); if (conf.bot->hub) write_userfile(-1); dprintf(idx, "Channel %s removed from the bot.\n", chname); dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n"); if (findchan_by_dname(chname)) { dprintf(idx, "Failed to remove channel.\n"); return; } dprintf(idx, "%i bots parting %s during the next %i seconds\n", count, chname, delay); if (!conf.bot->hub) dprintf(DP_MODE, "PART %s\n", chname); }
static void cmd_slowjoin(int idx, char *par) { int intvl = 0, delay = 0, count = 0; char *chname = NULL, *p = NULL, buf[2048] = "", buf2[RESULT_LEN] = ""; struct chanset_t *chan = NULL; tand_t *bot = NULL; /* slowjoin #chan 60 */ putlog(LOG_CMDS, "*", "#%s# slowjoin %s", dcc[idx].nick, par); chname = newsplit(&par); p = newsplit(&par); intvl = atoi(p); if (!chname[0] || !p[0]) { dprintf(idx, "Usage: slowjoin <channel> <interval-seconds> [channel options]\n"); return; } if (intvl < 10) { dprintf(idx, "Interval must be at least 10 seconds\n"); return; } if ((chan = findchan_by_dname(chname))) { dprintf(idx, "Already on %s\n", chan->dname); return; } if (!strchr(CHANMETA, chname[0])) { dprintf(idx, "Invalid channel name\n"); return; } simple_snprintf(buf, sizeof(buf), "+inactive addedby %s addedts %li ", dcc[idx].nick, (long)now); if (par[0]) strlcat(buf, par, sizeof(buf)); if (channel_add(buf2, chname, buf) == ERROR) { dprintf(idx, "Invalid channel or channel options.\n"); if (buf2[0]) dprintf(idx, " %s\n", buf2); return; } buf2[0] = 0; chan = findchan_by_dname(chname); if (!chan) { dprintf(idx, "Hmmm... Channel didn't get added. Weird *shrug*\n"); return; } simple_snprintf(buf2, sizeof(buf2), "cjoin %s %s", chan->dname, buf); putallbots(buf2); if (conf.bot->hub) count = 0; chan->status &= ~CHAN_INACTIVE; for (bot = tandbot; bot; bot = bot->next) { char tmp[100] = ""; tmp[0] = 0; if (bot->u) { if (bot_hublevel(bot->u) < 999) { simple_snprintf(tmp, sizeof(tmp), "sj %s 0", chname); } else { struct flag_record fr = { FR_CHAN|FR_GLOBAL|FR_BOT, 0, 0, 0 }; get_user_flagrec(bot->u, &fr, chname); /* Only send the 'sj' command if the bot is supposed to be in the channel (backups and such) */ if (bot_shouldjoin(bot->u, &fr, chan, 1)) { /* Variation: 60 secs intvl should be 60 +/- 15 */ int v = (random() % (intvl / 2)) - (intvl / 4); delay += intvl; simple_snprintf(tmp, sizeof(tmp), "sj %s %i", chname, delay + v); count++; } } if (tmp[0]) putbot(bot->bot, tmp); } } if (!conf.bot->hub && shouldjoin(chan)) count++; dprintf(idx, "%i bots joining %s during the next %i seconds\n", count, chan->dname, delay); if (!conf.bot->hub && shouldjoin(chan)) join_chan(chan); }