summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/Makefile.am1
-rw-r--r--docs/botnet.txt316
-rw-r--r--src/irc/bot/Makefile.am32
-rw-r--r--src/irc/bot/bot-events.c201
-rw-r--r--src/irc/bot/bot-irc-commands.c164
-rw-r--r--src/irc/bot/bot-users.c579
-rw-r--r--src/irc/bot/bot-users.h56
-rw-r--r--src/irc/bot/bot.c52
-rw-r--r--src/irc/bot/bot.h26
-rw-r--r--src/irc/bot/botnet-connection.c592
-rw-r--r--src/irc/bot/botnet-users.c219
-rw-r--r--src/irc/bot/botnet-users.h13
-rw-r--r--src/irc/bot/botnet.c827
-rw-r--r--src/irc/bot/botnet.h134
-rw-r--r--src/irc/bot/botnets.sample15
-rw-r--r--src/irc/bot/module.h3
-rw-r--r--src/irc/bot/users.sample18
17 files changed, 0 insertions, 3248 deletions
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 8541ef1d..5e222564 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -4,7 +4,6 @@ man_MANS = \
irssi.1
doc_DATA = \
- botnet.txt \
design.txt \
formats.txt \
manual.txt \
diff --git a/docs/botnet.txt b/docs/botnet.txt
deleted file mode 100644
index 8b5f9ba7..00000000
--- a/docs/botnet.txt
+++ /dev/null
@@ -1,316 +0,0 @@
-
- Irssi's botnet description
-
- Copyright (c) 1999-2000 Timo Sirainen
-
-
- 0. History
-
- draft v0.1 : 21.8.1999
-
- Just a first draft of my botnet design I did on a boring friday
- work afternoon :) I'll try to implement this to irssi some day, it
- feels pretty interesting now so it might be pretty soon even. Any
- comments are welcome :)
-
- draft v0.2 : 21.11.1999
-
- Exactly three months since the first draft :) Now I actually have
- some code done, just committed pretty simple botnet to irssi CVS.
- Made several changes to this document.. Still missing much details
- but the basic idea should be clear.
-
- draft v0.3 : 21.05.2000
-
- Strange, again the same day. I really didn't plan this :)
- Reformatted the text, added lots of text, implemented more of the
- stuff.
-
-
- 1. General
-
- 1.1 Description
-
- A small description of what botnet would do: A group of bots
- efficiently working together to perform their tasks. Like when
- someone's trying to take over your channel, bots will quickly
- decide who deops/kicks whom instead of multiple bots deopping or
- trying to kick the same people.
-
- Irssi's botnet is pretty much based on trust. Some malicious bot
- can quite well mess up the whole botnet. Connecting the bots to
- each other via ssh would be a good idea.
-
- 1.2 Configuration
-
- example config file:
-
- mybotnet =
- {
- priority=5;
- nick=mybot;
- uplinks = (
- { host = "main.botnet.org"; password = "mypass"; },
- { host = "alter.botnet.org"; password = "pass2"; }
- );
- downlinks = (
- { password = "thepass"; valid_addrs = ( "192.168.0.*" ); },
- { password = "blah"; valid_addrs = ( "*.botnet.org" ); },
- { password = "localpass"; valid_addrs = ( "127.*" ); }
- );
- }
-
- When connecting to botnet, the bot first tries to connect to the
- first bot in uplinks list, then the second, etc. Setting port to -1
- will prevent connecting to the bot, 0 uses the default.
-
- 1.3 Botnet master
-
- To avoid total chaos inside botnet, the bots shouldn't do (almost)
- anything without a command from botnet's master. The master should
- know everything, and give commands to clients that can perform the
- task best.
-
- Master is the bot with the highest priority. If there's multiple
- with the same priority, the one that already was the master will
- stay master. When joining two botnets to one, the uplink's master
- stays. If link to master breaks, the closest bot to it will choose
- a new one.
-
- The priorities should be given so that the bots that have the
- fastest connections and are in the middle of the botnet have the
- highest priorities.
-
- 1.4 Command format
-
- Commands that are sent inside botnet are in the following format:
-
- <from_nick> <to_nick> COMMAND [command specific data..]
-
- If to_nick is '-', the command should be sent to everyone.
-
-
- 2. Handshake
-
- First host checks from bots' valid_addrs who is connecting. If
- there's no matches it just disconnects the client.
-
- CLIENT: PASS <password>
- HOST : (if error, disconnect)
-
- CLIENT: NICK <nick>
- HOST : NICKERROR | CONNECTED
-
- If nick is already in use, the host sends NICKERROR and waits for
- new nick.
-
- Now we're connected to botnet. The commands from now on use the
- format specified in section 1.4.
-
- Both the client and the host sends information to other side of
- all the clients they serve (if any):
-
- BOTINFO <nick> <connected_to_nick> <priority>
-
- BOTINFOs must be sent sorted so that connected_to_nick bot is
- always known. Like first comes the bots connected to the
- host/client, then the bots connected to them etc.
-
- If the client had downlinks, nick collisions might happen. The
- uplink is responsible for noticing them from BOTINFO commands.
- It should automatically replace the nicks with new ones and
- send nick change command to client and all it's downlinks. For
- example if host received:
-
- BOTINFO bot highbot 10
-
- And the bot already exists, the BOTINFO is changed to:
-
- BOTINFO bot2 highbot 10
-
- And the client and it's downlinks are notified:
-
- BOTNICK bot2 bot
-
- After sending BOTINFOs, the host tells the current master:
-
- MASTER <nick>
-
- The client now checks if it's priority is higher than the current
- master's. If it is, it will send the MASTER command without any
- parameters.
-
-
- 3. Bot connections
-
- 3.1 General
-
- Everyone's connections should be kept in n-way tree. Example:
-
-
- [highuplink]
- _____________/ | | \
- / | [h5] [h6]
- [h1] | / | \
- / \ | [h7] | [h8]
- [h2] [h3] | | \
- | [uplink] [h9] [h10]
- [h4] / | \
- [up2] | [up1]
- / | | |
- [up3] [up4] | [up5]
- |
- [we]
- / \
- [client1] [client2]
- / \
- [c3] [c4]
-
-
- Botnet should try to keep together even if some hub in the middle
- crashes. Each bot should have at least two uplinks in case one
- dies. For example if [uplink] dies, [we] and [up1] could connect
- to [up2], and [up2] could connect to [highuplink].
-
- When connection is closed to some bot, a notice is sent by the
- bot's uplink:
-
- BOTQUIT <nick>
-
- The quit notice should be sent only about the bot that was
- disconnected. Bots should figure out themselves the other bots and
- remove them too from their lists.
-
- 3.2 Lag
-
- Each bot should send PING commands to their up/downlinks every
- now and then (1min?) to check that the connection is still active.
- If the PONG isn't received in 10 seconds, it's priority should be
- temporarily lowered to -1. If the PONG isn't received in 3
- minutes, the whole connection should be closed.
-
- Master should know lag times of every bots. It could then
- automatically raise/lower bots' priorities depending on how big
- their lag is. Master could also lower it's own priority and pass
- the master status to someone else with lower lag.
-
- If there's lot of lag (>3sec?) somewhere and something urgent
- happens, the botnet could split and behave independently.
-
-
- 4. IRC networks
-
- 4.1 Server connections
-
- When bot is connected to some irc server and is ready to take
- commands, it says:
-
- IRCJOIN <tag> <ircnet> <server> <nick>
-
- Tag is the bot specific unique tag of the server, so that the bot
- can connect multiple times to same IRC network. All IRC related
- commands should specify the server tag where it should be sent.
-
- If bot quits an irc network, it says:
-
- IRCQUIT <tag>
-
- 4.2 IRC commands
-
- Master asks a bot to send some command to IRC server by saying:
-
- CMD <id> <tag> <command>
-
- <command> can't really be anything, since the bot should also be
- able to reply to it. The <id> is for identifying the command/reply
- pair. Master should keep the command in memory until it receives
- the reply:
-
- CMDREPLY <id> <last> <reply>
-
- The command could get a reply of multiple lines, so <last>
- specifies if the reply is the last line (1 or 0).
-
- If the command failed for some reason, the bot will reply with
-
- CMDFAIL <id>
-
- and master should send the command to some other bot.
-
- 4.3 Channels
-
- When joined/left channels, the bot says:
-
- CHANJOIN <tag> <channel>
- CHANPART <tag> <channel>
-
- After BOTJOIN, master tries to op the bot. When bot receives +o,
- it says:
-
- CHANOP <tag> <channel>
-
- If it is the first opped bot in channel, master orders the bot to
- op the rest of the bots.
-
- If the bot is kicked, it says:
-
- CHANKICK <tag> <channel>
-
- When master notices that bot is kicked, it first checks if there's
- any other opped bots in channel. If not, it waits for a random
- pause, 5-10sec before letting the bot join the channel again so
- that it won't get autorejoin ban.
-
- If bot can't join channel, it says:
-
- CHANBANNED <tag> <channel>
- (or)
- CHANCANTJOIN <tag> <channel>
-
- When received BOTBANNED, master tries to unban bot or set a ban
- exception. BOTCANTJOIN results as invite to channel.
-
- 4.4 Channel information
-
- When master notices that bot is the first one joined to channel,
- it asks the bot for some channel information:
-
- CMD <id> <tag> NAMES <channel>
- CMD <id> <tag> WHO <channel>
- CMD <id> <tag> MODE <channel>
- CMD <id> <tag> MODE b <channel>
- CMD <id> <tag> MODE e <channel> (if IRC network supports this)
- CMD <id> <tag> MODE I <channel> (if IRC network supports this)
-
- It's also possible that if several bots join immediately after the
- first bot, the commands are shared between all the bots.
-
- Bots should cache the information as much as possible, at least
- NAMES command.
-
- 4.5 Channel priorities
-
- Every channel has a priority: LOW, NORMAL, HIGH.
-
- Normally LOW operates just as NORMAL channels, except when some
- channel has HIGH priority and bots are really busy, LOW channels
- just wait until there's time for them.
-
- In NORMAL channels, the most urgent operations (kicks, ops, deops)
- are performed quite soon even while bots are busy handling HIGH
- priority commands.
-
- Channels shouldn't normally be HIGH priority, but if attack
- against channel is detected (like someone comes from split, gets
- ops and gets to op someone else), it's priority is set to HIGH.
- When channel's priority is HIGH, botnet does everything it can to
- get rid of unauthorized opped people as fast as possible.
-
- LOW channel's priority can also be raised to HIGH, but it's
- priority is dropped back to LOW if some NORMAL channel's priority
- is raised to HIGH too.
-
- Master notifies about channel's priority change by saying:
-
- CHANPRIORITY <ircnet> <channel> <LOW/NORMAL/HIGH>
-
diff --git a/src/irc/bot/Makefile.am b/src/irc/bot/Makefile.am
deleted file mode 100644
index a97abf07..00000000
--- a/src/irc/bot/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
-moduledir = $(libdir)/irssi/modules
-module_LTLIBRARIES = libirc_bot.la
-
-libirc_bot_la_LDFLAGS = -avoid-version
-
-INCLUDES = \
- -I$(top_srcdir)/src \
- -I$(top_srcdir)/src/core/ \
- -I$(top_srcdir)/src/irc/core/ \
- $(GLIB_CFLAGS)
-
-libirc_bot_la_LIBADD = -lcrypt
-
-libirc_bot_la_SOURCES = \
- bot.c \
- bot-irc-commands.c \
- bot-events.c \
- bot-users.c \
- botnet.c \
- botnet-connection.c \
- botnet-users.c
-
-noinst_HEADERS = \
- bot.h \
- bot-users.h \
- botnet.h \
- botnet-users.h \
- module.h
-
-EXTRA_DIST = \
- users.sample \
- botnets.sample
diff --git a/src/irc/bot/bot-events.c b/src/irc/bot/bot-events.c
deleted file mode 100644
index 9ef646de..00000000
--- a/src/irc/bot/bot-events.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- bot-events.c : IRC bot plugin for irssi
-
- Copyright (C) 1999 Timo Sirainen
-
- 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "module.h"
-#include "signals.h"
-#include "commands.h"
-
-#include "irc.h"
-#include "irc-servers.h"
-#include "irc-channels.h"
-#include "nicklist.h"
-#include "modes.h"
-#include "netsplit.h"
-
-#include "bot-users.h"
-
-static int get_flags(USER_REC *user, IRC_CHANNEL_REC *channel)
-{
- USER_CHAN_REC *userchan;
-
- g_return_val_if_fail(user != NULL, 0);
- g_return_val_if_fail(channel != NULL, 0);
-
- userchan = g_hash_table_lookup(user->channels, channel->name);
- return (user->flags | (userchan == NULL ? 0 : userchan->flags)) &
- (~user->not_flags);
-}
-
-static void event_massjoin(IRC_CHANNEL_REC *channel, GSList *users)
-{
- USER_REC *user;
- USER_CHAN_REC *userchan;
- NICK_REC *nick;
- GString *modestr, *nickstr;
- int flags;
-
- g_return_if_fail(channel != NULL);
- g_return_if_fail(users != NULL);
-
- modestr = g_string_new(NULL);
- nickstr = g_string_new(NULL);
-
- for (; users != NULL; users = users->next) {
- user = users->data;
- userchan = g_hash_table_lookup(user->channels, channel->name);
- nick = userchan->nickrec;
-
- flags = get_flags(user, channel);
- if (!nick->op && (flags & USER_AUTO_OP)) {
- g_string_sprintfa(modestr, "+o");
- g_string_sprintfa(nickstr, "%s,", nick->nick);
- }
-
- if (!nick->voice && !nick->op && (flags & USER_AUTO_VOICE)) {
- g_string_sprintfa(modestr, "+v");
- g_string_sprintfa(nickstr, "%s,", nick->nick);
- }
- }
-
- if (nickstr->len > 0) {
- g_string_truncate(nickstr, nickstr->len-1);
- g_string_sprintfa(modestr, " %s", nickstr->str);
-
- channel_set_mode(channel->server, channel->name, modestr->str);
- }
-
- g_string_free(modestr, TRUE);
- g_string_free(nickstr, TRUE);
-}
-
-/* Parse channel mode string */
-static void parse_channel_mode(IRC_CHANNEL_REC *channel, const char *mode,
- const char *nick, const char *address)
-{
- NETSPLIT_CHAN_REC *splitnick;
- NICK_REC *nickrec;
- USER_REC *user;
- GString *str;
- char *ptr, *curmode, type, *dup, *modestr;
- int flags;
-
- g_return_if_fail(channel != NULL);
- g_return_if_fail(nick != NULL);
- g_return_if_fail(mode != NULL);
-
- user = botuser_find(nick, address);
- flags = user == NULL ? 0 : get_flags(user, channel);
-
- if (!channel->chanop || (flags & USER_MASTER) ||
- g_strcasecmp(nick, channel->server->nick) == 0) {
- /* can't do anything or we/master did mode change,
- don't bother checking what */
- return;
- }
-
- /* check if unwanted people got ops */
- str = g_string_new(NULL);
- dup = modestr = g_strdup(mode);
-
- type = '+';
- curmode = cmd_get_param(&modestr);
- for (; *curmode != '\0'; curmode++) {
- if (*curmode == '+' || *curmode == '-') {
- type = *curmode;
- continue;
- }
-
- if (!HAS_MODE_ARG(type, *curmode))
- ptr = NULL;
- else {
- ptr = cmd_get_param(&modestr);
- if (*ptr == '\0') continue;
- }
-
- if (*curmode != 'o')
- continue;
-
- if (type == '-' && strcmp(channel->server->nick, ptr) == 0) {
- /* we aren't chanop anymore .. */
- g_string_truncate(str, 0);
- break;
- }
-
- if (type != '+')
- continue;
-
- /* check that op is valid */
- nickrec = nicklist_find(CHANNEL(channel), ptr);
- if (nickrec == NULL || nickrec->host == NULL)
- continue;
-
- user = botuser_find(ptr, nickrec->host);
- flags = user == NULL ? 0 : get_flags(user, channel);
- if (flags & USER_OP)
- continue;
-
- if (address == NULL) {
- /* server opped, check if user was opped before netsplit. */
- splitnick = netsplit_find_channel(channel->server, nickrec->nick, nickrec->host, channel->name);
- if (splitnick != NULL && splitnick->op)
- continue;
- }
-
- /* this one isn't supposed to get ops! */
- g_string_sprintfa(str, "%s ", ptr);
- }
- g_free(dup);
-
- if (str->len != 0)
- signal_emit("command deop", 3, str->str, channel->server, channel);
- g_string_free(str, TRUE);
-}
-
-static void event_mode(IRC_SERVER_REC *server, const char *data,
- const char *nick, const char *address)
-{
- IRC_CHANNEL_REC *chanrec;
- char *params, *channel, *mode;
-
- g_return_if_fail(data != NULL);
-
- params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &channel, &mode);
-
- if (ischannel(*channel)) {
- /* channel mode change */
- chanrec = irc_channel_find(server, channel);
- if (chanrec != NULL)
- parse_channel_mode(chanrec, mode, nick, address);
- }
-
- g_free(params);
-}
-
-void bot_events_init(void)
-{
- signal_add_last("bot massjoin", (SIGNAL_FUNC) event_massjoin);
- signal_add("event mode", (SIGNAL_FUNC) event_mode);
-}
-
-void bot_events_deinit(void)
-{
- signal_remove("bot massjoin", (SIGNAL_FUNC) event_massjoin);
- signal_remove("event mode", (SIGNAL_FUNC) event_mode);
-}
diff --git a/src/irc/bot/bot-irc-commands.c b/src/irc/bot/bot-irc-commands.c
deleted file mode 100644
index 9ed39acd..00000000
--- a/src/irc/bot/bot-irc-commands.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- bot-irc-commands.c : IRC bot plugin for irssi
-
- Copyright (C) 1999-2000 Timo Sirainen
-
- 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "module.h"
-#include "signals.h"
-#include "commands.h"
-
-#include "irc.h"
-#include "irc-servers.h"
-#include "channels.h"
-#include "nicklist.h"
-#include "irc-masks.h"
-
-#include "bot-users.h"
-#include "botnet-users.h"
-
-static void event_privmsg(IRC_SERVER_REC *server, const char *data,
- const char *nick, const char *address)
-{
- char *params, *target, *msg, *args, *str;
-
- g_return_if_fail(data != NULL);
-
- params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg);
- if (ischannel(*target)) {
- g_free(params);
- return;
- }
-
- /* private message for us */
- str = g_strconcat("bot command ", msg, NULL);
- args = strchr(str+12, ' ');
- if (args != NULL) *args++ = '\0'; else args = "";
-
- g_strdown(str);
- if (signal_emit(str, 4, server, args, nick, address)) {
- /* msg was a command - the msg event. */
- signal_stop();
- }
- g_free(str);
- g_free(params);
-}
-
-static void botcmd_op(IRC_SERVER_REC *server, const char *data,
- const char *nick, const char *address)
-{
- CHANNEL_REC *channel;
- USER_REC *user;
- USER_CHAN_REC *userchan;
- GSList *tmp;
-
- g_return_if_fail(data != NULL);
-
- if (*data == '\0') {
- /* no password given? .. */
- return;
- }
-
- user = botuser_find(nick, address);
- if (user == NULL || (user->not_flags & USER_OP) ||
- !botuser_verify_password(user, data)) {
- /* not found, can't op with this mask or failed password */
- return;
- }
-
- /* find the channels where to op.. */
- for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
- channel = tmp->data;
-
- userchan = g_hash_table_lookup(user->channels, channel->name);
- if ((user->flags & USER_OP) || (userchan->flags & USER_OP))
- signal_emit("command op", 3, nick, server, channel);
- }
-}
-
-static void botcmd_ident(IRC_SERVER_REC *server, const char *data,
- const char *nick, const char *address)
-{
- USER_REC *user;
- char *mask;
-
- g_return_if_fail(data != NULL);
-
- user = botuser_find(nick, address);
- if (user != NULL) {
- /* Already know this host */
- return;
- }
-
- user = botuser_find(nick, NULL);
- if (user == NULL || !botuser_verify_password(user, data)) {
- /* failed password */
- return;
- }
-
- /* add the new mask */
- mask = irc_get_mask(nick, address, IRC_MASK_USER | IRC_MASK_DOMAIN);
- botcmd_user_add_mask(user, mask);
-
- irc_send_cmdv(server, "NOTICE %s :Added new mask %s", nick, mask);
- g_free(mask);
-}
-
-static void botcmd_pass(IRC_SERVER_REC *server, const char *data,
- const char *nick, const char *address)
-{
- USER_REC *user;
- char *params, *pass, *newpass;
-
- g_return_if_fail(data != NULL);
-
- params = event_get_params(data, 2, &pass, &newpass);
-
- user = botuser_find(nick, address);
- if (user == NULL || *pass == '\0') {
- g_free(params);
- return;
- }
-
- if (user->password != NULL &&
- (*newpass == '\0' || !botuser_verify_password(user, pass))) {
- g_free(params);
- return;
- }
-
- /* change the password */
- botcmd_user_set_password(user, user->password == NULL ? pass : newpass);
- irc_send_cmdv(server, "NOTICE %s :Password changed", nick);
-
- g_free(params);
-}
-
-void bot_irc_commands_init(void)
-{
- signal_add("event privmsg", (SIGNAL_FUNC) event_privmsg);
- signal_add_last("bot command op", (SIGNAL_FUNC) botcmd_op);
- signal_add_last("bot command ident", (SIGNAL_FUNC) botcmd_ident);
- signal_add_last("bot command pass", (SIGNAL_FUNC) botcmd_pass);
-}
-
-void bot_irc_commands_deinit(void)
-{
- signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg);
- signal_remove("bot command op", (SIGNAL_FUNC) botcmd_op);
- signal_remove("bot command ident", (SIGNAL_FUNC) botcmd_ident);
- signal_remove("bot command pass", (SIGNAL_FUNC) botcmd_pass);
-}
diff --git a/src/irc/bot/bot-users.c b/src/irc/bot/bot-users.c
deleted file mode 100644
index 35d7b8c8..00000000
--- a/src/irc/bot/bot-users.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- bot-users.c : IRC bot plugin for irssi - user handling
-
- Copyright (C) 1999-2000 Timo Sirainen
-
- 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE /* for crypt() */
-#endif
-
-#include "module.h"
-#include "signals.h"
-#include "misc.h"
-#include "lib-config/iconfig.h"
-
-#include "irc.h"
-#include "irc-servers.h"
-#include "irc-channels.h"
-#include "irc-nicklist.h"
-#include "masks.h"
-
-#include "bot-users.h"
-
-#define WRITE_USERS_INTERVAL (60*15)
-
-static char *user_flags = "oavm"; /* Keep these in the same order as USER_xxx flags */
-
-static CONFIG_REC *userconfig;
-static GHashTable *users;
-
-static int writeusers_tag;
-static time_t last_write;
-
-int botuser_flags2value(const char *flags)
-{
- char *pos;
- int val;
-
- g_return_val_if_fail(flags != NULL, 0);
-
- val = 0;
- while (*flags != '\0') {
- pos = strchr(user_flags, *flags);
- if (pos != NULL)
- val |= 1 << (int) (pos-user_flags);
- flags++;
- }
-
- return val;
-}
-
-char *botuser_value2flags(int value)
-{
- char *str, *p;
- int n;
-
- p = str = g_malloc(USER_FLAG_COUNT+1);
- for (n = 0; n < USER_FLAG_COUNT; n++) {
- if (value & (1 << n))
- *p++ = user_flags[n];
- }
- *p = '\0';
-
- return str;
-}
-
-/* save channel specific user record */
-static void botuser_save_chan(const char *key, USER_CHAN_REC *rec, CONFIG_NODE *node)
-{
- CONFIG_NODE *noderec;
- char *str;
-
- if (rec->flags == 0) {
- /* no flags in this channel - no need to save to config */
- config_node_set_str(userconfig, node, rec->channel, NULL);
- return;
- }
-
- noderec = config_node_section(node, rec->channel, NODE_TYPE_BLOCK);
-
- str = botuser_value2flags(rec->flags);
- config_node_set_str(userconfig, noderec, "flags", str);
- g_free_not_null(str);
-}
-
-static void botuser_config_save(USER_REC *user)
-{
- CONFIG_NODE *node, *subnode, *noderec;
- GSList *tmp;
- char *str;
-
- user->last_modify = time(NULL);
-
- node = config_node_traverse(userconfig, "users", TRUE);
- node = config_node_section(node, user->nick, NODE_TYPE_BLOCK);
-
- str = user->flags == 0 ? NULL :
- botuser_value2flags(user->flags);
- config_node_set_str(userconfig, node, "flags", str);
- g_free_not_null(str);
-
- config_node_set_str(userconfig, node, "password", user->password);
- config_node_set_int(userconfig, node, "last_modify", (int) user->last_modify);
-
- /* Save masks */
- if (user->masks == NULL)
- config_node_set_str(userconfig, node, "masks", NULL);
- else {
- subnode = config_node_section(node, "masks", NODE_TYPE_LIST);
-
- for (tmp = user->masks; tmp != NULL; tmp = tmp->next) {
- USER_MASK_REC *rec = tmp->data;
-
- noderec = config_node_section(subnode, NULL, NODE_TYPE_BLOCK);
- config_node_set_str(userconfig, noderec, "mask", rec->mask);
-
- str = user->flags == 0 ? NULL :
- botuser_value2flags(rec->not_flags);
- config_node_set_str(userconfig, noderec, "not_flags", str);
- g_free_not_null(str);
- }
- }
-
- /* Save channels */
- if (g_hash_table_size(user->channels) == 0)
- config_node_set_str(userconfig, node, "channels", NULL);
- else {
- subnode = config_node_section(node, "channels", NODE_TYPE_LIST);
- g_hash_table_foreach(user->channels, (GHFunc) botuser_save_chan, subnode);
- }
-}
-
-static int botuser_find_mask(USER_REC *user, const char *nick, const char *host)
-{
- GSList *tmp;
-
- g_return_val_if_fail(user != NULL, FALSE);
- g_return_val_if_fail(nick != NULL, FALSE);
- g_return_val_if_fail(host != NULL, FALSE);
-
- /* Check that masks match */
- for (tmp = user->masks; tmp != NULL; tmp = tmp->next) {
- USER_MASK_REC *rec = tmp->data;
-
- if (mask_match_address(NULL, rec->mask, nick, host)) {
- user->not_flags = rec->not_flags;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static USER_MASK_REC *botuser_find_full_mask(USER_REC *user, const char *mask)
-{
- GSList *tmp;
-
- g_return_val_if_fail(user != NULL, FALSE);
- g_return_val_if_fail(mask != NULL, FALSE);
-
- for (tmp = user->masks; tmp != NULL; tmp = tmp->next) {
- USER_MASK_REC *rec = tmp->data;
-
- if (g_strcasecmp(rec->mask, mask) == 0)
- return rec;
- }
-
- return NULL;
-}
-
-static void botuser_getusers_hash(void *key, USER_REC *user, GList **list)
-{
- *list = g_list_append(*list, user);
-}
-
-USER_REC *botuser_find(const char *nick, const char *host)
-{
- USER_REC *user;
- char *stripnick;
- GList *list, *tmp;
-
- g_return_val_if_fail(nick != NULL, NULL);
-
- /* First check for user with same nick */
- stripnick = irc_nick_strip(nick);
- user = g_hash_table_lookup(users, stripnick);
- g_free(stripnick);
-
- if (user != NULL && host != NULL &&
- !botuser_find_mask(user, nick, host)) {
- /* mask didn't match, check for more.. */
- user = NULL;
- }
-
- if (user != NULL || host == NULL)
- return user;
-
- /* Check for different nicks.. */
- list = NULL;
- g_hash_table_foreach(users, (GHFunc) botuser_getusers_hash, &list);
- for (tmp = list; tmp != NULL; tmp = tmp->next) {
- if (botuser_find_mask(tmp->data, nick, host)) {
- user = tmp->data;
- break;
- }
- }
- g_list_free(list);
-
- return user;
-}
-
-USER_REC *botuser_find_rec(CHANNEL_REC *channel, NICK_REC *nick)
-{
- USER_REC *user, *rec;
- USER_CHAN_REC *userchan;
- GList *list, *tmp;
-
- g_return_val_if_fail(channel != NULL, NULL);
- g_return_val_if_fail(nick != NULL, NULL);
-
- user = NULL; list = NULL;
- g_hash_table_foreach(users, (GHFunc) botuser_getusers_hash, &list);
- for (tmp = list; tmp != NULL; tmp = tmp->next) {
- rec = tmp->data;
-
- userchan = g_hash_table_lookup(rec->channels, channel->name);
- if (userchan != NULL && userchan->nickrec == nick) {
- user = rec;
- break;
- }
- }
- g_list_free(list);
-
- return user;
-}
-
-USER_CHAN_REC *botuser_get_channel(USER_REC *user, const char *channel)
-{
- USER_CHAN_REC *rec;
-
- g_return_val_if_fail(user != NULL, NULL);
- g_return_val_if_fail(channel != NULL, NULL);
-
- rec = g_hash_table_lookup(user->channels, channel);
- if (rec != NULL) return rec;
-
- rec = g_new0(USER_CHAN_REC, 1);
- rec->channel = g_strdup(channel);
- g_hash_table_insert(user->channels, rec->channel, rec);
- return rec;
-}
-
-USER_REC *botuser_add(const char *nick)
-{
- USER_REC *user;
-
- /* Add new user */
- user = g_new0(USER_REC, 1);
- user->nick = g_strdup(nick);
- g_hash_table_insert(users, user->nick, user);
-
- botuser_config_save(user);
- return user;
-}
-
-void botuser_set_flags(USER_REC *user, int flags)
-{
- user->flags = flags;
- botuser_config_save(user);
-}
-
-void botuser_set_channel_flags(USER_REC *user, const char *channel, int flags)
-{
- USER_CHAN_REC *rec;
-
- rec = botuser_get_channel(user, channel);
- if (rec != NULL) rec->flags = flags;
-
- botuser_config_save(user);
-}
-
-static USER_MASK_REC *botuser_create_mask(USER_REC *user, const char *mask)
-{
- USER_MASK_REC *rec;
-
- rec = g_new0(USER_MASK_REC, 1);
- rec->mask = g_strdup(mask);
-
- user->masks = g_slist_append(user->masks, rec);
- return rec;
-}
-
-USER_MASK_REC *botuser_add_mask(USER_REC *user, const char *mask)
-{
- USER_MASK_REC *rec;
-
- rec = botuser_create_mask(user, mask);
- botuser_config_save(user);
- return rec;
-}
-
-void botuser_set_mask_notflags(USER_REC *user, const char *mask, int not_flags)
-{
- USER_MASK_REC *rec;
-
- rec = botuser_find_full_mask(user, mask);
- if (rec == NULL) rec = botuser_create_mask(user, mask);
-
- rec->not_flags = not_flags;
- botuser_config_save(user);
-}
-
-void botuser_set_password(USER_REC *user, const char *password)
-{
- char *pass, salt[3];
-
- g_return_if_fail(user != NULL);
- g_return_if_fail(password != NULL);
-
- salt[0] = rand()%20 + 'A';
- salt[1] = rand()%20 + 'A';
- salt[2] = '\0';
- pass = crypt(password, salt);
-
- if (user->password != NULL) g_free(user->password);
- user->password = g_strdup(pass);
- botuser_config_save(user);
-}
-
-int botuser_verify_password(USER_REC *user, const char *password)
-{
- char *pass, salt[3];
-
- g_return_val_if_fail(user != NULL, FALSE);
- g_return_val_if_fail(password != NULL, FALSE);
-
- if (user->password == NULL || strlen(user->password) < 3)
- return FALSE;
-
- salt[0] = user->password[0];
- salt[1] = user->password[1];
- salt[2] = '\0';
- pass = crypt(password, salt);
- return strcmp(user->password, pass) == 0;
-}
-
-void botuser_save(const char *fname)
-{
- config_write(userconfig, fname, 0600);
-}
-
-static void event_massjoin(CHANNEL_REC *channel, GSList *nicks)
-{
- USER_REC *user;
- USER_CHAN_REC *userchan;
- GSList *users;
-
- g_return_if_fail(channel != NULL);
- g_return_if_fail(nicks != NULL);
-
- users = NULL;
- for (; nicks != NULL; nicks = nicks->next) {
- NICK_REC *rec = nicks->data;
-
- user = botuser_find(rec->nick, rec->host);
- if (user != NULL) {
- userchan = botuser_get_channel(user, channel->name);
- userchan->nickrec = rec;
- users = g_slist_append(users, user);
- }
- }
-
- if (users != NULL) {
- signal_emit("bot massjoin", 2, channel, users);
- g_slist_free(users);
- }
-}
-
-/* channel synced - find everyone's NICK_REC's */
-static void sig_channel_sync(CHANNEL_REC *channel)
-{
- USER_REC *user;
- USER_CHAN_REC *userchan;
- GSList *tmp, *nicks;
-
- g_return_if_fail(channel != NULL);
-
- nicks = nicklist_getnicks(channel);
- for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
- NICK_REC *rec = tmp->data;
-
- if (rec->send_massjoin)
- continue; /* This will be checked in "massjoin" signal */
-
- user = botuser_find(rec->nick, rec->host);
- if (user != NULL) {
- userchan = botuser_get_channel(user, channel->name);
- userchan->nickrec = rec;
- }
- }
- g_slist_free(nicks);
-}
-
-/* user left channel - remove from users record */
-static void sig_nicklist_remove(CHANNEL_REC *channel, NICK_REC *nick)
-{
- USER_REC *user;
- USER_CHAN_REC *userchan;
-
- g_return_if_fail(channel != NULL);
- g_return_if_fail(nick != NULL);
-
- user = botuser_find_rec(channel, nick);
- userchan = user == NULL ? NULL :
- g_hash_table_lookup(user->channels, channel->name);
- if (userchan != NULL) userchan->nickrec = NULL;
-}
-
-/* Free memory used by user channel record */
-static void user_destroy_chan(const char *key, USER_CHAN_REC *rec)
-{
- g_free(rec->channel);
- g_free(rec);
-}
-
-static void usermask_destroy(USER_MASK_REC *rec)
-{
- g_free(rec->mask);
- g_free(rec);
-}
-
-/* Free memory used by user record */
-static void user_destroy(const char *key, USER_REC *user)
-{
- g_slist_foreach(user->masks, (GFunc) usermask_destroy, NULL);
- g_slist_free(user->masks);
-
- g_hash_table_foreach(user->channels, (GHFunc) user_destroy_chan, NULL);
- g_hash_table_destroy(user->channels);
-
- g_free_not_null(user->password);
- g_free(user->nick);
- g_free(user);
-}
-
-static int sig_write_users(void)
-{
- if (last_write + WRITE_USERS_INTERVAL <= time(NULL)) {
- last_write = time(NULL);
- config_write(userconfig, NULL, -1);
- }
- return 1;
-}
-
-static void botuser_config_read_user(CONFIG_NODE *node)
-{
- USER_REC *user;
- USER_CHAN_REC *userchan;
- USER_MASK_REC *usermask;
- CONFIG_NODE *subnode;
- GSList *tmp;
- char *value;
-
- g_return_if_fail(node != NULL);
-
- /* nick = { ... } */
- if (node->key == NULL || node->value == NULL)
- return;
-
- /* Add new user */
- user = g_new0(USER_REC, 1);
- user->nick = g_strdup(node->key);
- g_hash_table_insert(users, user->nick, user);
-
- /* password, flags, modify time */
- user->password = g_strdup(config_node_get_str(node, "password", NULL));
- user->flags = botuser_flags2value(config_node_get_str(node, "flags", ""));
- user->last_modify = (time_t) config_node_get_int(node, "last_modify", 0);
-
- /* get masks */
- user->masks = NULL;
- subnode = config_node_section(node, "masks", -1);
- tmp = subnode == NULL ? NULL : subnode->value;
- for (; tmp != NULL; tmp = tmp->next) {
- subnode = tmp->data;
-
- value = config_node_get_str(subnode, "mask", NULL);
- if (value == NULL) continue; /* mask is required */
-
- usermask = botuser_create_mask(user, value);
- value = config_node_get_str(subnode, "not_flags", "");
- usermask->not_flags = botuser_flags2value(value);
- }
-
- /* get channels - must be last, messes up pvalue */
- user->channels = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal);
- subnode = config_node_section(node, "channels", -1);
- tmp = subnode == NULL ? NULL : subnode->value;
- for (; tmp != NULL; tmp = tmp->next) {
- subnode = tmp->data;
-
- value = config_node_get_str(subnode, "channel", NULL);
- if (value == NULL) continue; /* channel is required */
-
- /* create user channel specific record */
- userchan = g_new0(USER_CHAN_REC, 1);
- userchan->channel = g_strdup(value);
- g_hash_table_insert(user->channels, userchan->channel, userchan);
-
- value = config_node_get_str(subnode, "flags", "");
- userchan->flags = botuser_flags2value(value);
- }
-}
-
-static void botuser_config_read(void)
-{
- CONFIG_NODE *node;
- GSList *tmp;
- char *fname;
-
- /* Read users from ~/.irssi/users */
- fname = g_strdup_printf("%s/users", get_irssi_dir());
- userconfig = config_open(fname, 0600);
- g_free(fname);
-
- if (userconfig == NULL)
- return; /* access denied?! */
-
- config_parse(userconfig);
-
- node = config_node_traverse(userconfig, "users", FALSE);
- tmp = node == NULL ? NULL : node->value;
- for (; tmp != NULL; tmp = tmp->next)
- botuser_config_read_user(tmp->data);
-}
-
-void bot_users_init(void)
-{
- users = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal);
-
- last_write = time(NULL);
- writeusers_tag = g_timeout_add(10000, (GSourceFunc) sig_write_users, NULL);
-
- botuser_config_read();
- signal_add_last("massjoin", (SIGNAL_FUNC) event_massjoin);
- signal_add_last("channel sync", (SIGNAL_FUNC) sig_channel_sync);
- signal_add_last("nicklist remove", (SIGNAL_FUNC) sig_nicklist_remove);
-}
-
-void bot_users_deinit(void)
-{
- if (userconfig != NULL) {
- config_write(userconfig, NULL, -1);
- config_close(userconfig);
- }
-
- g_source_remove(writeusers_tag);
-
- g_hash_table_foreach(users, (GHFunc) user_destroy, NULL);
- g_hash_table_destroy(users);
-
- signal_remove("massjoin", (SIGNAL_FUNC) event_massjoin);
- signal_remove("channel sync", (SIGNAL_FUNC) sig_channel_sync);
- signal_remove("nicklist remove", (SIGNAL_FUNC) sig_nicklist_remove);
-}
diff --git a/src/irc/bot/bot-users.h b/src/irc/bot/bot-users.h
deleted file mode 100644
index 8023e9a6..00000000
--- a/src/irc/bot/bot-users.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __BOT_USERS_H
-#define __BOT_USERS_H
-
-#define USER_OP 0x0001
-#define USER_AUTO_OP 0x0002
-#define USER_AUTO_VOICE 0x0004
-#define USER_MASTER 0x0008
-
-#define USER_FLAG_COUNT 4
-
-/* Channel specific flags */
-typedef struct {
- char *channel;
- int flags;
- NICK_REC *nickrec; /* Nick record in channel,
- FIXME: User can be in channel with multiple nicks too! */
-} USER_CHAN_REC;
-
-typedef struct {
- char *mask;
- int not_flags; /* do not let this mask use these flags.. */
-} USER_MASK_REC;
-
-/* User specific flags */
-typedef struct {
- char *nick;
- int flags;
- char *password;
-
- GSList *masks;
- GHashTable *channels;
-
- int not_flags; /* active not_flags based on current host mask,
- botuser_find() updates this */
- time_t last_modify; /* last time the user settings were modified */
-} USER_REC;
-
-int botuser_flags2value(const char *flags);
-char *botuser_value2flags(int value);
-
-USER_REC *botuser_find(const char *nick, const char *host);
-USER_REC *botuser_find_rec(CHANNEL_REC *channel, NICK_REC *nick);
-
-USER_REC *botuser_add(const char *nick);
-void botuser_set_flags(USER_REC *user, int flags);
-void botuser_set_channel_flags(USER_REC *user, const char *channel, int flags);
-
-USER_MASK_REC *botuser_add_mask(USER_REC *user, const char *mask);
-void botuser_set_mask_notflags(USER_REC *user, const char *mask, int not_flags);
-
-void botuser_set_password(USER_REC *user, const char *password);
-int botuser_verify_password(USER_REC *user, const char *password);
-
-void botuser_save(const char *fname);
-
-#endif
diff --git a/src/irc/bot/bot.c b/src/irc/bot/bot.c
deleted file mode 100644
index f2beee4d..00000000
--- a/src/irc/bot/bot.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- bot.c : IRC bot plugin for irssi
-
- Copyright (C) 1999-2000 Timo Sirainen
-
- 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "module.h"
-#include "modules.h"
-
-void bot_irc_commands_deinit(void);
-void bot_irc_commands_init(void);
-
-void bot_events_init(void);
-void bot_events_deinit(void);
-
-void bot_users_init(void);
-void bot_users_deinit(void);
-
-void botnet_init(void);
-void botnet_deinit(void);
-
-void irc_bot_init(void)
-{
- bot_users_init();
- bot_irc_commands_init();
- bot_events_init();
- botnet_init();
-
- module_register("bot", "irc");
-}
-
-void irc_bot_deinit(void)
-{
- bot_users_deinit();
- bot_irc_commands_deinit();
- bot_events_deinit();
- botnet_deinit();
-}
diff --git a/src/irc/bot/bot.h b/src/irc/bot/bot.h
deleted file mode 100644
index a518d4bd..00000000
--- a/src/irc/bot/bot.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __BOT_H
-#define __BOT_H
-
-typedef struct
-{
- PLUGIN_REC *plugin;
- gboolean loaded;
-
- GHashTable *users;
- GSList *botnets;
-
- gchar *nick;
- gint rank;
-
- time_t last_write;
-}
-PLUGIN_DATA;
-
-void plugin_bot_events(PLUGIN_REC *plugin);
-
-#include "botnet.h"
-#include "users.h"
-
-#define MODULE_NAME "bot"
-
-#endif
diff --git a/src/irc/bot/botnet-connection.c b/src/irc/bot/botnet-connection.c
deleted file mode 100644
index 1039cea0..00000000
--- a/src/irc/bot/botnet-connection.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- botnet-connection.c : IRC bot plugin for irssi
-
- Copyright (C) 1999-2000 Timo Sirainen
-
- 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "module.h"
-#include "network.h"
-#include "net-nonblock.h"
-#include "signals.h"
-#include "commands.h"
-#include "misc.h"
-#include "line-split.h"
-#include "lib-config/iconfig.h"
-
-#include "botnet.h"
-#include "bot-users.h"
-
-#define BOTNET_RECONNECT_TIME (60*5)
-
-static int reconnect_tag;
-
-static int sig_reconnect(void)
-{
- GSList *tmp;
-
- for (tmp = botnets; tmp != NULL; tmp = tmp->next) {
- BOTNET_REC *rec = tmp->data;
-
- if (rec->reconnect)
- botnet_connect(rec);
- }
-
- return 1;
-}
-
-static void sig_bot_read(BOT_REC *bot)
-{
- BOTNET_REC *botnet;
- char tmpbuf[1024], *str;
- int ret, recvlen, reconnect;
-
- botnet = bot->botnet;
- for (;;) {
- recvlen = bot->handle == NULL ? -1 :
- net_receive(bot->handle, tmpbuf, sizeof(tmpbuf));
- ret = line_split(tmpbuf, recvlen, &str, &bot->buffer);
-
- if (ret == 0)
- break;
- if (ret == -1) {
- /* connection lost */
- reconnect = !bot->disconnect && bot->uplink;
- bot_destroy(bot);
-
- if (reconnect) {
- /* wasn't intentional disconnection from
- our uplink, reconnect */
- botnet_connect(botnet);
- }
- break;
- }
-
- fprintf(stderr, "%s\r\n", str);
- signal_emit("botnet event", 2, bot, str);
- }
-}
-
-static void connect_downlink(BOTNET_REC *botnet, GIOChannel *handle,
- IPADDR *ip, const char *host)
-{
- BOT_DOWNLINK_REC *downlink;
- BOT_REC *bot;
-
- g_return_if_fail(botnet != NULL);
-
- /* identify the bot who's trying to connect.. */
- downlink = bot_downlink_find(botnet, ip, host);
- if (downlink == NULL || downlink->password == NULL) {
- /* unknown bot, close connection /
- bot didn't have password, don't let it connect to us */
- net_disconnect(handle);
- return;
- }
-
- bot = g_new0(BOT_REC, 1);
- bot->botnet = botnet;
- bot->link = downlink;
- g_node_append_data(botnet->bots, bot);
-
- /* connected.. */
- bot->handle = handle;
- bot->read_tag = g_input_add(handle, G_INPUT_READ, (GInputFunction) sig_bot_read, bot);
-}
-
-typedef struct {
- char *botnet;
- IPADDR ip;
- GIOChannel *handle;
-} BOT_CONNECT_REC;
-
-static void sig_host_got(RESOLVED_NAME_REC *name, BOT_CONNECT_REC *rec)
-{
- BOTNET_REC *botnet;
-
- botnet = botnet_find(rec->botnet);
- if (botnet == NULL || !botnet->connected) {
- /* this botnet isn't connected anymore.. */
- net_disconnect(rec->handle);
- } else {
- connect_downlink(botnet, rec->handle, &rec->ip,
- name->error ? NULL : name->name);
- }
- g_free(rec->botnet);
- g_free(rec);
-}
-
-static void sig_botnet_listen(BOTNET_REC *botnet)
-{
- BOT_CONNECT_REC *rec;
- IPADDR ip;
- GIOChannel *handle;
-
- g_return_if_fail(botnet != NULL);
-
- /* accept connection */
- handle = net_accept(botnet->listen_handle, &ip, NULL);
- if (handle == NULL)
- return;
-
- rec = g_new0(BOT_CONNECT_REC, 1);
- rec->botnet = g_strdup(botnet->name);
- memcpy(&rec->ip, &ip, sizeof(IPADDR));
- rec->handle = handle;
-
- if (!net_gethostbyaddr_nonblock(&ip, (NET_HOST_CALLBACK) sig_host_got, rec)) {
- /* failed for some reason, try without host */
- connect_downlink(botnet, handle, &ip, NULL);
- g_free(rec->botnet);
- g_free(rec);
- }
-}
-
-static int botnet_listen(BOTNET_REC *botnet)
-{
- IPADDR addr;
- int port;
-
- g_return_val_if_fail(botnet != NULL, FALSE);
-
- if (botnet->port <= 0)
- return FALSE;
-
- port = botnet->port;
- if (botnet->addr == NULL)
- botnet->listen_handle = net_listen(NULL, &port);
- else {
- net_host2ip(botnet->addr, &addr);
- botnet->listen_handle = net_listen(&addr, &port);
- }
-
- if (botnet->listen_handle == NULL) {
- g_warning("Couldn't start listening botnet\n");
- return FALSE;
- }
-
- botnet->listen_tag = g_input_add(botnet->listen_handle, G_INPUT_READ,
- (GInputFunction) sig_botnet_listen, botnet);
-
- return TRUE;
-}
-
-static void sig_botnet_connected(GIOChannel *handle, BOT_UPLINK_REC *uplink)
-{
- BOTNET_REC *botnet;
- BOT_REC *bot;
-
- g_return_if_fail(uplink != NULL);
-
- botnet = uplink->botnet;
-
- if (handle == NULL) {
- /* error, try another bot */
- botnet_connect(botnet);
- return;
- }
-
- /* connected to bot */
- bot = g_new0(BOT_REC, 1);
- bot->botnet = botnet;
- bot->link = uplink;
- bot->uplink = TRUE;
-
- bot->handle = handle;
- bot->read_tag = g_input_add(handle, G_INPUT_READ, (GInputFunction) sig_bot_read, bot);
-
- botnet->uplink = bot;
- g_node_append_data(botnet->bots, bot);
-
- /* send nick/pass */
- bot_send_cmdv(bot, "PASS %s", uplink->password);
- bot_send_cmdv(bot, "NICK %s", botnet->nick);
-}
-
-void botnet_connect(BOTNET_REC *botnet)
-{
- BOT_REC *bot;
- BOT_UPLINK_REC *uplink, *best;
- GSList *tmp;
- time_t now;
-
- g_return_if_fail(botnet != NULL);
-
- botnet->reconnect = FALSE;
- if (botnet->bots == NULL) {
- /* create bot record for us */
- bot = g_new0(BOT_REC, 1);
- bot->botnet = botnet;
- bot->nick = g_strdup(botnet->nick);
- bot->priority = botnet->priority;
- bot->connected = TRUE;
- bot->master = TRUE;
-
- bot->read_tag = -1;
-
- botnet->connected = TRUE;
- botnet->master = bot;
-
- botnet->bots = g_node_new(bot);
- }
-
- if (botnet->listen_handle == NULL) {
- /* start listening */
- botnet_listen(botnet);
- }
-
- if (botnet->uplinks == NULL) {
- /* we have no uplinks */
- return;
- }
-
- /* find some bot where we can try to connect to */
- now = time(NULL);
- uplink = best = NULL;
- for (tmp = botnet->uplinks; tmp != NULL; tmp = tmp->next) {
- uplink = tmp->data;
-
- if (uplink->last_connect+BOTNET_RECONNECT_TIME > now)
- continue;
-
- if (uplink->last_connect == 0) {
- /* haven't yet tried to connect to this bot */
- best = uplink;
- break;
- }
-
- if (best == NULL || uplink->last_connect < best->last_connect)
- best = uplink;
- }
-
- if (best == NULL) {
- /* reconnect later */
- botnet->reconnect = TRUE;
- return;
- }
-
- /* connect to uplink */
- best->last_connect = time(NULL);
- net_connect_nonblock(best->host, best->port, NULL, (NET_CALLBACK) sig_botnet_connected, best);
-}
-
-static int botnet_send_botinfo(GNode *node, BOT_REC *client)
-{
- BOT_REC *parent, *bot;
-
- bot = node->data;
- parent = node->parent == NULL ? NULL : node->parent->data;
- if (parent == NULL && client->uplink) parent = client;
-
- bot_send_cmdv(client, "%s - BOTINFO %s %s %d", bot->botnet->nick, bot->nick,
- parent != NULL ? parent->nick : "-", bot->priority);
- return FALSE;
-}
-
-/* send botnet links to specified bot */
-static void botnet_send_links(BOT_REC *bot, int downlinks)
-{
- GNode *node;
-
- if (!downlinks) {
- /* send uplinks */
- if (bot->botnet->uplink == NULL)
- return;
-
- node = g_node_find(bot->botnet->bots, G_IN_ORDER,
- G_TRAVERSE_ALL, bot->botnet->uplink);
- if (node == NULL)
- return;
-
- g_node_traverse(node, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1,
- (GNodeTraverseFunc) botnet_send_botinfo, bot);
- return;
- }
-
- /* send downlinks = all non-uplink nodes */
- for (node = bot->botnet->bots->children; node != NULL; node = node->next) {
- BOT_REC *rec = node->data;
-
- if (rec == bot || rec->uplink || !rec->connected)
- continue;
-
- g_node_traverse(node, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1,
- (GNodeTraverseFunc) botnet_send_botinfo, bot);
- }
-}
-
-static void botnet_connect_event_uplink(BOT_REC *bot, const char *data)
-{
- BOTNET_REC *botnet;
- BOT_REC *ownbot;
- char *str, *p;
- int num;
-
- botnet = bot->botnet;
- g_return_if_fail(botnet != NULL);
-
- if (g_strcasecmp(data, "NICKERROR") == 0) {
- /* nick already in use, change it by adding a number
- at the end of it */
- p = botnet->nick+strlen(botnet->nick);
- while (p > botnet->nick && i_isdigit(p[-1])) p--;
- num = *p == '\0' ? 2 : atoi(p)+1; *p = '\0';
- str = g_strdup_printf("%s%d", botnet->nick, num);
- g_free(botnet->nick); botnet->nick = str;
-
- ownbot = botnet->bots->data;
- g_free(ownbot->nick); ownbot->nick = g_strdup(str);
-
- /* try again.. */
- bot_send_cmdv(bot, "NICK %s", botnet->nick);
-
- return;
- }
-
- if (g_strcasecmp(data, "CONNECTED") == 0) {
- /* connected, wait for SYNC command */
- bot->connected = TRUE;
- return;
- }
-
- /* error? what? */
-}
-
-static void botnet_event(BOT_REC *bot, const char *data)
-{
- BOT_DOWNLINK_REC *downlink;
- char *fname;
-
- g_return_if_fail(bot != NULL);
- g_return_if_fail(data != NULL);
-
- if (bot->connected)
- return;
-
- signal_stop_by_name("botnet event");
-
- if (bot->uplink) {
- botnet_connect_event_uplink(bot, data);
- return;
- }
-
- downlink = bot->link;
-
- if (!bot->pass_ok && g_strncasecmp(data, "PASS ", 5) == 0) {
- /* password sent, check that it matches */
- if (strcmp(data+5, downlink->password) == 0) {
- /* ok, connected! */
- bot->pass_ok = TRUE;
- } else {
- /* wrong password, disconnect */
- bot_disconnect(bot);
- }
- return;
- }
-
- if (g_strncasecmp(data, "NICK ", 5) == 0) {
- /* set bot's nick */
- if (!bot->pass_ok) {
- /* password has to be sent before nick, kill the
- stupid bot. */
- bot_disconnect(bot);
- return;
- }
-
- if (g_strcasecmp(bot->botnet->nick, data+5) == 0 ||
- bot_find_nick(bot->botnet, data+5) != NULL) {
- /* nick already exists */
- bot_send_cmd(bot, "NICKERROR");
- return;
- }
-
- /* set the nick */
- bot->nick = g_strdup(data+5);
- bot->connected = TRUE;
- bot_send_cmd(bot, "CONNECTED");
-
- /* send info about all the bots that are connected now
- to this botnet */
- botnet_send_botinfo(bot->botnet->bots, bot);
- botnet_send_links(bot, FALSE);
- botnet_send_links(bot, TRUE);
- bot_send_cmdv(bot, "%s - MASTER %s", bot->botnet->nick, bot->botnet->master->nick);
-
- /* send our current user configuration */
- fname = g_strdup_printf("%s/users.temp", get_irssi_dir());
- botuser_save(fname);
- botnet_send_file(bot->botnet, bot->nick, fname);
- g_free(fname);
-
- /* send sync msg */
- bot_send_cmdv(bot, "%s - SYNC", bot->botnet->nick);
- return;
- }
-
- /* pass/nick not sent yet */
- bot_send_cmd(bot, "ERROR");
-}
-
-static void botnet_event_sync(BOT_REC *bot)
-{
- /* send our record to host */
- botnet_send_botinfo(bot->botnet->bots, bot);
-
- /* send our downlinks to host */
- botnet_send_links(bot, TRUE);
-
- signal_stop_by_name("botnet event");
-}
-
-static BOT_REC *bot_add(BOTNET_REC *botnet, const char *nick, const char *parent)
-{
- GNode *node;
- BOT_REC *rec;
-
- g_return_val_if_fail(botnet != NULL, NULL);
- g_return_val_if_fail(nick != NULL, NULL);
-
- node = bot_find_nick(botnet, nick);
- if (node != NULL) return node->data;
-
- node = bot_find_nick(botnet, parent);
- if (node == NULL) return NULL;
-
- rec = g_new0(BOT_REC, 1);
- rec->botnet = botnet;
- rec->nick = g_strdup(nick);
-
- rec->read_tag = -1;
- rec->connected = TRUE;
-
- g_node_append_data(node, rec);
- return rec;
-}
-
-static void botnet_event_botinfo(BOT_REC *bot, const char *data, const char *sender)
-{
- char *nick, *parent, *priority;
- void *free_arg;
- BOT_REC *rec;
-
- /*str = g_strdup_printf("BOTINFO %s", data);
- botnet_broadcast(bot->botnet, bot, sender, str);
- g_free(str);*/
-
- if (!cmd_get_params(data, &free_arg, 3, &nick, &parent, &priority))
- return;
- if (*parent == '-' && parent[1] == '\0')
- parent = NULL;
-
- if (parent == NULL && bot->botnet->uplink != NULL &&
- bot->botnet->uplink == bot) {
- /* our uplink */
- if (bot->nick == NULL) bot->nick = g_strdup(nick);
- rec = bot;
- } else {
- rec = bot_add(bot->botnet, nick, parent);
- }
-
- if (rec != NULL) {
- rec->priority = atoi(priority);
- }
- cmd_params_free(free_arg);
-}
-
-static void botnet_event_botquit(BOT_REC *bot, const char *data)
-{
- GNode *node;
-
- node = bot_find_nick(bot->botnet, data);
- if (node != NULL) bot_destroy(node->data);
-
- signal_stop_by_name("botnet event");
-}
-
-static void sig_bot_disconnected(BOT_REC *bot)
-{
- BOT_REC *master, *tmpbot;
- GNode *node;
- char *str;
-
- if (!bot->botnet->connected)
- return;
-
- if (bot->connected && bot->handle != NULL) {
- /* send notice to rest of the botnet about quit */
- str = g_strdup_printf("BOTQUIT %s", bot->nick);
- botnet_broadcast(bot->botnet, bot, NULL, str);
- g_free(str);
- }
-
- if (bot->master) {
- /* master quit */
- node = bot_find_path(bot->botnet, bot->nick);
- tmpbot = node == NULL ? NULL : node->data;
-
- if (tmpbot != NULL && tmpbot->disconnect) {
- /* we lost the connection to master - find new
- master for the botnet*/
- master = botnet_find_master(bot->botnet, NULL);
- botnet_set_master(bot->botnet, master);
-
- str = g_strdup_printf("MASTER %s", master->nick);
- botnet_broadcast(bot->botnet, bot, NULL, str);
- g_free(str);
- }
- }
-}
-
-static int print_bot(GNode *node)
-{
- BOT_REC *bot = node->data;
-
- fprintf(stderr, "%s %d %d\r\n", bot->nick, bot->connected, bot->disconnect);
- return FALSE;
-}
-
-static void cmd_bots(void)
-{
- BOTNET_REC *botnet = botnet_find("ircnet");
-
- fprintf(stderr, "\r\n");
- g_node_traverse(botnet->bots, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1,
- (GNodeTraverseFunc) print_bot, NULL);
-}
-
-void botnet_connection_init(void)
-{
- reconnect_tag = g_timeout_add(BOTNET_RECONNECT_TIME*1000, (GSourceFunc) sig_reconnect, NULL);
-
- signal_add("botnet event", (SIGNAL_FUNC) botnet_event);
- signal_add("botnet event sync", (SIGNAL_FUNC) botnet_event_sync);
- signal_add("botnet event botinfo", (SIGNAL_FUNC) botnet_event_botinfo);
- signal_add("botnet event botquit", (SIGNAL_FUNC) botnet_event_botquit);
- signal_add("bot disconnected", (SIGNAL_FUNC) sig_bot_disconnected);
- command_bind("bots", NULL, (SIGNAL_FUNC) cmd_bots);
-}
-
-void botnet_connection_deinit(void)
-{
- g_source_remove(reconnect_tag);
-
- signal_remove("botnet event", (SIGNAL_FUNC) botnet_event);
- signal_remove("botnet event sync", (SIGNAL_FUNC) botnet_event_sync);
- signal_remove("botnet event botinfo", (SIGNAL_FUNC) botnet_event_botinfo);
- signal_remove("botnet event botquit", (SIGNAL_FUNC) botnet_event_botquit);
- signal_remove("bot disconnected", (SIGNAL_FUNC) sig_bot_disconnected);
- command_unbind("bots", (SIGNAL_FUNC) cmd_bots);
-}
diff --git a/src/irc/bot/botnet-users.c b/src/irc/bot/botnet-users.c
deleted file mode 100644
index 9369a2a1..00000000
--- a/src/irc/bot/botnet-users.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- botnet-users.c : IRC bot plugin for irssi
-
- Copyright (C) 1999-2000 Timo Sirainen
-
- 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "module.h"
-#include "signals.h"
-#include "commands.h"
-
-#include "irc.h"
-#include "irc-servers.h"
-#include "channels.h"
-#include "nicklist.h"
-#include "masks.h"
-
-#include "bot-users.h"
-#include "botnet.h"
-
-void botcmd_user_add(const char *nick)
-{
- char *str;
-
- botuser_add(nick);
-
- str = g_strdup_printf("USER_ADD %s", nick);
- botnet_broadcast(NULL, NULL, NULL, str);
- g_free(str);
-}
-
-void botcmd_user_set_flags(USER_REC *user, int flags)
-{
- char *str, *flagstr;
-
- botuser_set_flags(user, flags);
-
- flagstr = botuser_value2flags(flags);
- str = g_strdup_printf("USER_FLAGS %s %s", user->nick, flagstr);
- g_free(flagstr);
-
- botnet_broadcast(NULL, NULL, NULL, str);
- g_free(str);
-}
-
-void botcmd_user_set_channel_flags(USER_REC *user, const char *channel, int flags)
-{
- char *str, *flagstr;
-
- botuser_set_channel_flags(user, channel, flags);
-
- flagstr = botuser_value2flags(flags);
- str = g_strdup_printf("USER_CHAN_FLAGS %s %s %s", user->nick, channel, flagstr);
- g_free(flagstr);
-
- botnet_broadcast(NULL, NULL, NULL, str);
- g_free(str);
-}
-
-void botcmd_user_add_mask(USER_REC *user, const char *mask)
-{
- char *str;
-
- botuser_add_mask(user, mask);
-
- str = g_strdup_printf("USER_ADD_MASK %s %s", user->nick, mask);
- botnet_broadcast(NULL, NULL, NULL, str);
- g_free(str);
-}
-
-void botcmd_user_set_mask_notflags(USER_REC *user, const char *mask, int not_flags)
-{
- char *str, *flagstr;
-
- botuser_set_mask_notflags(user, mask, not_flags);
-
- flagstr = botuser_value2flags(not_flags);
- str = g_strdup_printf("USER_MASK_NOTFLAGS %s %s %s", user->nick, mask, flagstr);
- g_free(flagstr);
-
- botnet_broadcast(NULL, NULL, NULL, str);
- g_free(str);
-}
-
-void botcmd_user_set_password(USER_REC *user, const char *password)
-{
- char *str;
-
- botuser_set_password(user, password);
-
- str = g_strdup_printf("USER_PASS %s %s", user->nick, password);
- botnet_broadcast(NULL, NULL, NULL, str);
- g_free(str);
-}
-
-static void botnet_event_user_add(BOT_REC *bot, const char *data, const char *sender)
-{
- char *nick;
- void *free_arg;
-
- if (!cmd_get_params(data, &free_arg, 1, &nick))
- return;
-
- botuser_add(nick);
- cmd_params_free(free_arg);
-}
-
-static void botnet_event_user_flags(BOT_REC *bot, const char *data, const char *sender)
-{
- USER_REC *user;
- char *nick, *flags;
- void *free_arg;
-
- if (!cmd_get_params(data, &free_arg, 2, &nick, &flags))
- return;
-
- user = botuser_find(nick, NULL);
- if (user == NULL) user = botuser_add(nick);
- botuser_set_flags(user, botuser_flags2value(flags));
-
- cmd_params_free(free_arg);
-}
-
-static void botnet_event_user_chan_flags(BOT_REC *bot, const char *data, const char *sender)
-{
- USER_REC *user;
- char *nick, *channel, *flags;
- void *free_arg;
-
- if (!cmd_get_params(data, &free_arg, 3, &nick, &channel, &flags))
- return;
-
- user = botuser_find(nick, NULL);
- if (user == NULL) user = botuser_add(nick);
- botuser_set_channel_flags(user, channel, botuser_flags2value(flags));
-
- cmd_params_free(free_arg);
-}
-
-static void botnet_event_user_add_mask(BOT_REC *bot, const char *data, const char *sender)
-{
- USER_REC *user;
- char *nick, *mask;
- void *free_arg;
-
- if (!cmd_get_params(data, &free_arg, 2, &nick, &mask))
- return;
-
- user = botuser_find(nick, NULL);
- if (user == NULL) user = botuser_add(nick);
- botuser_add_mask(user, mask);
-
- cmd_params_free(free_arg);
-}
-
-static void botnet_event_user_mask_notflags(BOT_REC *bot, const char *data, const char *sender)
-{
- USER_REC *user;
- char *nick, *mask, *not_flags;
- void *free_arg;
-
- if (!cmd_get_params(data, &free_arg, 3, &nick, &mask, &not_flags))
- return;
-
- user = botuser_find(nick, NULL);
- if (user == NULL) user = botuser_add(nick);
- botuser_set_mask_notflags(user, mask, botuser_flags2value(not_flags));
-
- cmd_params_free(free_arg);
-}
-
-static void botnet_event_user_pass(BOT_REC *bot, const char *data, const char *sender)
-{
- USER_REC *user;
- char *nick, *pass;
- void *free_arg;
-
- if (!cmd_get_params(data, &free_arg, 2, &nick, &pass))
- return;
-
- user = botuser_find(nick, NULL);
- if (user == NULL) user = botuser_add(nick);
- botuser_set_password(user, pass);
-
- cmd_params_free(free_arg);
-}
-
-void botnet_users_init(void)
-{
- signal_add("botnet event user_add", (SIGNAL_FUNC) botnet_event_user_add);
- signal_add("botnet event user_flags", (SIGNAL_FUNC) botnet_event_user_flags);
- signal_add("botnet event user_chan_flags", (SIGNAL_FUNC) botnet_event_user_chan_flags);
- signal_add("botnet event user_add_mask", (SIGNAL_FUNC) botnet_event_user_add_mask);
- signal_add("botnet event user_mask_notflags", (SIGNAL_FUNC) botnet_event_user_mask_notflags);
- signal_add("botnet event user_pass", (SIGNAL_FUNC) botnet_event_user_pass);
-}
-
-void botnet_users_deinit(void)
-{
- signal_remove("botnet event user_add", (SIGNAL_FUNC) botnet_event_user_add);
- signal_remove("botnet event user_flags", (SIGNAL_FUNC) botnet_event_user_flags);
- signal_remove("botnet event user_chan_flags", (SIGNAL_FUNC) botnet_event_user_chan_flags);
- signal_remove("botnet event user_add_mask", (SIGNAL_FUNC) botnet_event_user_add_mask);
- signal_remove("botnet event user_mask_notflags", (SIGNAL_FUNC) botnet_event_user_mask_notflags);
- signal_remove("botnet event user_pass", (SIGNAL_FUNC) botnet_event_user_pass);
-}
diff --git a/src/irc/bot/botnet-users.h b/src/irc/bot/botnet-users.h
deleted file mode 100644
index 303a0890..00000000
--- a/src/irc/bot/botnet-users.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __BOTNET_USERS_H
-#define __BOTNET_USERS_H
-
-void botcmd_user_add(const char *nick);
-void botcmd_user_set_flags(USER_REC *user, int flags);
-void botcmd_user_set_channel_flags(USER_REC *user, const char *channel, int flags);
-
-void botcmd_user_add_mask(USER_REC *user, const char *mask);
-void botcmd_user_set_mask_notflags(USER_REC *user, const char *mask, int not_flags);
-
-void botcmd_user_set_password(USER_REC *user, const char *password);
-
-#endif
diff --git a/src/irc/bot/botnet.c b/src/irc/bot/botnet.c
deleted file mode 100644
index 3eb038e5..00000000
--- a/src/irc/bot/botnet.c
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- botnet.c : IRC bot plugin for irssi
-
- Copyright (C) 1999-2000 Timo Sirainen
-
- 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "module.h"
-#include "network.h"
-#include "net-nonblock.h"
-#include "signals.h"
-#include "commands.h"
-#include "misc.h"
-#include "line-split.h"
-#include "lib-config/iconfig.h"
-
-#include "botnet.h"
-
-void botnet_connection_init(void);
-void botnet_connection_deinit(void);
-
-void botnet_users_deinit(void);
-void botnet_users_init(void);
-
-GSList *botnets;
-
-void bot_send_cmd(BOT_REC *bot, const char *data)
-{
- g_return_if_fail(bot != NULL);
- g_return_if_fail(data != NULL);
-
- net_transmit(bot->handle, data, strlen(data));
- net_transmit(bot->handle, "\n", 1);
-}
-
-void bot_send_cmdv(BOT_REC *bot, const char *format, ...)
-{
- va_list args;
- char *str;
-
- va_start(args, format);
-
- str = g_strdup_vprintf(format, args);
- bot_send_cmd(bot, str);
- g_free(str);
-
- va_end(args);
-}
-
-static void botnet_broadcast_single(BOTNET_REC *botnet, BOT_REC *except_bot,
- const char *source, const char *data)
-{
- GNode *node;
- char *str;
-
- g_return_if_fail(botnet != NULL);
- g_return_if_fail(data != NULL);
-
- str = g_strdup_printf("%s - %s", source != NULL ? source :
- botnet->nick, data);
- for (node = botnet->bots->children; node != NULL; node = node->next) {
- BOT_REC *rec = node->data;
-
- if (rec != except_bot && rec->handle != NULL)
- bot_send_cmd(rec, str);
- }
- g_free(str);
-}
-
-/* broadcast a message to everyone in bot network, except for `except_bot'
- if it's not NULL. If botnet is NULL, the message is sent to all botnets. */
-void botnet_broadcast(BOTNET_REC *botnet, BOT_REC *except_bot,
- const char *source, const char *data)
-{
- GSList *tmp;
-
- g_return_if_fail(data != NULL);
-
- if (botnet != NULL) {
- botnet_broadcast_single(botnet, except_bot, source, data);
- return;
- }
-
- /* broadcast to all botnets */
- for (tmp = botnets; tmp != NULL; tmp = tmp->next) {
- BOTNET_REC *rec = tmp->data;
-
- botnet_broadcast_single(rec, except_bot, source, data);
- }
-}
-
-void botnet_send_cmd(BOTNET_REC *botnet, const char *source,
- const char *target, const char *data)
-{
- GNode *node;
- char *str;
-
- g_return_if_fail(botnet != NULL);
- g_return_if_fail(target != NULL);
- g_return_if_fail(data != NULL);
-
- node = bot_find_path(botnet, target);
- if (node == NULL) {
- g_warning("Can't find route for target %s", target);
- return;
- }
-
- str = g_strdup_printf("%s %s %s", source != NULL ? source :
- botnet->nick, target, data);
- bot_send_cmd(node->data, str);
- g_free(str);
-}
-
-static void escape_buffer(char *buffer, int len)
-{
- char *dest, *tempbuf, *p;
-
- dest = buffer;
- tempbuf = p = g_malloc(len*2+2);
- while (len > 0) {
- if (*buffer == '\0') {
- *p++ = '\\';
- *p++ = '0';
- } else if (*buffer == '\r') {
- *p++ = '\\';
- *p++ = 'r';
- } else if (*buffer == '\n') {
- *p++ = '\\';
- *p++ = 'n';
- } else if (*buffer == '\\') {
- *p++ = '\\';
- *p++ = '\\';
- } else {
- *p++ = *buffer;
- }
- len--; buffer++;
- }
- *p++ = '\0';
-
- len = (int) (p-tempbuf);
- memcpy(dest, tempbuf, len);
- g_free(tempbuf);
-}
-
-int botnet_send_file(BOTNET_REC *botnet, const char *target, const char *fname)
-{
- GNode *node;
- GString *str;
- char buffer[1024];
- int f, len;
-
- node = bot_find_path(botnet, target);
- if (node == NULL) {
- g_warning("Can't find route for target %s", target);
- return FALSE;
- }
-
- f = open(fname, O_RDONLY);
- if (f == -1) return FALSE;
-
- str = g_string_new(NULL);
-
- g_string_sprintf(str, "%s %s FILE %s", botnet->nick, target, g_basename(fname));
- bot_send_cmd(node->data, str->str);
-
- while ((len = read(f, buffer, sizeof(buffer)/2-2)) > 0) {
- escape_buffer(buffer, len);
-
- g_string_sprintf(str, "%s %s FILE %s", botnet->nick, target, buffer);
- bot_send_cmd(node->data, str->str);
- }
-
- g_string_sprintf(str, "%s %s FILE", botnet->nick, target);
- bot_send_cmd(node->data, str->str);
- g_string_free(str, TRUE);
-
- close(f);
- return TRUE;
-}
-
-BOTNET_REC *botnet_find(const char *name)
-{
- GSList *tmp;
-
- g_return_val_if_fail(name != NULL, NULL);
-
- for (tmp = botnets; tmp != NULL; tmp = tmp->next) {
- BOTNET_REC *rec = tmp->data;
-
- if (g_strcasecmp(rec->name, name) == 0)
- return rec;
- }
-
- return NULL;
-}
-
-typedef struct {
- gconstpointer key;
- int priority;
- GNode *node;
-} BOT_FIND_REC;
-
-static int gnode_find_nick(GNode *node, BOT_FIND_REC *rec)
-{
- BOT_REC *bot = node->data;
-
- if (bot == NULL) return FALSE;
-
- if (bot->nick != NULL && g_strcasecmp(bot->nick, rec->key) == 0) {
- rec->node = node;
- return TRUE;
- }
-
- return FALSE;
-}
-
-GNode *bot_find_nick(BOTNET_REC *botnet, const char *nick)
-{
- BOT_FIND_REC rec;
-
- g_return_val_if_fail(botnet != NULL, NULL);
- g_return_val_if_fail(nick != NULL, NULL);
-
- rec.key = nick;
- rec.node = NULL;
- g_node_traverse(botnet->bots, 0, G_TRAVERSE_ALL, -1,
- (GNodeTraverseFunc) gnode_find_nick, &rec);
- return rec.node;
-}
-
-/* Return the bot who we should send the message if we wanted `nick' to get it. */
-GNode *bot_find_path(BOTNET_REC *botnet, const char *nick)
-{
- BOT_FIND_REC rec;
- GNode *node;
-
- g_return_val_if_fail(botnet != NULL, NULL);
- g_return_val_if_fail(nick != NULL, NULL);
-
- rec.key = nick;
- rec.node = NULL;
- for (node = botnet->bots->children; node != NULL; node = node->next) {
- g_node_traverse(node, 0, G_TRAVERSE_ALL, -1,
- (GNodeTraverseFunc) gnode_find_nick, &rec);
- if (rec.node != NULL) return node;
- }
- return rec.node;
-}
-
-/* check if `addr' is an IP address - this is checked to make sure that
- if we have an address like "192.168.0.*", it wouldn't match to host name
- 192.168.0.host.org */
-static int is_ip_mask(const char *addr)
-{
- while (*addr != '\0') {
- if (!i_isdigit(*addr) && *addr != '.' &&
- *addr != '*' && *addr != '?') return FALSE;
- addr++;
- }
-
- return TRUE;
-}
-
-BOT_DOWNLINK_REC *bot_downlink_find(BOTNET_REC *botnet, IPADDR *ip, const char *host)
-{
- GSList *tmp, *tmp2;
- char ipname[MAX_IP_LEN];
-
- g_return_val_if_fail(botnet != NULL, NULL);
- g_return_val_if_fail(ip != NULL, NULL);
-
- net_ip2host(ip, ipname);
-
- for (tmp = botnet->downlinks; tmp != NULL; tmp = tmp->next) {
- BOT_DOWNLINK_REC *rec = tmp->data;
-
- for (tmp2 = rec->valid_addrs; tmp2 != NULL; tmp2 = tmp2->next) {
- if (match_wildcards(tmp2->data, ipname))
- return rec;
- if (match_wildcards(tmp2->data, host) &&
- !is_ip_mask(tmp2->data))
- return rec;
- }
- }
-
- return NULL;
-}
-
-static int gnode_find_master(GNode *node, BOT_FIND_REC *rec)
-{
- BOT_REC *bot = node->data;
-
- if (bot == NULL) return FALSE;
-
- if (!bot->disconnect && bot->priority > rec->priority) {
- rec->node = node;
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOT_REC *botnet_find_master(BOTNET_REC *botnet, BOT_REC *old_master)
-{
- BOT_FIND_REC rec;
-
- g_return_val_if_fail(botnet != NULL, NULL);
-
- rec.node = NULL;
- rec.priority = old_master == NULL ? -1 : old_master->priority;
- g_node_traverse(botnet->bots, 0, G_TRAVERSE_ALL, -1,
- (GNodeTraverseFunc) gnode_find_master, &rec);
- return rec.node == NULL ? old_master : rec.node->data;
-}
-
-void botnet_set_master(BOTNET_REC *botnet, BOT_REC *bot)
-{
- g_return_if_fail(botnet != NULL);
- g_return_if_fail(bot != NULL);
-
- if (botnet->master != NULL)
- botnet->master->master = FALSE;
-
- bot->master = TRUE;
- botnet->master = bot;
-}
-
-void bot_nick_destroy(BOT_CHANNEL_REC *rec, NICK_REC *nick)
-{
- g_return_if_fail(rec != NULL);
- g_return_if_fail(nick != NULL);
-
- rec->nicks = g_slist_remove(rec->nicks, nick);
-
- g_free(nick->nick);
- g_free_not_null(nick->realname);
- g_free_not_null(nick->host);
- g_free(nick);
-}
-
-void bot_channel_destroy(BOT_IRCNET_REC *ircnet, BOT_CHANNEL_REC *rec)
-{
- g_return_if_fail(ircnet != NULL);
- g_return_if_fail(rec != NULL);
-
- ircnet->channels = g_slist_remove(ircnet->channels, rec);
-
- while (rec->nicks != NULL)
- bot_nick_destroy(rec, rec->nicks->data);
-
- g_slist_foreach(rec->banlist, (GFunc) g_free, NULL);
- g_slist_foreach(rec->ebanlist, (GFunc) g_free, NULL);
- g_slist_foreach(rec->invitelist, (GFunc) g_free, NULL);
-
- g_slist_free(rec->banlist);
- g_slist_free(rec->ebanlist);
- g_slist_free(rec->invitelist);
-
- g_free_not_null(rec->mode);
- g_free_not_null(rec->key);
- g_free(rec->name);
- g_free(rec);
-}
-
-void bot_ircnet_destroy(BOT_REC *bot, BOT_IRCNET_REC *rec)
-{
- g_return_if_fail(bot != NULL);
- g_return_if_fail(rec != NULL);
-
- bot->ircnets = g_slist_remove(bot->ircnets, bot);
-
- while (rec->channels != NULL)
- bot_channel_destroy(rec, rec->channels->data);
-
- g_free(rec->tag);
- g_free(rec->ircnet);
- g_free(rec->server);
- g_free(rec->nick);
- g_free(rec);
-}
-
-void bot_disconnect(BOT_REC *bot)
-{
- bot->disconnect = TRUE;
-
- signal_emit("bot disconnected", 1, bot);
-
- if (bot->read_tag != -1) {
- g_source_remove(bot->read_tag);
- bot->read_tag = -1;
- }
- if (bot->handle != NULL) {
- net_disconnect(bot->handle);
- bot->handle = NULL;
- }
-}
-
-static void bot_mark_disconnect(GNode *node)
-{
- BOT_REC *bot = node->data;
-
- bot->disconnect = TRUE;
-}
-
-#define bot_mark_disconnects(node) \
- g_node_traverse(node, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, \
- (GNodeTraverseFunc) bot_mark_disconnect, NULL)
-
-void bot_destroy(BOT_REC *bot)
-{
- GNode *node;
-
- g_return_if_fail(bot != NULL);
-
- node = g_node_find(bot->botnet->bots, 0, G_TRAVERSE_ALL, bot);
- if (node != NULL) {
- if (!bot->disconnect)
- bot_mark_disconnects(node);
- }
-
- bot_disconnect(bot);
-
- if (node != NULL) {
- while (node->children != NULL)
- bot_destroy(node->children->data);
- g_node_destroy(node);
- }
-
- if (bot->botnet->uplink == bot)
- bot->botnet->uplink = NULL;
- if (bot->botnet->master == bot)
- bot->botnet->master = NULL;
-
- while (bot->ircnets != NULL)
- bot_ircnet_destroy(bot, bot->ircnets->data);
-
- line_split_free(bot->buffer);
- g_free_not_null(bot->nick);
- g_free(bot);
-}
-
-void bot_downlink_destroy(BOT_DOWNLINK_REC *rec)
-{
- rec->botnet->downlinks = g_slist_remove(rec->botnet->downlinks, rec);
-
- g_slist_foreach(rec->valid_addrs, (GFunc) g_free, NULL);
- g_slist_free(rec->valid_addrs);
-
- g_free_not_null(rec->password);
- g_free(rec);
-}
-
-void bot_uplink_destroy(BOT_UPLINK_REC *rec)
-{
- rec->botnet->uplinks = g_slist_remove(rec->botnet->uplinks, rec);
-
- g_free(rec->host);
- g_free_not_null(rec->password);
- g_free(rec);
-}
-
-void botnet_disconnect(BOTNET_REC *botnet)
-{
- botnet->connected = FALSE;
-
- bot_destroy(botnet->bots->data);
- botnet->bots = NULL;
-
- if (botnet->listen_tag != -1) {
- g_source_remove(botnet->listen_tag);
- botnet->listen_tag = -1;
- }
- if (botnet->listen_handle != NULL) {
- net_disconnect(botnet->listen_handle);
- botnet->listen_handle = NULL;
- }
-}
-
-static void botnet_destroy(BOTNET_REC *botnet)
-{
- botnets = g_slist_remove(botnets, botnet);
-
- while (botnet->uplinks != NULL)
- bot_uplink_destroy(botnet->uplinks->data);
- while (botnet->downlinks != NULL)
- bot_downlink_destroy(botnet->downlinks->data);
-
- botnet_disconnect(botnet);
-
- g_free_not_null(botnet->addr);
- g_free(botnet->name);
- g_free(botnet->nick);
- g_free(botnet);
-}
-
-static void botnet_event(BOT_REC *bot, const char *data)
-{
- char *source, *target, *command, *args, *event;
- void *free_arg;
-
- if (!bot->connected)
- return;
-
- if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_GETREST,
- &source, &target, &command, &args))
- return;
-
- if (*target == '-' && target[1] == '\0')
- target = NULL;
- g_strdown(command);
-
- event = g_strconcat("botnet event ", command, NULL);
- signal_emit(event, 4, bot, args, source, target);
- g_free(event);
-
- cmd_params_free(free_arg);
-}
-
-/* broadcast the signal forward */
-static void botnet_event_broadcast(BOT_REC *bot, const char *data)
-{
- char *source, *target, *command;
- void *free_arg;
-
- if (!bot->connected)
- return;
-
- if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
- &source, &target, &command))
- return;
-
- if (g_strcasecmp(target, bot->botnet->nick) == 0) {
- /* message was for us */
- cmd_params_free(free_arg);
- return;
- }
-
- if (*target == '-' && target[1] == '\0') {
- /* broadcast */
- botnet_broadcast(bot->botnet, bot, source, command);
- } else {
- /* send to specified target */
- botnet_send_cmd(bot->botnet, source, target, command);
- }
-
- cmd_params_free(free_arg);
-}
-
-static void botnet_event_master(BOT_REC *bot, const char *data, const char *sender)
-{
- BOTNET_REC *botnet;
- BOT_REC *master;
- GNode *node;
- char *str;
-
- botnet = bot->botnet;
-
- node = bot_find_nick(bot->botnet, data);
- master = node == NULL ? NULL : node->data;
- master = botnet_find_master(bot->botnet, master);
- g_return_if_fail(master != NULL);
-
- if (node == NULL || node->data != master) {
- /* no, we don't agree with that master -
- send our own to everyone. */
- bot = NULL;
- }
-
- botnet_set_master(botnet, master);
-
- str = g_strdup_printf("MASTER %s", master->nick);
- botnet_broadcast(botnet, bot, sender, str);
- g_free(str);
-
- signal_stop_by_name("botnet event");
-}
-
-static int unescape_data(const char *input, char *output)
-{
- int len;
-
- len = 0;
- while (*input != '\0') {
- if (*input != '\\')
- *output++ = *input;
- else {
- input++;
- g_return_val_if_fail(*input != '\0', len);
- switch (*input) {
- case '\\':
- *output++ = '\\';
- break;
- case '0':
- *output++ = '\0';
- break;
- case 'r':
- *output++ = '\r';
- break;
- case 'n':
- *output++ = '\n';
- break;
- }
- }
- input++;
- len++;
- }
-
- return len;
-}
-
-static void botnet_event_file(BOT_REC *bot, const char *data, const char *sender, const char *target)
-{
- GNode *node;
- char *tempbuf, *str;
- int len;
-
- if (g_strcasecmp(target, bot->botnet->nick) != 0)
- return;
-
- node = bot_find_nick(bot->botnet, sender);
- g_return_if_fail(node != NULL);
-
- bot = node->data;
- if (bot->file_handle <= 0) {
- /* first line - data contains file name */
- str = g_strdup_printf("%s/%s", get_irssi_dir(), data);
- bot->file_handle = open(str, O_CREAT|O_TRUNC|O_WRONLY, 0600);
- g_free(str);
- } else if (*data == '\0') {
- /* no data - end of file */
- if (bot->file_handle > 0) {
- close(bot->file_handle);
- bot->file_handle = -1;
- }
- } else {
- /* file data */
- tempbuf = g_malloc(strlen(data)*2+2);
- len = unescape_data(data, tempbuf);
- write(bot->file_handle, tempbuf, len);
- g_free(tempbuf);
- }
-}
-
-static void botnet_config_read_ips(BOT_DOWNLINK_REC *rec, CONFIG_NODE *node)
-{
- GSList *tmp;
-
- g_return_if_fail(rec != NULL);
- g_return_if_fail(node != NULL);
-
- node = config_node_section(node, "valid_addrs", -1);
- tmp = node == NULL ? NULL : node->value;
- for (; tmp != NULL; tmp = tmp->next) {
- node = tmp->data;
- rec->valid_addrs = g_slist_append(rec->valid_addrs, g_strdup(node->value));
- }
-}
-
-static void botnet_config_read_uplink(BOTNET_REC *botnet, CONFIG_NODE *node)
-{
- BOT_UPLINK_REC *rec;
- char *value;
-
- g_return_if_fail(botnet != NULL);
- g_return_if_fail(node != NULL);
-
- value = config_node_get_str(node, "host", NULL);
- if (value == NULL) return; /* host required */
-
- rec = g_new0(BOT_UPLINK_REC, 1);
- rec->botnet = botnet;
- rec->host = g_strdup(value);
- rec->port = config_node_get_int(node, "port", DEFAULT_BOTNET_PORT);
- rec->password = g_strdup(config_node_get_str(node, "password", NULL));
-
- botnet->uplinks = g_slist_append(botnet->uplinks, rec);
-}
-
-static void botnet_config_read_downlink(BOTNET_REC *botnet, CONFIG_NODE *node)
-{
- BOT_DOWNLINK_REC *rec;
-
- g_return_if_fail(botnet != NULL);
- g_return_if_fail(node != NULL);
-
- rec = g_new0(BOT_DOWNLINK_REC, 1);
-
- botnet_config_read_ips(rec, node);
- if (rec->valid_addrs == NULL) {
- g_free(rec);
- return;
- }
-
- rec->botnet = botnet;
- rec->password = g_strdup(config_node_get_str(node, "password", NULL));
- botnet->downlinks = g_slist_append(botnet->downlinks, rec);
-}
-
-static void botnet_config_read_botnet(CONFIG_NODE *node)
-{
- CONFIG_NODE *subnode;
- BOTNET_REC *botnet;
- GSList *tmp;
-
- g_return_if_fail(node != NULL);
-
- if (node->key == NULL || node->value == NULL)
- return;
-
- /* New botnet */
- botnet = g_new0(BOTNET_REC, 1);
- botnet->name = g_strdup(node->key);
- botnet->nick = g_strdup(config_node_get_str(node, "nick", "bot"));
- botnet->priority = config_node_get_int(node, "priority", DEFAULT_BOTNET_PRIORITY);
- botnet->autoconnect = config_node_get_bool(node, "autoconnect", FALSE);
-
- botnet->addr = g_strdup(config_node_get_str(node, "listen_addr", NULL));
- botnet->port = config_node_get_int(node, "listen_port", DEFAULT_BOTNET_PORT);
-
- botnet->listen_tag = -1;
-
- /* read uplinks */
- subnode = config_node_section(node, "uplinks", -1);
- tmp = subnode == NULL ? NULL : subnode->value;
- for (; tmp != NULL; tmp = tmp->next)
- botnet_config_read_uplink(botnet, tmp->data);
-
- /* read downlinks */
- subnode = config_node_section(node, "downlinks", -1);
- tmp = subnode == NULL ? NULL : subnode->value;
- for (; tmp != NULL; tmp = tmp->next)
- botnet_config_read_downlink(botnet, tmp->data);
-
- botnets = g_slist_append(botnets, botnet);
-}
-
-static void botnet_config_read(void)
-{
- CONFIG_REC *config;
- CONFIG_NODE *node;
- GSList *tmp;
- char *fname;
-
- /* Read botnets from ~/.irssi/botnets */
- fname = g_strdup_printf("%s/botnets", get_irssi_dir());
- config = config_open(fname, -1);
- g_free(fname);
-
- if (config == NULL)
- return;
-
- config_parse(config);
-
- node = config_node_traverse(config, "botnets", FALSE);
- tmp = node == NULL ? NULL : node->value;
- for (; tmp != NULL; tmp = tmp->next)
- botnet_config_read_botnet(tmp->data);
- config_close(config);
-}
-
-/* FIXME: this command is just temporary */
-static void cmd_botnet(const char *data)
-{
- BOTNET_REC *botnet;
- char *str;
-
- botnet = botnets->data;
-
- str = g_strdup_printf("BCAST %s", data);
- botnet_broadcast(botnet, NULL, NULL, str);
- g_free(str);
-}
-
-static void autoconnect_botnets(void)
-{
- GSList *tmp;
-
- for (tmp = botnets; tmp != NULL; tmp = tmp->next) {
- BOTNET_REC *rec = tmp->data;
-
- if (rec->autoconnect)
- botnet_connect(rec);
- }
-}
-
-void botnet_init(void)
-{
- botnet_config_read();
- botnet_connection_init();
- botnet_users_init();
-
- signal_add("botnet event", (SIGNAL_FUNC) botnet_event);
- signal_add_last("botnet event", (SIGNAL_FUNC) botnet_event_broadcast);
- signal_add("botnet event master", (SIGNAL_FUNC) botnet_event_master);
- signal_add("botnet event file", (SIGNAL_FUNC) botnet_event_file);
- command_bind("botnet", NULL, (SIGNAL_FUNC) cmd_botnet);
-
- autoconnect_botnets();
-}
-
-void botnet_deinit(void)
-{
- while (botnets)
- botnet_destroy(botnets->data);
-
- botnet_connection_deinit();
- botnet_users_deinit();
-
- signal_remove("botnet event", (SIGNAL_FUNC) botnet_event);
- signal_remove("botnet event", (SIGNAL_FUNC) botnet_event_broadcast);
- signal_remove("botnet event master", (SIGNAL_FUNC) botnet_event_master);
- signal_remove("botnet event file", (SIGNAL_FUNC) botnet_event_file);
- command_unbind("botnet", (SIGNAL_FUNC) cmd_botnet);
-}
diff --git a/src/irc/bot/botnet.h b/src/irc/bot/botnet.h
deleted file mode 100644
index 0372de22..00000000
--- a/src/irc/bot/botnet.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#ifndef __BOT_BOTNET_H
-#define __BOT_BOTNET_H
-
-#include "nicklist.h"
-
-#define DEFAULT_BOTNET_PORT 2255
-#define DEFAULT_BOTNET_PRIORITY 5
-
-typedef struct _botnet_rec BOTNET_REC;
-
-typedef struct {
- char *name;
- GSList *nicks; /* NICK_RECs */
- unsigned int chanop:1;
-
- GSList *banlist;
- GSList *ebanlist;
- GSList *invitelist;
-
- char *mode;
- int limit;
- char *key;
-} BOT_CHANNEL_REC;
-
-typedef struct {
- char *tag; /* same as server->tag */
- char *ircnet;
- char *server;
- char *nick;
-
- GSList *channels;
-} BOT_IRCNET_REC;
-
-typedef struct {
- BOTNET_REC *botnet;
- void *link; /* NULL, BOT_UPLINK_REC or BOT_DOWNLINK_REC */
-
- unsigned int uplink:1; /* this is our uplink */
- unsigned int pass_ok:1; /* downlink's password was ok */
- unsigned int connected:1; /* bot is in this botnet now */
- unsigned int disconnect:1; /* just disconnecting this bot.. */
- unsigned int master:1; /* this bot is the bot network's current master */
-
- char *nick; /* bot's unique nick in botnet */
- int priority;
-
- GIOChannel *handle;
- int read_tag;
- LINEBUF_REC *buffer;
-
- int file_handle; /* if bot is sending a file to us */
-
- GSList *ircnets;
-} BOT_REC;
-
-typedef struct {
- BOTNET_REC *botnet;
-
- char *host;
- int port;
- char *password;
-
- time_t last_connect;
-} BOT_UPLINK_REC;
-
-typedef struct {
- BOTNET_REC *botnet;
-
- GSList *valid_addrs; /* IP/host masks where this bot is allowed to connect */
- char *password;
-} BOT_DOWNLINK_REC;
-
-struct _botnet_rec {
- unsigned int connected:1;
- unsigned int autoconnect:1;
- unsigned int reconnect:1;
-
- char *name; /* botnet name */
- char *nick; /* our nick in botnet */
- int priority; /* our priority in botnet */
-
- char *addr; /* in what address we should listen, NULL = all */
- int port; /* what port we should listen, 0 = default, -1 = don't listen */
-
- GIOChannel *listen_handle;
- int listen_tag;
-
- GSList *uplinks;
- GSList *downlinks;
-
- GNode *bots;
- BOT_REC *uplink; /* our current uplink */
- BOT_REC *master; /* link to current master */
-};
-
-extern GSList *botnets;
-
-void bot_send_cmd(BOT_REC *bot, const char *data);
-void bot_send_cmdv(BOT_REC *bot, const char *format, ...);
-
-/* broadcast a message to everyone in bot network, except for `except_bot'
- if it's not NULL. If botnet is NULL, the message is sent to all botnets. */
-void botnet_broadcast(BOTNET_REC *botnet, BOT_REC *except_bot,
- const char *source, const char *data);
-
-void botnet_send_cmd(BOTNET_REC *botnet, const char *source,
- const char *target, const char *data);
-
-int botnet_send_file(BOTNET_REC *botnet, const char *target, const char *fname);
-
-BOT_REC *botnet_find_master(BOTNET_REC *botnet, BOT_REC *old_master);
-void botnet_set_master(BOTNET_REC *botnet, BOT_REC *bot);
-
-BOTNET_REC *botnet_find(const char *name);
-GNode *bot_find_nick(BOTNET_REC *botnet, const char *nick);
-/* Return the bot who we should send the message if we wanted `nick' to get it. */
-GNode *bot_find_path(BOTNET_REC *botnet, const char *nick);
-
-BOT_DOWNLINK_REC *bot_downlink_find(BOTNET_REC *botnet, IPADDR *ip, const char *host);
-
-void bot_nick_destroy(BOT_CHANNEL_REC *rec, NICK_REC *nick);
-void bot_channel_destroy(BOT_IRCNET_REC *ircnet, BOT_CHANNEL_REC *rec);
-void bot_ircnet_destroy(BOT_REC *bot, BOT_IRCNET_REC *rec);
-
-void bot_disconnect(BOT_REC *bot);
-void bot_destroy(BOT_REC *bot);
-
-void bot_downlink_destroy(BOT_DOWNLINK_REC *rec);
-void bot_uplink_destroy(BOT_UPLINK_REC *rec);
-
-void botnet_connect(BOTNET_REC *botnet);
-void botnet_disconnect(BOTNET_REC *botnet);
-
-#endif
diff --git a/src/irc/bot/botnets.sample b/src/irc/bot/botnets.sample
deleted file mode 100644
index 01ce9684..00000000
--- a/src/irc/bot/botnets.sample
+++ /dev/null
@@ -1,15 +0,0 @@
-botnets = {
- irssinet = {
- nick = irssibot;
- priority = 5;
- autoconnect = yes;
- uplinks = (
- { host = "main.botnet.org"; password = "mypass"; }
- );
- downlinks = (
- { password = "thepass"; valid_addrs = ( "192.168.0.*" ); },
- { password = "blah"; valid_addrs = ( "*.botnet.org" ); },
- { password = "localpass"; valid_addrs = ( "127.*" ); }
- );
- };
-};
diff --git a/src/irc/bot/module.h b/src/irc/bot/module.h
deleted file mode 100644
index 3ae857fa..00000000
--- a/src/irc/bot/module.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "common.h"
-
-#define MODULE_NAME "irc/bot"
diff --git a/src/irc/bot/users.sample b/src/irc/bot/users.sample
deleted file mode 100644
index 72e534a8..00000000
--- a/src/irc/bot/users.sample
+++ /dev/null
@@ -1,18 +0,0 @@
-users =
-{
- mynick = {
- flags = oa;
- masks = (
- { mask="*!*@somewhere" },
- { mask="*!*@somewhere.else"; not_flags=a; }
- );
- };
-
- other = {
- masks = ( { mask="*!nick@home.org"; } );
- channels = (
- { channel = "#irssi";flags = oa; },
- { channel = "#chan";flags = oa; }
- );
- };
-};