This repository has been archived on 2025-02-12. You can view files and clone it, but cannot push or open issues or pull requests.
NeoStats-secureserv/OnJoinBot.c
2004-09-09 19:50:57 +00:00

1027 lines
28 KiB
C

/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2004 Justin Hammond
** http://www.neostats.net/
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#include <stdio.h>
#include "neostats.h"
#include "SecureServ.h"
#define MAX_NICKS 100
#define DEFAULT_VERSION_RESPONSE "Visual IRC 2.0rc5 (English) - Fast. Powerful. Free. http://www.visualirc.net/beta.php"
typedef struct randomnicks {
char nick[MAXNICK];
char user[MAXUSER];
char host[MAXHOST];
char realname[MAXREALNAME];
}randomnicks;
static char confbuf[CONFBUFSIZE];
static list_t *monchans;
static int SaveMonChans();
/* this is the list of random nicknames */
static list_t *nicks;
char onjoinbot_modes[MODESIZE] = "+";
static lnode_t *lastmonchan;
static unsigned hrand(unsigned upperbound, unsigned lowerbound)
{
if ((upperbound < 1)) {
return -1;
}
return ((unsigned)(rand()%((int)(upperbound-lowerbound+1))-((int)(lowerbound-1))));
}
static int chkmonchan (const void *key1, const void *key2)
{
char *chan = (char *)key1;
char *chk = (char *)key2;
return (strcasecmp(chan, chk));
}
int is_monchan(char* chan)
{
if (list_find(monchans, chan, chkmonchan)) {
return(1);
}
return(0);
}
static Chans *GetRandomChan()
{
hscan_t cs;
hnode_t *cn;
int randno, curno;
curno = 0;
randno = hrand(hash_count(ch), 1);
if (randno == -1) {
return NULL;
}
hash_scan_begin(&cs, ch);
while ((cn = hash_scan_next(&cs)) != NULL) {
if (curno == randno) {
return((Chans *)hnode_get(cn));
}
curno++;
}
nlog(LOG_WARNING, LOG_MOD, "GetRandomChan() ran out of channels?");
return NULL;
}
static Chans * GetNewChan ()
{
Chans *c;
int i;
for(i = 0; i < 5; i++) {
c = GetRandomChan();
if (c != NULL) {
nlog(LOG_DEBUG1, LOG_MOD, "Random Chan is %s", c->name);
/* if channel is private and setting is enabled, don't join */
if ((SecureServ.doprivchan == 0) && (is_priv_chan(c))) {
nlog(LOG_DEBUG1, LOG_MOD, "Not Scanning %s, as its a private channel", c->name);
continue;
}
if (!strcasecmp(me.chan, c->name)) {
/* this was the last channel we joined, don't join it again */
nlog(LOG_DEBUG1, LOG_MOD, "Not Scanning %s, as this is the services channel", c->name);
continue;
}
if (!strcasecmp(SecureServ.lastchan, c->name)) {
/* this was the last channel we joined, don't join it again */
nlog(LOG_DEBUG1, LOG_MOD, "Not Scanning %s, as we just did it", c->name);
continue;
}
/* if the channel is exempt, restart */
if (SS_IsChanExempt(c) > 0) {
continue;
}
/* if we are already monitoring with a monbot, don't join */
if (is_monchan(c->name)) {
nlog(LOG_DEBUG1, LOG_MOD, "Not Scanning %s as we are monitoring it with a monbot",c->name);
continue;
}
return(c);
} else {
/* hu? */
nlog(LOG_DEBUG1, LOG_MOD, "Hu? Couldn't find a channel");
SecureServ.lastchan[0] = 0;
SecureServ.lastnick[0] = 0;
return NULL;
}
}
/* give up after 5 attempts */
nlog(LOG_DEBUG1, LOG_MOD, "Couldn't find a fresh Channel, Giving up");
SecureServ.lastchan[0] = 0;
SecureServ.lastnick[0] = 0;
return NULL;
}
static randomnicks * GetNewBot(int resetflag)
{
randomnicks *nickname = NULL;
lnode_t *rnn;
int randno, curno, i;
if(list_count(nicks) == 0) {
/* No bots available */
nlog(LOG_DEBUG1, LOG_MOD, "No bots available, giving up");
return NULL;
}
if(list_count(nicks) == 1) {
/* If only one bot, no need for random (which crashes with 1 anyway)
* so just return the single bot */
rnn = list_first(nicks);
if(rnn != NULL) {
nickname = lnode_get(rnn);
/* make sure no one is online with this nickname */
if (finduser(nickname->nick) != NULL) {
nlog(LOG_DEBUG1, LOG_MOD, "%s is online, can't use that nick", nickname->nick);
return NULL;
}
nlog(LOG_DEBUG1, LOG_MOD, "RandomNick is %s", nickname->nick);
return nickname;
}
return NULL;
}
for(i = 0; i < 5; i++) {
curno = 1;
randno = hrand(list_count(nicks)-1, 0 );
rnn = list_first(nicks);
while (rnn != NULL) {
if (curno == randno) {
nickname = lnode_get(rnn);
if (!strcasecmp(nickname->nick, SecureServ.lastnick)) {
/* its the same as last time, nope */
nlog(LOG_DEBUG1, LOG_MOD, "%s was used last time. Retring", nickname->nick);
break;
}
/* make sure no one is online with this nickname */
if (finduser(nickname->nick) != NULL) {
nlog(LOG_DEBUG1, LOG_MOD, "%s is online, can't use that nick, retring", nickname->nick);
break;
}
nlog(LOG_DEBUG1, LOG_MOD, "RandomNick is %s", nickname->nick);
return nickname;
}
curno++;
rnn = list_next(nicks, rnn);
}
}
/* give up if we try five times */
nlog(LOG_DEBUG1, LOG_MOD, "Couldn't find a free nickname, giving up");
if(resetflag) {
SecureServ.lastchan[0] = 0;
SecureServ.lastnick[0] = 0;
}
return NULL;
}
void MonBotCycle()
{
lnode_t *mcnode;
Chans *c;
char *chan;
/* cycle one of hte monchans, if configured to */
if (SecureServ.monbot[0] == 0) {
return;
}
if (SecureServ.monchancycle > 0) {
/* this is broken, so lets just do something simple for the meantime */
#if 0
if (lastmonchan == NULL) {
/* its brand new */
mcnode = list_first(monchans);
} else {
mcnode = list_next(monchans, lastmonchan);
if (mcnode == NULL) {
/* we have moved through all teh chans, start from scratch */
mcnode = list_first(monchans);
}
}
if (mcnode == NULL) {
/* No MonChans so abort */
return;
}
/* check the channel is active, if not, just bail out */
if (!findchan(lnode_get(mcnode))) {
return;
}
#else
mcnode = list_first(monchans);
while (mcnode != NULL) {
chan = lnode_get(mcnode);
if (!chan) {
nlog(LOG_WARNING, LOG_MOD, "MonChans has a empty node?");
mcnode = list_next(monchans, mcnode);
continue;
}
c = findchan(chan);
if (!c) {
/* channel isn't online atm, ignore */
mcnode = list_next(monchans, mcnode);
continue;
}
if (IsChanMember(c, finduser(SecureServ.monbot))) {
spart_cmd(SecureServ.monbot, c->name);
}
join_bot_to_chan(SecureServ.monbot, c->name, 0);
mcnode = list_next(monchans, mcnode);
}
#endif
}
}
void JoinNewChan()
{
Chans *c;
randomnicks *nickname = NULL;
SET_SEGV_LOCATION();
/* first, if the lastchan and last nick are not empty, it means one of our bots is in a chan, sign them off */
if (SecureServ.lastnick[0] != 0) {
if (finduser(SecureServ.lastnick)) {
if (SecureServ.lastchan[0] != 0) {
spart_cmd(SecureServ.lastnick, SecureServ.lastchan);
}
del_bot(SecureServ.lastnick, "Finished Scanning");
SecureServ.lastchan[0] = 0;
SecureServ.lastnick[0] = 0;
}
}
/* restore segvinmodules */
SET_SEGV_INMODULE("SecureServ");
/* if we don't do OnJoin Checking, Don't go any further */
if (SecureServ.DoOnJoin < 1)
return;
if (list_count(nicks) < 1) {
/* just broadcast a error every time we try, till a admin either turns of Onjoin checking, or adds a few bots */
chanalert(s_SecureServ, "Warning!!! BotList is empty. We cant do OnJoin Checking. Add a few bots via ./msg %s bots command", s_SecureServ);
return;
}
c = GetNewChan ();
if (c == NULL) {
return;
}
strlcpy(SecureServ.lastchan, c->name, CHANLEN);
nickname = GetNewBot(1);
if(nickname == NULL) {
return;
}
strlcpy(SecureServ.lastnick, nickname->nick, MAXNICK);
/* ok, init the new bot. */
if (init_bot(nickname->nick, nickname->user, nickname->host, nickname->realname, onjoinbot_modes, "SecureServ") == -1) {
/* hu? Nick was in use. How is that possible? */
SecureServ.lastchan[0] = 0;
SecureServ.lastnick[0] = 0;
nlog(LOG_WARNING, LOG_MOD, "init_bot reported nick was in use. How? Dunno");
return;
}
CloakHost(findbot(nickname->nick));
join_bot_to_chan (nickname->nick, c->name, 0);
if (SecureServ.verbose) {
chanalert(me.allbots ? nickname->nick : s_SecureServ, "Scanning %s with %s for OnJoin Viruses", c->name, nickname->nick);
}
}
static int CheckChan(User *u, char *requestchan)
{
Chans *c;
randomnicks *nickname = NULL;
lnode_t *lnode;
User *cm;
SET_SEGV_LOCATION();
c = findchan(requestchan);
if (!c) {
prefmsg(u->nick, s_SecureServ, "Can not find Channel %s, It has to have Some Users!", requestchan);
return -1;
}
/* first, run the channel through the viri list, make sure its not bad */
/* now scan channel members */
lnode = list_first(c->chanmembers);
while (lnode) {
cm = finduser(lnode_get(lnode));
if (cm && ScanChan(cm, c) == 0) {
/* if its 0, means its ok, no need to scan other members */
break;
}
lnode = list_next(c->chanmembers, lnode);
}
nickname = GetNewBot(0);
if(nickname ==NULL) {
prefmsg(u->nick, s_SecureServ, "Couldnt Find a free Nickname to check %s with. Giving up (Try again later)", requestchan);
return -1;
}
/* first, if the lastchan and last nick are not empty, it means one of our bots is in a chan, sign them off */
if (SecureServ.lastchan[0] != 0) {
spart_cmd(SecureServ.lastnick, SecureServ.lastchan);
del_bot(SecureServ.lastnick, "Finished Scanning");
}
/* restore segvinmodules */
SET_SEGV_INMODULE("SecureServ");
strlcpy(SecureServ.lastnick, nickname->nick, MAXNICK);
strlcpy(SecureServ.lastchan, c->name, CHANLEN);
/* ok, init the new bot. */
init_bot(nickname->nick, nickname->user, nickname->host, nickname->realname, onjoinbot_modes, "SecureServ");
CloakHost(findbot(nickname->nick));
join_bot_to_chan (nickname->nick, c->name, 0);
chanalert(me.allbots ? nickname->nick : s_SecureServ, "Scanning %s with %s for OnJoin Viruses by request of %s", c->name, nickname->nick, u->nick);
prefmsg(u->nick, s_SecureServ, "Scanning %s with %s", c->name, nickname->nick);
return 1;
}
void OnJoinBotMsg(User *u, char *botname, char *msg)
{
SET_SEGV_LOCATION();
if (!u) {
return;
}
if (!strncasecmp(msg, "\1version\1", sizeof("\1version\1"))) {
/* its a version request */
nlog(LOG_NORMAL, LOG_MOD, "Received version request from %s to OnJoin Bot %s", u->nick, botname);
notice(u->nick, botname, "\1VERSION %s\1", SecureServ.sampleversion);
return;
}
/* check if this user is exempt */
if (SS_IsUserExempt(u) > 0) {
nlog(LOG_DEBUG1, LOG_MOD, "User %s is exempt from Message Checking", u->nick);
return;
}
nlog(LOG_NORMAL, LOG_MOD, "Received message from %s to OnJoin Bot %s: %s", u->nick, botname, msg);
if (SecureServ.verbose||SecureServ.BotEcho) {
chanalert(me.allbots ? botname : s_SecureServ, "OnJoin Bot %s Received Private Message from %s: %s", botname, u->nick, msg);
}
ScanMsg(u, msg, 0);
}
int CheckOnjoinBotKick(char **argv, int ac)
{
lnode_t *mn;
SET_SEGV_LOCATION();
/* check its one of our nicks */
if (!strcasecmp(SecureServ.lastnick, argv[1]) && (!strcasecmp(SecureServ.lastchan, argv[0]))) {
nlog(LOG_NOTICE, LOG_MOD, "Our Bot %s was kicked from %s", argv[1], argv[0]);
SecureServ.lastchan[0] = 0;
return 1;
}
if (SecureServ.monbot[0] == 0) {
return 0;
}
/* if its our monbot, rejoin the channel! */
if (!strcasecmp(SecureServ.monbot, argv[1])) {
mn = list_first(monchans);
while (mn != NULL) {
if (!strcasecmp(argv[0], lnode_get(mn))) {
/* rejoin the monitor bot to the channel */
join_bot_to_chan (SecureServ.monbot, argv[0], 0);
/* restore segvinmodules */
SET_SEGV_INMODULE("SecureServ");
if (SecureServ.verbose) {
chanalert(s_SecureServ, "%s was kicked out of Monitored Channel %s by %s. Rejoining", argv[1], argv[0], argv[2]);
}
nlog(LOG_NOTICE, LOG_MOD, "%s was kicked out of Monitored Channel %s by %s. Rejoining", argv[1], argv[0], argv[2]);
return 1;
}
mn = list_next(monchans, mn);
}
return 1;
}
return 0;
}
int MonJoin(Chans *c) {
randomnicks *nickname = NULL;
lnode_t *rnn, *mn;
if (SecureServ.monbot[0] == 0) {
return -1;
}
mn = list_first(monchans);
while (mn != NULL) {
if (!strcasecmp(c->name, lnode_get(mn))) {
if (findbot(SecureServ.monbot) == NULL) {
/* the monbot isn't online. Initilze it */
rnn = list_first(nicks);
while (rnn != NULL) {
nickname = lnode_get(rnn);
if (!strcasecmp(nickname->nick, SecureServ.monbot)) {
/* its our bot */
break;
}
rnn = list_next(nicks, rnn);
}
if (rnn != NULL) {
init_bot(nickname->nick, nickname->user, nickname->host, nickname->realname, onjoinbot_modes, "SecureServ");
CloakHost(findbot(nickname->nick));
} else {
nlog(LOG_WARNING, LOG_MOD, "Warning, MonBot %s isn't available!", SecureServ.monbot);
return -1;
}
}
/* restore segvinmodules */
SET_SEGV_INMODULE("SecureServ");
/* if they the monbot is not a member of the channel, join it. */
if (!IsChanMember(c, finduser(SecureServ.monbot))) {
/* join the monitor bot to the new channel */
join_bot_to_chan (SecureServ.monbot, c->name, 0);
/* restore segvinmodules */
SET_SEGV_INMODULE("SecureServ");
}
return 1;
}
mn = list_next(monchans, mn);
}
return 1;
}
int MonBotDelChan(Chans *c)
{
if (c->cur_users != 2) {
return -1;
}
if (SecureServ.monbot[0] == 0) {
return -1;
}
/* really easy way to tell if this is our monitored channel */
if (IsChanMember(c, finduser(SecureServ.monbot))) {
/* yep, its us just part the channel */
spart_cmd(SecureServ.monbot, c->name);
}
return 1;
}
static int MonChan(User *u, char *requestchan)
{
Chans *c;
randomnicks *nickname = NULL;
lnode_t *rnn, *mn;
char *buf;
SET_SEGV_LOCATION();
if (list_isfull(monchans)) {
if (u) prefmsg(u->nick, s_SecureServ, "Can not monitor any additional channels");
nlog(LOG_WARNING, LOG_MOD, "MonChan List is full. Not Monitoring %s", requestchan);
return -1;
}
mn = list_first(monchans);
while (mn != NULL) {
if (!strcasecmp(requestchan, lnode_get(mn))) {
if (u) prefmsg(u->nick, s_SecureServ, "Already Monitoring Channel %s", requestchan);
return 1;
}
mn = list_next(monchans, mn);
}
c = findchan(requestchan);
if (!c) {
if (u) prefmsg(u->nick, s_SecureServ, "Can not find Channel %s, It has to have Some Users!", requestchan);
return -1;
}
/* dont allow excepted channels */
if (SS_IsChanExempt(c) > 0) {
if (u) prefmsg(u->nick, s_SecureServ, "Can not monitor a channel listed as a Exempt Channel");
return -1;
}
if (SecureServ.monbot[0] == 0) {
if (u) prefmsg(u->nick, s_SecureServ, "Warning, No Monitor Bot set. /msg %s help set", s_SecureServ);
return -1;
}
if (IsChanMember(c, finduser(SecureServ.monbot))) {
if (u) prefmsg(u->nick, s_SecureServ, "Already Monitoring %s", (char*)lnode_get(rnn));
return -1;
}
if (findbot(SecureServ.monbot) == NULL) {
/* the monbot isn't online. Initilze it */
rnn = list_first(nicks);
while (rnn != NULL) {
nickname = lnode_get(rnn);
if (!strcasecmp(nickname->nick, SecureServ.monbot)) {
/* its the same as last time, nope */
break;
}
rnn = list_next(nicks, rnn);
}
if (rnn != NULL) {
init_bot(nickname->nick, nickname->user, nickname->host, nickname->realname, onjoinbot_modes, "SecureServ");
CloakHost(findbot(nickname->nick));
} else {
nlog(LOG_WARNING, LOG_MOD, "Warning, MonBot %s isn't available!", SecureServ.monbot);
return -1;
}
}
/* restore segvinmodules */
SET_SEGV_INMODULE("SecureServ");
/* append it to the list */
buf = malloc(CHANLEN);
strlcpy(buf, requestchan, CHANLEN);
rnn = lnode_create(buf);
list_append(monchans, rnn);
/* join the monitor bot to the new channel */
join_bot_to_chan (SecureServ.monbot, c->name, 0);
/* restore segvinmodules */
SET_SEGV_INMODULE("SecureServ");
if (SecureServ.verbose) chanalert(me.allbots ? SecureServ.monbot : s_SecureServ, "Monitoring %s with %s for Viruses by request of %s", c->name, SecureServ.monbot, u ? u->nick : s_SecureServ);
if (u) prefmsg(u->nick, s_SecureServ, "Monitoring %s with %s", c->name, SecureServ.monbot);
return 1;
}
static int StopMon(User *u, char *chan)
{
lnode_t *node, *node2;
int ok = 0;
SET_SEGV_LOCATION();
node = list_first(monchans);
while (node != NULL) {
node2 = list_next(monchans, node);
if (!strcasecmp(chan, lnode_get(node))) {
list_delete(monchans, node);
prefmsg(u->nick, s_SecureServ, "Deleted %s out of Monitored Channels List.", (char*)lnode_get(node));
spart_cmd(SecureServ.monbot, lnode_get(node));
free(lnode_get(node));
lnode_destroy(node);
ok = 1;
}
node = node2;
}
if (ok == 1) {
SaveMonChans();
} else {
prefmsg(u->nick, s_SecureServ, "Couldn't find Channel %s in Monitored Channel list", chan);
}
return 1;
}
int ListMonChan(User *u)
{
lnode_t *node;
SET_SEGV_LOCATION();
prefmsg(u->nick, s_SecureServ, "Monitored Channels List (%d):", (int)list_count(monchans)); node = list_first(monchans);
node = list_first(monchans);
while (node != NULL) {
prefmsg(u->nick, s_SecureServ, "%s", (char*)lnode_get(node));
node = list_next(monchans, node);
}
prefmsg(u->nick, s_SecureServ, "End of List");
return 1;
}
int LoadMonChans()
{
int i;
char **chan;
SET_SEGV_LOCATION();
monchans = list_create(20);
if (GetDir("MonChans", &chan) > 0) {
for (i = 0; chan[i] != NULL; i++) {
MonChan(NULL, chan[i]);
}
}
free(chan);
lastmonchan = NULL;
return 1;
}
int SaveMonChans()
{
lnode_t *node;
char buf[CONFBUFSIZE];
SET_SEGV_LOCATION();
DelConf("MonChans");
node = list_first(monchans);
while (node != NULL) {
ircsnprintf(buf, CONFBUFSIZE, "MonChans/%s", (char *)lnode_get(node));
SetConf((void *)1, CFGINT, buf);
node = list_next(monchans, node);
}
return 1;
}
int MonChanCount(void)
{
return (list_count(monchans));
}
int OnJoinBotConf(void)
{
randomnicks *rnicks;
lnode_t *node;
int i;
char **data;
char *tmp;
SET_SEGV_LOCATION();
/* get Random Nicknames */
if (GetDir("RandomNicks", &data) > 0) {
/* try */
for (i = 0; data[i] != NULL; i++) {
rnicks = malloc(sizeof(randomnicks));
strlcpy(rnicks->nick, data[i], MAXNICK);
ircsnprintf(confbuf, CONFBUFSIZE, "RandomNicks/%s/User", data[i]);
if (GetConf((void *)&tmp, CFGSTR, confbuf) <= 0) {
free(rnicks);
continue;
} else {
strlcpy(rnicks->user, tmp, MAXUSER);
free(tmp);
}
ircsnprintf(confbuf, CONFBUFSIZE, "RandomNicks/%s/Host", data[i]);
if (GetConf((void *)&tmp, CFGSTR, confbuf) <= 0) {
free(rnicks);
continue;
} else {
strlcpy(rnicks->host, tmp, MAXHOST);
free(tmp);
}
ircsnprintf(confbuf, CONFBUFSIZE, "RandomNicks/%s/RealName", data[i]);
if (GetConf((void *)&tmp, CFGSTR, confbuf) <= 0) {
free(rnicks);
continue;
} else {
strlcpy(rnicks->realname, tmp, MAXREALNAME);
free(tmp);
}
nlog(LOG_DEBUG2, LOG_MOD, "Adding Random Nick %s!%s@%s with RealName %s", rnicks->nick, rnicks->user, rnicks->host, rnicks->realname);
node = lnode_create(rnicks);
list_prepend(nicks, node);
}
}
if (GetConf((void *)&tmp, CFGSTR, "MonBot") <= 0) {
SecureServ.monbot[0] = '\0';
} else {
node = list_first(nicks);
while (node != NULL) {
rnicks = lnode_get(node);
if (!strcasecmp(rnicks->nick, tmp)) {
/* ok, got the bot ! */
break;
}
node = list_next(nicks, node);
}
if (node != NULL) {
strlcpy(SecureServ.monbot, tmp, MAXNICK);
} else {
SecureServ.monbot[0] = '\0';
nlog(LOG_DEBUG2, LOG_MOD, "Warning, Cant find nick %s in random bot list for monbot", tmp);
}
free(tmp);
}
return 1;
}
int InitOnJoinBots(void)
{
SET_SEGV_LOCATION();
/* init the random nicks list */
nicks = list_create(MAX_NICKS);
/* init CTCP version response */
strlcpy(SecureServ.sampleversion, DEFAULT_VERSION_RESPONSE, SS_BUF_SIZE);
OnJoinBotConf();
return 1;
}
int ExitOnJoinBots(void)
{
SET_SEGV_LOCATION();
if (finduser(SecureServ.lastnick)) {
chanalert(s_SecureServ, "SecureServ is unloading, OnJoinBot %s leaving", SecureServ.lastnick);
if (SecureServ.lastchan[0] != 0) {
spart_cmd(SecureServ.lastnick, SecureServ.lastchan);
}
del_bot(SecureServ.lastnick, SecureServ.botquitmsg);
SecureServ.lastchan[0] = 0;
SecureServ.lastnick[0] = 0;
}
if (SecureServ.monbot[0] != 0) {
chanalert(s_SecureServ, "SecureServ is unloading, monitor bot %s leaving", SecureServ.monbot);
del_bot(SecureServ.monbot, SecureServ.botquitmsg);
return -1;
}
return 1;
}
int do_bots(User* u, char **argv, int argc)
{
int i;
lnode_t *node;
randomnicks *bots;
char *buf, *buf2;
SET_SEGV_LOCATION();
if (!strcasecmp(argv[2], "LIST")) {
node = list_first(nicks);
i = 1;
prefmsg(u->nick, s_SecureServ, "Bot List:");
while (node) {
bots = lnode_get(node);
prefmsg(u->nick, s_SecureServ, "%d) %s (%s@%s) - %s", i, bots->nick, bots->user, bots->host, bots->realname);
++i;
node = list_next(nicks, node);
}
prefmsg(u->nick, s_SecureServ, "End of List.");
chanalert(s_SecureServ, "%s requested Bot List", u->nick);
} else if (!strcasecmp(argv[2], "ADD")) {
if (argc < 7) {
prefmsg(u->nick, s_SecureServ, "Syntax Error. /msg %s help bots", s_SecureServ);
return 0;
}
if (list_isfull(nicks)) {
prefmsg(u->nick, s_SecureServ, "Error, Bot list is full");
return 0;
}
buf = malloc(CONFBUFSIZE);
ircsnprintf(buf, CONFBUFSIZE, "RandomNicks/%s/User", argv[3]);
SetConf((void *)argv[4], CFGSTR, buf);
ircsnprintf(buf, CONFBUFSIZE, "RandomNicks/%s/Host", argv[3]);
SetConf((void *)argv[5], CFGSTR, buf);
ircsnprintf(buf, CONFBUFSIZE, "RandomNicks/%s/RealName", argv[3]);
buf2 = joinbuf(argv, argc, 6);
SetConf((void *)buf2, CFGSTR, buf);
free(buf);
bots = malloc(sizeof(randomnicks));
strlcpy(bots->nick, argv[3], MAXNICK);
strlcpy(bots->user, argv[4], MAXUSER);
strlcpy(bots->host, argv[5], MAXHOST);
strlcpy(bots->realname, buf2, MAXREALNAME);
free(buf2);
node = lnode_create(bots);
list_append(nicks, node);
prefmsg(u->nick, s_SecureServ, "Added %s (%s@%s - %s) Bot to Bot list", bots->nick, bots->user, bots->host, bots->realname);
chanalert(s_SecureServ, "%s added %s (%s@%s - %s) Bot to Bot list", u->nick, bots->nick, bots->user, bots->host, bots->realname);
return 1;
} else if (!strcasecmp(argv[2], "DEL")) {
if (argc < 4) {
prefmsg(u->nick, s_SecureServ, "Syntax Error. /msg %s help bots", s_SecureServ);
return 0;
}
if (atoi(argv[3]) != 0) {
node = list_first(nicks);
i = 1;
while (node) {
if (i == atoi(argv[3])) {
/* delete the entry */
bots = lnode_get(node);
/* dont delete the bot if its setup as the monbot */
if (!strcasecmp(bots->nick, SecureServ.monbot)) {
prefmsg(u->nick, s_SecureServ, "Cant delete %s from botlist as its set as the monitor Bot", bots->nick);
return -1;
}
/* don't delete the bot if its online! */
if (findbot(bots->nick)) {
prefmsg(u->nick, s_SecureServ, "Can't delete %s from botlist as its online at the moment", bots->nick);
return -1;
}
list_delete(nicks, node);
buf = malloc(CONFBUFSIZE);
ircsnprintf(buf, CONFBUFSIZE, "RandomNicks/%s", bots->nick);
DelConf(buf);
free(buf);
prefmsg(u->nick, s_SecureServ, "Deleted %s out of Bot list", bots->nick);
chanalert(s_SecureServ, "%s deleted %s out of bot list", u->nick, bots->nick);
lnode_destroy(node);
free(bots);
return 1;
}
++i;
node = list_next(nicks, node);
}
/* if we get here, then we can't find the entry */
prefmsg(u->nick, s_SecureServ, "Error, Can't find entry %d. /msg %s bots list", atoi(argv[3]), s_SecureServ);
return 0;
} else {
prefmsg(u->nick, s_SecureServ, "Error, Out of Range");
return 0;
}
} else {
prefmsg(u->nick, s_SecureServ, "Syntax Error. /msg %s help bots", s_SecureServ);
return 0;
}
return 0;
}
int do_checkchan(User* u, char **argv, int argc)
{
SET_SEGV_LOCATION();
CheckChan(u, argv[2]);
return 1;
}
int do_monchan(User* u, char **argv, int argc)
{
SET_SEGV_LOCATION();
if (!strcasecmp(argv[2], "ADD")) {
if (argc < 4) {
prefmsg(u->nick, s_SecureServ, "Syntax Error. /msg %s help monchan", s_SecureServ);
return -1;
}
MonChan(u, argv[3]);
/* dont save in MonChan, as thats also called by LoadChan */
SaveMonChans();
} else if (!strcasecmp(argv[2], "DEL")) {
if (argc < 4) {
prefmsg(u->nick, s_SecureServ, "Syntax Error. /msg %s help monchan", s_SecureServ);
return -1;
}
StopMon(u, argv[3]);
} else if (!strcasecmp(argv[2], "LIST")) {
ListMonChan(u);
} else {
prefmsg(u->nick, s_SecureServ, "Syntax Error. /msg %s help monchan", s_SecureServ);
}
return 1;
}
int do_cycle(User* u, char **argv, int argc)
{
SET_SEGV_LOCATION();
JoinNewChan();
return 1;
}
int do_set_monbot(User* u, char **av, int ac)
{
/* this is ok, its just to shut up fussy compilers */
randomnicks *nickname = NULL;
lnode_t *rnn;
SET_SEGV_LOCATION();
if (!strcasecmp(av[2], "LIST")) {
prefmsg(u->nick, s_SecureServ, "MONBOT: %s", (strlen(SecureServ.monbot) > 0) ? SecureServ.monbot : "Not Set");
return 1;
}
if (ac < 4) {
prefmsg(u->nick, s_SecureServ, "Invalid Syntax. /msg %s help set for more info", s_SecureServ);
return 1;
}
/* Do not allow overwrite of the monbot if one is already
* assigned and we have monchans.
*/
if(SecureServ.monbot[0] != 0 && MonChanCount() > 1) {
prefmsg(u->nick, s_SecureServ, "Monitor bot already set to %s and is monitoring channels.", SecureServ.monbot);
return 1;
}
/* don't allow a monitor bot to be assigned if we don't have enough onjoin bots */
if (list_count(nicks) <= 2) {
prefmsg(u->nick, s_SecureServ, "Not enough Onjoin bots would be left if you assign a MonBot. Please create more Onjoin Bots");
return 1;
}
rnn = list_first(nicks);
while (rnn != NULL) {
nickname = lnode_get(rnn);
if (!strcasecmp(nickname->nick, av[3])) {
/* ok, got the bot ! */
break;
}
rnn = list_next(nicks, rnn);
}
if (rnn != NULL) {
/* Do not allow monbot to be assigned if its online as a Onjoin bot atm */
if (finduser(nickname->nick)) {
prefmsg(u->nick, s_SecureServ, "Can not assign a Monitor Bot while it is online as a Onjoin Bot. Please try again in a couple of minutes");
return 1;
}
SetConf((void *)av[3], CFGSTR, "MonBot");
strlcpy(SecureServ.monbot, nickname->nick, MAXNICK);
prefmsg(u->nick, s_SecureServ, "Monitoring Bot set to %s", av[3]);
chanalert(s_SecureServ, "%s set the Monitor bot to %s", u->nick, av[3]);
return 1;
}
prefmsg(u->nick, s_SecureServ, "Can't find Bot %s in bot list. /msg %s bot list for Bot List", av[3], s_SecureServ);
return 1;
}
int CheckMonBotKill(char* nick)
{
randomnicks *nickname = NULL;
lnode_t *rnn;
lnode_t *mcnode;
Chans *c;
char *chan;
if (SecureServ.monbot[0] == 0) {
return 0;
}
if (strcasecmp(nick, SecureServ.monbot)) {
return 0;
}
rnn = list_first(nicks);
while (rnn != NULL) {
nickname = lnode_get(rnn);
if (!strcasecmp(nickname->nick, SecureServ.monbot)) {
/* its our bot */
break;
}
rnn = list_next(nicks, rnn);
}
if (rnn != NULL) {
init_bot(nickname->nick, nickname->user, nickname->host, nickname->realname, onjoinbot_modes, "SecureServ");
CloakHost(findbot(nickname->nick));
} else {
nlog(LOG_WARNING, LOG_MOD, "Warning, MonBot %s isn't available!", SecureServ.monbot);
return -1;
}
/* restore segvinmodules */
SET_SEGV_INMODULE("SecureServ");
mcnode = list_first(monchans);
while (mcnode != NULL) {
chan = lnode_get(mcnode);
if (!chan) {
nlog(LOG_WARNING, LOG_MOD, "MonChans has a empty node?");
mcnode = list_next(monchans, mcnode);
continue;
}
c = findchan(chan);
if (!c) {
/* channel isn't online atm, ignore */
mcnode = list_next(monchans, mcnode);
continue;
}
join_bot_to_chan(SecureServ.monbot, c->name, 0);
mcnode = list_next(monchans, mcnode);
}
return 1;
}
void OnJoinDelChan(Chans* c)
{
SET_SEGV_LOCATION();
if (c->cur_users != 2) {
return;
}
/* first, if the lastchan and last nick are not empty, it means one of our bots is in a chan, sign them off */
if (SecureServ.lastnick[0] != 0 && SecureServ.lastchan[0] != 0) {
if (finduser(SecureServ.lastnick)) {
if (strcasecmp(SecureServ.lastchan, c->name) == 0) {
spart_cmd(SecureServ.lastnick, SecureServ.lastchan);
del_bot(SecureServ.lastnick, "Finished Scanning");
SecureServ.lastchan[0] = 0;
SecureServ.lastnick[0] = 0;
}
}
}
}