static void got_cpart(char *botnick, char *code, char *par) { if (!par[0]) return; char *chname = newsplit(&par); struct chanset_t *chan = NULL; if (!(chan = findchan_by_dname(chname))) return; char *bots = newsplit(&par); int match = 0; /* if bots is '*' just remove_channel */ if (!strcmp(bots, "*")) match = 0; else match = parsebots(bots, conf.bot->nick); if (match) do_chanset(NULL, chan, "+inactive", DO_LOCAL); else remove_channel(chan); if (conf.bot->hub) write_userfile(-1); }
static void got_term(int z) { if (conf.bot->hub) write_userfile(-1); fatal("Received SIGTERM", 0); exit(1); /* for GCC noreturn */ }
static int console_store(int idx, char *par, bool displaySave) { struct console_info *i = (struct console_info *) get_user(&USERENTRY_CONSOLE, dcc[idx].user); if (!i) i = (struct console_info *) my_calloc(1, sizeof(struct console_info)); if (i->channel) free(i->channel); i->channel = strdup(dcc[idx].u.chat->con_chan); i->conflags = dcc[idx].u.chat->con_flags; i->stripflags = dcc[idx].u.chat->strip_flags; i->echoflags = (dcc[idx].status & STAT_ECHO) ? 1 : 0; if (dcc[idx].status & STAT_PAGE) i->page = dcc[idx].u.chat->max_line; else i->page = 0; if (dcc[idx].status & STAT_COLOR) i->color = 1; else i->color = 0; if (dcc[idx].status & STAT_BANNER) i->banner = 1; else i->banner = 0; if (dcc[idx].status & STAT_CHANNELS) i->channels = 1; else i->channels = 0; if (dcc[idx].status & STAT_BOTS) i->bots = 1; else i->bots = 0; if (dcc[idx].status & STAT_WHOM) i->whom = 1; else i->whom = 0; i->conchan = dcc[idx].u.chat->channel; if (par) { dprintf(idx, "%s\n", "Saved your Console Settings:"); dprintf(idx, " %s %s\n", "Channel:", i->channel); dprintf(idx, " %s %s, %s %s, %s %s\n", "Console flags:", masktype(i->conflags), "", stripmasktype(i->stripflags), "Echo:", i->echoflags ? "yes" : "no"); dprintf(idx, " %s %d, %s %d\n", "Page setting:", i->page, "Console channel:", i->conchan); dprintf(idx, " Color: $b%s$b\n", i->color ? "on" : "off"); dprintf(idx, " Login settings:\n"); dprintf(idx, " Login settings:\n"); dprintf(idx, " Banner: $b%-3s$b Bots: $b%-3s$b\n", i->banner ? "on" : "off", i->bots ? "on" : "off"); dprintf(idx, " Channels: $b%-3s$b Whom: $b%-3s$b\n", i->channels ? "on" : "off", i->whom ? "on" : "off"); } set_user(&USERENTRY_CONSOLE, dcc[idx].user, i); dprintf(idx, "Console setting stored.\n"); if (conf.bot->hub) write_userfile(displaySave ? idx : -1); return 0; }
static void pls_chan(int idx, char *par, char *bot) { char *chname = NULL, result[RESULT_LEN] = "", buf[2048] = ""; struct chanset_t *chan = NULL; if (!bot) putlog(LOG_CMDS, "*", "#%s# +chan %s", dcc[idx].nick, par); if (!par[0]) { dprintf(idx, "Usage: +chan [%s]<channel> [options]\n", CHANMETA); return; } chname = newsplit(&par); simple_snprintf(buf, sizeof(buf), "cjoin %s %s", chname, bot ? bot : "*"); /* +chan makes all bots join */ if (par[0]) { strlcat(buf, " ", sizeof(buf)); strlcat(buf, par, sizeof(buf)); strlcat(buf, " ", sizeof(buf)); } if (!bot && findchan_by_dname(chname)) { dprintf(idx, "That channel already exists!\n"); return; } else if ((chan = findchan(chname)) && !bot) { dprintf(idx, "That channel already exists as %s!\n", chan->dname); return; } else if (strchr(CHANMETA, chname[0]) == NULL) { dprintf(idx, "Invalid channel prefix.\n"); return; } else if (strchr(chname, ',') != NULL) { dprintf(idx, "Invalid channel name.\n"); return; } if (!chan && !findchan_by_dname(chname) && channel_add(result, chname, par) == ERROR) { dprintf(idx, "Invalid channel or channel options.\n"); if (result[0]) dprintf(idx, " %s\n", result); } else { if ((chan = findchan_by_dname(chname))) { char tmp[51] = ""; simple_snprintf(tmp, sizeof(tmp), "addedby %s addedts %li", dcc[idx].nick, (long) now); if (buf[0]) { strlcat(buf, " ", sizeof(buf)); strlcat(buf, tmp, sizeof(buf)); } do_chanset(NULL, chan, buf[0] ? buf : tmp, DO_LOCAL); if (!bot) { dprintf(idx, "Channel %s added to the botnet.\n", chname); } else { dprintf(idx, "Channel %s added to the bot: %s\n", chname, bot); } putallbots(buf); } if (conf.bot->hub) write_userfile(-1); } }
static void got_hup(int z) { write_userfile(-1); if (check_tcl_signal("sighup")) return; putlog(LOG_MISC, "*", "Received HUP signal: rehashing..."); do_restart = -2; return; }
/* Kills the bot. s1 is the reason shown to other bots, * s2 the reason shown on the partyline. (Sup 25Jul2001) */ void kill_bot(char *s1, char *s2) { write_userfile(-1); if (!conf.bot->hub) server_die(); chatout("*** %s\n", s1); botnet_send_chat(-1, conf.bot->nick, s1); botnet_send_bye(s2); fatal(s2, 0); }
static void got_term(int z) { write_userfile(-1); check_tcl_event("sigterm"); if (die_on_sigterm) { botnet_send_chat(-1, botnetnick, "ACK, I've been terminated!"); fatal("TERMINATE SIGNAL -- SIGNING OFF", 0); } else putlog(LOG_MISC, "*", "RECEIVED TERMINATE SIGNAL (IGNORING)"); }
static void got_hup(int z) { write_userfile(-1); check_tcl_event("sighup"); if (die_on_sighup) { fatal("HANGUP SIGNAL -- SIGNING OFF", 0); } else putlog(LOG_MISC, "*", "Received HUP signal: rehashing..."); do_restart = -2; return; }
static void got_sp(int idx, char *code, char *par) { struct chanset_t *chan = findchan_by_dname(newsplit(&par)); if (chan) { if (conf.bot->hub) { remove_channel(chan); write_userfile(-1); } else chan->channel.parttime = ((atoi(par) + now) - server_lag); } }
static void got_sj(int idx, char *code, char *par) { struct chanset_t *chan = findchan_by_dname(newsplit(&par)); if (chan) { if (conf.bot->hub) { chan->status &= ~CHAN_INACTIVE; write_userfile(-1); } else chan->channel.jointime = ((atoi(par) + now) - server_lag); } }
static void cmd_mns_chrec(int idx, char *par) { char *nick = NULL, *chn = NULL; struct userrec *u1 = NULL; struct chanuserrec *chanrec = NULL; if (!par[0]) { dprintf(idx, "Usage: -chrec <user> [channel]\n"); return; } nick = newsplit(&par); u1 = get_user_by_handle(userlist, nick); if (!u1) { dprintf(idx, "No such user.\n"); return; } if (!par[0]) { struct chanset_t *chan; chan = findchan_by_dname(dcc[idx].u.chat->con_chan); if (chan) chn = chan->dname; else { dprintf(idx, "Invalid console channel.\n"); return; } } else chn = newsplit(&par); get_user_flagrec(dcc[idx].user, &user, chn); get_user_flagrec(u1, &victim, chn); if (privchan(user, findchan_by_dname(chn), PRIV_OP)) { dprintf(idx, "No such channel.\n"); return; } if ((!glob_master(user) && !chan_master(user)) || /* drummer */ (chan_owner(victim) && !chan_owner(user) && !glob_owner(user)) || (glob_owner(victim) && !glob_owner(user))) { dprintf(idx, "You have no permission to do that.\n"); return; } chanrec = get_chanrec(u1, chn); if (!chanrec) { dprintf(idx, "User %s doesn't have a channel record for %s.\n", nick, chn); return; } putlog(LOG_CMDS, "*", "#%s# -chrec %s %s", dcc[idx].nick, nick, chn); del_chanrec(u1, chn); dprintf(idx, "Removed %s channel record from %s.\n", chn, nick); if (conf.bot->hub) write_userfile(idx); }
void hard_restart(int idx) { write_userfile(idx); if (!conf.bot->hub) { nuke_server((char *) reason); /* let's drop the server connection ASAP */ cycle_time = 0; } fatal(idx <= 0x7FF0 ? reason : NULL, 1); usleep(2000 * 500); unlink(conf.bot->pid_file); /* if this fails it is ok, cron will restart the bot, *hopefully* */ simple_exec(binname, conf.bot->nick); exit(0); }
static void got_cjoin(char *botnick, char *code, char *par) { if (!par[0]) return; char *chname = newsplit(&par), *options = NULL; struct chanset_t *chan = findchan_by_dname(chname); int match = 0; if (conf.bot->hub) { newsplit(&par); /* hubs ignore the botmatch param */ options = par; } else { /* ALL hubs should add the channel, leaf should check the list for a match */ bool inactive = 0; char *bots = newsplit(&par); match = parsebots(bots, conf.bot->nick); if (strstr(par, "+inactive")) inactive = 1; if (chan && !match) return; if (!match) { size_t size = strlen(par) + 12 + 1; options = (char *) my_calloc(1, size); simple_snprintf(options, size, "%s +inactive", par); } else if (match && chan && !shouldjoin(chan)) { if (!inactive) do_chanset(NULL, chan, "-inactive", DO_LOCAL); return; } else options = par; } if (chan) return; sdprintf("OPTIONS: %s", options); char result[RESULT_LEN] = ""; if (channel_add(result, chname, options) == ERROR) /* drummer */ putlog(LOG_BOTS, "@", "Invalid channel or channel options from %s for %s: %s", botnick, chname, result); if (conf.bot->hub) write_userfile(-1); if (!match && !conf.bot->hub) free(options); }
static void mns_chan(int idx, char *par, char *bot) { char *chname = NULL, buf2[1024] = ""; struct chanset_t *chan = NULL; int i; if (!bot) putlog(LOG_CMDS, "*", "#%s# -chan %s", dcc[idx].nick, par); if (!par[0]) { dprintf(idx, "Usage: -chan [%s]<channel>\n", CHANMETA); return; } chname = newsplit(&par); simple_snprintf(buf2, sizeof(buf2), "cpart %s %s", chname, bot ? bot : "*"); if (bot) /* bot will just set it +inactive */ putbot(bot, buf2); else putallbots(buf2); chan = findchan_by_dname(chname); if (!chan) { if ((chan = findchan(chname))) dprintf(idx, "That channel exists with a short name of %s, use that.\n", chan->dname); else dprintf(idx, "That channel doesn't exist!\n"); return; } if (!bot) { for (i = 0; i < dcc_total; i++) { if (dcc[i].type && (dcc[i].type->flags & DCT_CHAT) && !rfc_casecmp(dcc[i].u.chat->con_chan, chan->dname)) { dprintf(i, "%s is no longer a valid channel, changing your console to '*'\n", chname); strlcpy(dcc[i].u.chat->con_chan, "*", 2); console_dostore(i, 0); } } remove_channel(chan); if (conf.bot->hub) write_userfile(idx); dprintf(idx, "Channel %s removed from the botnet.\n", chname); dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n"); } else dprintf(idx, "Channel %s removed from the bot: %s\n", chname, bot); }
static void cmd_mns_mask(const char type, int idx, char *par) { const char *cmd = (type == 'b' ? "ban" : type == 'e' ? "exempt" : "invite"); if (!par[0]) { usage: dprintf(idx, "Usage: -%s <hostmask> [channel]\n", cmd); return; } int i = 0, j; struct chanset_t *chan = NULL; char s[UHOSTLEN] = "", *who = NULL, *chname = NULL, *mask = NULL; masklist *m = NULL; who = newsplit(&par); if (par[0] && strchr(CHANMETA, par[0])) chname = newsplit(&par); /* Did they mix up the two params? */ if (!chname && strchr(CHANMETA, who[0])) { if (par[0]) { chname = who; who = newsplit(&par); } else { goto usage; } } if (!chname) chname = dcc[idx].u.chat->con_chan; if (chname || !(dcc[idx].user->flags & USER_MASTER)) { if (!chname) chname = dcc[idx].u.chat->con_chan; get_user_flagrec(dcc[idx].user, &user, chname); if (strchr(CHANMETA, chname[0]) && privchan(user, findchan_by_dname(chname), PRIV_OP)) { dprintf(idx, "No such channel.\n"); return; } if (!chk_op(user, findchan_by_dname(chname))) return; } strlcpy(s, who, sizeof s); i = u_delmask(type, NULL, s, (dcc[idx].user->flags & USER_MASTER)); if (i > 0) { if (lastdeletedmask) mask = lastdeletedmask; else mask = s; putlog(LOG_CMDS, "*", "#%s# -%s %s", dcc[idx].nick, cmd, mask); dprintf(idx, "%s %s: %s\n", "Removed", cmd, s); if (!conf.bot->hub) { for (chan = chanset; chan != NULL; chan = chan->next) add_mode(chan, '-', type, mask); } else write_userfile(idx); return; } /* Channel-specific ban? */ if (chname) chan = findchan_by_dname(chname); if (chan) { m = type == 'b' ? chan->channel.ban : type == 'e' ? chan->channel.exempt : chan->channel.invite; if (str_isdigit(who) && (i = atoi(who)) > 0) { simple_snprintf(s, sizeof s, "%d", i); j = u_delmask(type, chan, s, 1); if (j > 0) { if (lastdeletedmask) mask = lastdeletedmask; else mask = s; putlog(LOG_CMDS, "*", "#%s# (%s) -%s %s", dcc[idx].nick, chan->dname, cmd, mask); dprintf(idx, "Removed %s channel %s: %s\n", chan->dname, cmd, mask); if (!conf.bot->hub) add_mode(chan, '-', type, mask); else write_userfile(idx); return; } i = 0; for (; m && m->mask && m->mask[0]; m = m->next) { if ((!u_equals_mask(type == 'b' ? global_bans : type == 'e' ? global_exempts : global_invites, m->mask)) && (!u_equals_mask(type == 'b' ? chan->bans : type == 'e' ? chan->exempts : chan->invites, m->mask))) { i++; if (i == -j) { dprintf(idx, "%s %s '%s' on %s.\n", "Removed", cmd, m->mask, chan->dname); putlog(LOG_CMDS, "*", "#%s# (%s) -%s %s [on channel]", dcc[idx].nick, chan->dname, cmd, who); if (!conf.bot->hub) add_mode(chan, '-', type, m->mask); else write_userfile(idx); return; } } } } else { j = u_delmask(type, chan, who, 1); if (j > 0) { putlog(LOG_CMDS, "*", "#%s# (%s) -%s %s", dcc[idx].nick, dcc[idx].u.chat->con_chan, cmd, who); dprintf(idx, "Removed %s channel %s: %s\n", chname, cmd, who); if (!conf.bot->hub) add_mode(chan, '-', type, who); else write_userfile(idx); return; } for (; m && m->mask && m->mask[0]; m = m->next) { if (!rfc_casecmp(m->mask, who)) { dprintf(idx, "%s %s '%s' on %s.\n", "Removed", cmd, m->mask, chan->dname); putlog(LOG_CMDS, "*", "#%s# (%s) -%s %s [on channel]", dcc[idx].nick, chan->dname, cmd, who); if (!conf.bot->hub) add_mode(chan, '-', type, m->mask); else write_userfile(idx); return; } } } } dprintf(idx, "No such %s.\n", cmd); }
static void core_hourly() { write_userfile(-1); }
static void cmd_chinfo(int idx, char *par) { if (!use_info) { dprintf(idx, "Info storage is turned off.\n"); return; } char *handle = newsplit(&par); if (!handle[0]) { dprintf(idx, "Usage: chinfo <handle> [channel] <new-info>\n"); return; } struct userrec *u1 = get_user_by_handle(userlist, handle); if (!u1 || (u1 && !whois_access(dcc[idx].user, u1))) { dprintf(idx, "No such user.\n"); return; } char *chname = NULL; if (par[0] && strchr(CHANMETA, par[0])) { chname = newsplit(&par); if (!findchan_by_dname(chname)) { dprintf(idx, "No such channel.\n"); return; } } else chname = 0; if (u1->bot && !(dcc[idx].user->flags & USER_MASTER)) { dprintf(idx, "You have to be master to change bots info.\n"); return; } if ((u1->flags & USER_OWNER) && !(dcc[idx].user->flags & USER_OWNER)) { dprintf(idx, "You can't change info for the bot owner.\n"); return; } if (chname) { get_user_flagrec(dcc[idx].user, &user, chname); get_user_flagrec(u1, &victim, chname); if ((chan_owner(victim) || glob_owner(victim)) && !(glob_owner(user) || chan_owner(user))) { dprintf(idx, "You can't change info for the channel owner.\n"); return; } } putlog(LOG_CMDS, "*", "#%s# chinfo %s %s %s", dcc[idx].nick, handle, chname ? chname : par, chname ? par : ""); if (!strcasecmp(par, "none")) par[0] = 0; if (chname) { set_handle_chaninfo(userlist, handle, chname, par); if (par[0] == '@') dprintf(idx, "New info (LOCKED) for %s on %s: %s\n", handle, chname, &par[1]); else if (par[0]) dprintf(idx, "New info for %s on %s: %s\n", handle, chname, par); else dprintf(idx, "Wiped info for %s on %s\n", handle, chname); if (conf.bot->hub) write_userfile(idx); } else { set_user(&USERENTRY_INFO, u1, par[0] ? par : NULL); if (par[0] == '@') dprintf(idx, "New default info (LOCKED) for %s: %s\n", handle, &par[1]); else if (par[0]) dprintf(idx, "New default info for %s: %s\n", handle, par); else dprintf(idx, "Wiped default info for %s\n", handle); if (conf.bot->hub) write_userfile(idx); } }
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_stick_yn(int idx, char *par, int yn) { int i = 0, j; struct chanset_t *chan = NULL; char *stick_type = NULL, s[UHOSTLEN] = "", chname[81] = "", type = 0, *str_type = NULL; maskrec *channel_list = NULL; stick_type = newsplit(&par); strlcpy(s, newsplit(&par), sizeof s); strlcpy(chname, newsplit(&par), sizeof chname); if (strcasecmp(stick_type, "exempt") && strcasecmp(stick_type, "invite") && strcasecmp(stick_type, "ban")) { strlcpy(chname, s, sizeof chname); strlcpy(s, stick_type, sizeof s); stick_type = "ban"; } if (!s[0]) { dprintf(idx, "Usage: %sstick [ban/exempt/invite] <hostmask or number> [channel]\n", yn ? "" : "un"); return; } /* Now deal with exemptions */ if (!strcasecmp(stick_type, "exempt")) { type = 'e'; str_type = "exempt"; } else if (!strcasecmp(stick_type, "invite")) { type = 'I'; str_type = "invite"; } else if (!strcasecmp(stick_type, "ban")) { type = 'b'; str_type = "ban"; } else return; if (!chname[0]) { channel_list = (type == 'b' ? global_bans : type == 'e' ? global_exempts : global_invites); i = u_setsticky_mask(NULL, channel_list, s, (dcc[idx].user->flags & USER_MASTER) ? yn : -1, type); if (i > 0) { putlog(LOG_CMDS, "*", "#%s# %sstick %s %s", dcc[idx].nick, yn ? "" : "un", str_type, s); dprintf(idx, "%stuck %s: %s\n", yn ? "S" : "Uns", str_type, s); if (!conf.bot->hub) { struct chanset_t *achan = NULL; for (achan = chanset; achan != NULL; achan = achan->next) check_this_mask(type, achan, s, yn); } else write_userfile(idx); return; } strlcpy(chname, dcc[idx].u.chat->con_chan, sizeof chname); } /* Channel-specific mask? */ if (!(chan = findchan_by_dname(chname))) { dprintf(idx, "No such channel.\n"); return; } get_user_flagrec(dcc[idx].user, &user, chan->dname); if (privchan(user, chan, PRIV_OP)) { dprintf(idx, "No such channel.\n"); return; } channel_list = (type == 'b' ? chan->bans : type == 'e' ? chan->exempts : chan->invites); if (str_isdigit(s)) { /* substract the numer of global masks to get the number of the channel masks */ j = atoi(s); j -= count_mask(type == 'b' ? global_bans : type == 'e' ? global_exempts : global_invites); simple_snprintf(s, sizeof s, "%d", j); } j = u_setsticky_mask(chan, channel_list, s, yn, type); if (j > 0) { putlog(LOG_CMDS, "*", "#%s# %sstick %s %s %s", dcc[idx].nick, yn ? "" : "un", str_type, s, chname); dprintf(idx, "%stuck %s %s: %s\n", yn ? "S" : "Uns", chname, str_type, s); if (!conf.bot->hub) check_this_mask(type, chan, s, yn); else write_userfile(idx); return; } dprintf(idx, "No such %s.\n", str_type); }
void restart(int idx) { const char *reason = updating ? STR("Updating...") : STR("Restarting..."); Tempfile *socks = new Tempfile("socks"); int fd = 0; sdprintf("%s", reason); if (tands > 0) { botnet_send_chat(-1, conf.bot->nick, (char *) reason); botnet_send_bye(reason); } /* kill all connections except STDOUT/server */ for (fd = 0; fd < dcc_total; fd++) { if (dcc[fd].type && dcc[fd].type != &SERVER_SOCKET && dcc[fd].sock != STDOUT) { if (dcc[fd].sock >= 0) killsock(dcc[fd].sock); lostdcc(fd); } } const char salt1[] = SALT1; EncryptedStream stream(salt1); /* write out all leftover dcc[] entries */ for (fd = 0; fd < dcc_total; fd++) if (dcc[fd].type && dcc[fd].sock != STDOUT) dcc_write(stream, fd); /* write out all leftover socklist[] entries */ for (fd = 0; fd < MAXSOCKS; fd++) if (socklist[fd].sock != STDOUT) sock_write(stream, fd); if (server_online) { if (botname[0]) stream << bd::String::printf(STR("+botname %s\n"), botname); if (rolls) stream << bd::String::printf(STR("+rolls %d\n"), rolls); if (altnick_char) stream << bd::String::printf(STR("+altnick_char %c\n"), altnick_char); if (burst) stream << bd::String::printf(STR("+burst %d\n"), burst); if (flood_count) stream << bd::String::printf(STR("+flood_count %d\n"), flood_count); if (my_cookie_counter) stream << bd::String::printf(STR("+my_cookie_counter %lu\n"), my_cookie_counter); stream << bd::String::printf(STR("+server_online %li\n"), (long)server_online); } stream << bd::String::printf(STR("+online_since %li\n"), (long)online_since); if (floodless) stream << bd::String::printf(STR("+server_floodless %d\n"), floodless); if (in_deaf) stream << bd::String::printf(STR("+in_deaf\n")); if (in_callerid) stream << bd::String::printf(STR("+in_callerid\n")); for (struct chanset_t *chan = chanset; chan; chan = chan->next) if (shouldjoin(chan) && (channel_active(chan) || channel_pending(chan))) stream << bd::String::printf(STR("+chan %s\n"), chan->dname); stream << bd::String::printf(STR("+buildts %li\n"), (long)buildts); stream << bd::String::printf(STR("+ip4 %s\n"), myipstr(AF_INET)); stream << bd::String::printf(STR("+ip6 %s\n"), myipstr(AF_INET6)); replay_cache(-1, &stream); stream.writeFile(socks->fd); socks->my_close(); write_userfile(idx); /* if (server_online) { do_chanset(NULL, NULL, STR("+inactive"), DO_LOCAL); dprintf(DP_DUMP, STR("JOIN 0\n")); } */ fixmod(binname); /* replace image now */ char *argv[4] = { NULL, NULL, NULL, NULL }; argv[0] = strdup(binname); if (!backgrd || term_z || sdebug) { char shit[7] = ""; simple_snprintf(shit, sizeof(shit), STR("-%s%s%s"), !backgrd ? "n" : "", term_z ? "t" : "", sdebug ? "D" : ""); argv[1] = strdup(shit); argv[2] = strdup(conf.bot->nick); } else { argv[1] = strdup(conf.bot->nick); } unlink(conf.bot->pid_file); FILE *fp = NULL; if (!(fp = fopen(conf.bot->pid_file, "w"))) return; fprintf(fp, "%d %s\n", getpid(), socks->file); fclose(fp); execvp(argv[0], &argv[0]); /* hopefully this is never reached */ putlog(LOG_MISC, "*", STR("Could not restart: %s"), strerror(errno)); return; }
static void cmd_chanset(int idx, char *par) { char *chname = NULL, result[RESULT_LEN] = ""; struct chanset_t *chan = NULL; int all = 0; if (!par[0]) { putlog(LOG_CMDS, "*", "#%s# chanset %s", dcc[idx].nick, par); dprintf(idx, "Usage: chanset [%schannel|*|default] <settings>\n", CHANMETA); return; } // Determine channel name if (strchr(CHANMETA, par[0]) || !strncasecmp(par, "default", 7) || !strncmp(par, "*", 1)) chname = newsplit(&par); else { if (strncmp(dcc[idx].u.chat->con_chan, "*", 1) && !(chan = findchan_by_dname(chname = dcc[idx].u.chat->con_chan))) { dprintf(idx, "Invalid console channel.\n"); return; } chname = dcc[idx].u.chat->con_chan; } if (chname && chname[0]) { if (!strncmp(chname, "*", 1)) { all = 1; get_user_flagrec(dcc[idx].user, &user, chanset ? chanset->dname : ""); if (!glob_owner(user)) { dprintf(idx, "You need to be a global owner to use '%schanset *'.\n", (dcc[idx].u.chat->channel >= 0) ? settings.dcc_prefix : ""); return; } } else if (!strcasecmp(chname, "default")) { chan = chanset_default; } else chan = findchan_by_dname(chname); } if (!all && !chan && chname && chname[0]) { dprintf(idx, "No such channel.\n"); return; } if (!par[0]) { dprintf(idx, "Usage: chanset [%schannel|*|default] <settings>\n", CHANMETA); return; } if (!all) { get_user_flagrec(dcc[idx].user, &user, chan->dname); if (privchan(user, chan, PRIV_OP)) { dprintf(idx, "No such channel.\n"); return; } if (!glob_master(user) && !chan_master(user)) { dprintf(idx, "You don't have access to %s. \n", chan->dname); return; } else if ((strstr(par, "+private") || strstr(par, "-private")) && (!glob_owner(user))) { dprintf(idx, "You don't have access to set +/-private on %s (halting command).\n", chan->dname); return; } else if ((strstr(par, "+backup") || strstr(par, "-backup")) && (!glob_owner(user))) { dprintf(idx, "You don't have access to set +/-backup on %s (halting command).\n", chan->dname); return; } else if ((strstr(par, "+inactive") || strstr(par, "-inactive")) && (!glob_owner(user))) { dprintf(idx, "You don't have access to set +/-inactive on %s (halting command).\n", chan->dname); return; } } putlog(LOG_CMDS, "*", "#%s# chanset (%s) %s", dcc[idx].nick, all ? "*" : chan->dname, par); if (do_chanset(result, all ? NULL : chan, par, DO_LOCAL | DO_NET | CMD) == ERROR) { dprintf(idx, "Error trying to set { %s } on %s: %s\n", par, all ? "all channels" : chan->dname, result); return; } if (all) dprintf(idx, "Successfully set modes { %s } on all channels (Including the default).\n", par); else dprintf(idx, "Successfully set modes { %s } on %s\n", par, chan->dname); if (conf.bot->hub) write_userfile(idx); }
static void cmd_pls_mask(const char type, int idx, char *par) { const char *cmd = (type == 'b' ? "ban" : type == 'e' ? "exempt" : "invite"); if (!par[0]) { usage: dprintf(idx, "Usage: +%s <hostmask> [channel] [%%<XdXhXm>] [reason]\n", cmd); return; } char *chname = NULL, *who = NULL, s[UHOSTLEN] = "", s1[UHOSTLEN] = "", *p = NULL, *p_expire = NULL; unsigned long int expire_time = 0, expire_foo; int sticky = 0; struct chanset_t *chan = NULL; who = newsplit(&par); if (par[0] && strchr(CHANMETA, par[0])) chname = newsplit(&par); /* Did they mix up the two params? */ if (!chname && strchr(CHANMETA, who[0])) { if (par[0]) { chname = who; who = newsplit(&par); } else { goto usage; } } if (chname || !(dcc[idx].user->flags & USER_MASTER)) { if (!chname) chname = dcc[idx].u.chat->con_chan; get_user_flagrec(dcc[idx].user, &user, chname); chan = findchan_by_dname(chname); /* *shrug* ??? (guppy:10Feb1999) */ if (!chan || (chan && privchan(user, chan, PRIV_OP))) { dprintf(idx, "No such channel.\n"); return; } else if (!chk_op(user, chan)) { dprintf(idx, "You don't have access to set %ss on %s.\n", cmd, chname); return; } } else chan = 0; /* Added by Q and Solal -- Requested by Arty2, special thanx :) */ if (par[0] == '%') { p = newsplit(&par); p_expire = p + 1; while (*(++p) != 0) { switch (tolower(*p)) { case 'd': *p = 0; expire_foo = strtol(p_expire, NULL, 10); if (expire_foo > 365) expire_foo = 365; expire_time += 86400 * expire_foo; p_expire = p + 1; break; case 'h': *p = 0; expire_foo = strtol(p_expire, NULL, 10); if (expire_foo > 8760) expire_foo = 8760; expire_time += 3600 * expire_foo; p_expire = p + 1; break; case 'm': *p = 0; expire_foo = strtol(p_expire, NULL, 10); if (expire_foo > 525600) expire_foo = 525600; expire_time += 60 * expire_foo; p_expire = p + 1; } } } if (!par[0]) par = "requested"; else if (strlen(par) > MASKREASON_MAX) par[MASKREASON_MAX] = 0; if (strlen(who) > UHOSTMAX - 4) who[UHOSTMAX - 4] = 0; /* Fix missing ! or @ BEFORE checking against myself */ if (!strchr(who, '!')) { if (!strchr(who, '@')) simple_snprintf(s, sizeof s, "%s!*@*", who); /* Lame nick ban */ else simple_snprintf(s, sizeof s, "*!%s", who); } else if (!strchr(who, '@')) simple_snprintf(s, sizeof s, "%s@*", who); /* brain-dead? */ else strlcpy(s, who, sizeof s); if (conf.bot->hub) simple_snprintf(s1, sizeof s1, "%s!%s@%s", origbotname, botuser, conf.bot->net.host); else simple_snprintf(s1, sizeof s1, "%s!%s", botname, botuserhost); if (type == 'b' && s1[0] && wild_match(s, s1)) { dprintf(idx, "I'm not going to ban myself.\n"); putlog(LOG_CMDS, "*", "#%s# attempted +ban %s", dcc[idx].nick, s); return; } /* IRC can't understand bans longer than 70 characters */ if (strlen(s) > 70) { s[69] = '*'; s[70] = 0; } if (chan) { u_addmask(type, chan, s, dcc[idx].nick, par, expire_time ? now + expire_time : 0, 0); if (par[0] == '*') { sticky = 1; par++; putlog(LOG_CMDS, "*", "#%s# (%s) +%s %s %s (%s) (sticky)", dcc[idx].nick, dcc[idx].u.chat->con_chan, cmd, s, chan->dname, par); dprintf(idx, "New %s sticky %s: %s (%s)\n", chan->dname, cmd, s, par); } else { putlog(LOG_CMDS, "*", "#%s# (%s) +%s %s %s (%s)", dcc[idx].nick, dcc[idx].u.chat->con_chan, cmd, s, chan->dname, par); dprintf(idx, "New %s %s: %s (%s)\n", chan->dname, cmd, s, par); } if (!conf.bot->hub) { if (type == 'e' || type == 'I') add_mode(chan, '+', type, s); /* Avoid unnesessary modes if you got +dynamicbans */ else check_this_ban(chan, s, sticky); } else write_userfile(idx); } else { u_addmask(type, NULL, s, dcc[idx].nick, par, expire_time ? now + expire_time : 0, 0); if (par[0] == '*') { sticky = 1; par++; putlog(LOG_CMDS, "*", "#%s# (GLOBAL) +%s %s (%s) (sticky)", dcc[idx].nick, cmd, s, par); dprintf(idx, "New sticky %s: %s (%s)\n", cmd, s, par); } else { putlog(LOG_CMDS, "*", "#%s# (GLOBAL) +%s %s (%s)", dcc[idx].nick, cmd, s, par); dprintf(idx, "New %s: %s (%s)\n", cmd, s, par); } if (!conf.bot->hub) { for (chan = chanset; chan != NULL; chan = chan->next) { if (type == 'b') check_this_ban(chan, s, sticky); else add_mode(chan, '+', type, s); } } else write_userfile(idx); } }