2015-03-24 10:12:35 +00:00
|
|
|
/*
|
|
|
|
* xbot: Just another IRC bot
|
|
|
|
*
|
|
|
|
* Written by Aaron Blakely <aaron@ephasic.org>
|
|
|
|
**/
|
|
|
|
|
2024-03-08 10:14:06 +00:00
|
|
|
|
2015-03-24 10:12:35 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2015-04-07 18:18:24 +00:00
|
|
|
#include <stdlib.h>
|
2016-02-22 04:40:41 +00:00
|
|
|
#include <time.h>
|
|
|
|
#include <errno.h>
|
2024-03-06 02:12:10 +00:00
|
|
|
|
2015-04-07 18:18:24 +00:00
|
|
|
#include "config.h"
|
2015-03-24 10:12:35 +00:00
|
|
|
#include "irc.h"
|
2024-03-06 02:12:10 +00:00
|
|
|
#include "db.h"
|
2015-03-26 23:20:59 +00:00
|
|
|
#include "util.h"
|
|
|
|
#include "events.h"
|
2024-02-16 21:28:11 +00:00
|
|
|
#include "module.h"
|
|
|
|
#include "channel.h"
|
2024-02-21 14:24:49 +00:00
|
|
|
#include "timers.h"
|
2015-03-24 10:12:35 +00:00
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
#ifdef _WIN32
|
2024-03-08 09:18:36 +00:00
|
|
|
#include "resource.h"
|
2024-02-13 07:22:10 +00:00
|
|
|
#include <winsock2.h>
|
|
|
|
#else
|
|
|
|
#include <sys/select.h>
|
2024-03-06 09:45:01 +00:00
|
|
|
#include <unistd.h>
|
2024-02-13 07:22:10 +00:00
|
|
|
#endif
|
|
|
|
|
2016-02-22 04:40:41 +00:00
|
|
|
static time_t trespond;
|
|
|
|
|
2024-03-08 10:14:06 +00:00
|
|
|
int main(int argc, char **argv)
|
2015-03-24 10:12:35 +00:00
|
|
|
{
|
2024-03-11 10:22:05 +00:00
|
|
|
int n = 0;
|
2024-02-13 07:22:10 +00:00
|
|
|
fd_set rd;
|
|
|
|
struct irc_conn bot;
|
|
|
|
struct timeval tv;
|
2024-02-21 14:24:49 +00:00
|
|
|
struct timeval last_ping;
|
2024-03-08 10:14:06 +00:00
|
|
|
char conf[1024];
|
2024-03-11 10:22:05 +00:00
|
|
|
unsigned long ssl_err;
|
2024-02-21 14:24:49 +00:00
|
|
|
|
2024-02-16 21:28:11 +00:00
|
|
|
char *p;
|
2024-03-11 10:22:05 +00:00
|
|
|
char buf[1024];
|
|
|
|
int bytesRecv = 0;
|
|
|
|
int totalBytesRecv = 0;
|
|
|
|
|
2024-02-24 01:57:59 +00:00
|
|
|
|
2024-03-08 09:18:36 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
HICON hIcon;
|
|
|
|
|
|
|
|
hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
|
|
|
|
SendMessage(GetConsoleWindow(), WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
|
|
|
SetConsoleTitle("xbot [starting]");
|
|
|
|
#endif
|
|
|
|
|
2024-02-24 01:57:59 +00:00
|
|
|
bot.in = calloc(INBUF_SIZE, sizeof(char));
|
|
|
|
bot.out = calloc(OUTBUF_SIZE, sizeof(char));
|
|
|
|
|
2024-02-21 14:24:49 +00:00
|
|
|
last_ping.tv_sec = time(NULL);
|
2015-03-26 23:20:59 +00:00
|
|
|
|
2024-02-25 17:09:24 +00:00
|
|
|
set_bot(&bot);
|
2024-03-06 08:50:22 +00:00
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
init_events();
|
2024-02-21 14:24:49 +00:00
|
|
|
init_timers();
|
2024-02-13 23:47:20 +00:00
|
|
|
init_mods();
|
2024-03-08 10:14:06 +00:00
|
|
|
|
|
|
|
strlcpy(conf, "xbot.cfg", sizeof conf);
|
|
|
|
|
|
|
|
if (argc > 1)
|
|
|
|
{
|
|
|
|
if (argc == 2)
|
|
|
|
{
|
|
|
|
if (!strcmp(argv[1], "-v"))
|
|
|
|
{
|
|
|
|
printf("xbot version: %s\n", VERSION);
|
|
|
|
printf("Compiled on: %s %s\n\n", __DATE__, __TIME__);
|
|
|
|
printf("Written by Aaron Blakely <aaron@ephasic.org>\n");
|
|
|
|
printf("Licensed under the MIT License\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (!strcmp(argv[1], "-h"))
|
|
|
|
{
|
|
|
|
printf("Usage: xbot [-v] [-h] [-c <config file>]\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (argc == 3)
|
|
|
|
{
|
|
|
|
if (!strcmp(argv[1], "-c"))
|
|
|
|
{
|
|
|
|
free(bot.in);
|
|
|
|
free(bot.out);
|
|
|
|
|
|
|
|
bot.in = calloc(INBUF_SIZE, sizeof(char));
|
|
|
|
bot.out = calloc(OUTBUF_SIZE, sizeof(char));
|
|
|
|
|
|
|
|
strlcpy(conf, argv[2], sizeof conf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
// Read the config
|
2024-03-08 10:14:06 +00:00
|
|
|
bot = read_config(bot, conf);
|
2015-03-24 10:12:35 +00:00
|
|
|
|
2024-03-09 08:40:06 +00:00
|
|
|
log_init(bot.log_file);
|
|
|
|
|
2024-03-06 02:12:10 +00:00
|
|
|
// check if the db exists, if not, create it
|
2024-03-06 09:45:01 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
if (access(bot.db_file, 0) == -1)
|
|
|
|
#else
|
2024-03-06 02:12:10 +00:00
|
|
|
if (access(bot.db_file, F_OK) == -1)
|
2024-03-06 09:45:01 +00:00
|
|
|
#endif
|
2024-03-06 02:12:10 +00:00
|
|
|
{
|
2024-03-09 09:38:58 +00:00
|
|
|
xlog("[DB] Creating database file: %s\n", bot.db_file);
|
2024-03-06 02:12:10 +00:00
|
|
|
bot.db = (struct db_table *)malloc(sizeof(struct db_table));
|
|
|
|
memset(bot.db, 0, sizeof(struct db_table));
|
2024-03-06 08:50:22 +00:00
|
|
|
set_bot_db(bot.db);
|
2024-03-06 02:12:10 +00:00
|
|
|
|
|
|
|
bot.db->count = 0;
|
|
|
|
bot.db->hashes = NULL;
|
|
|
|
|
2024-03-06 08:50:22 +00:00
|
|
|
db_write(bot.db, bot.db_file);
|
2024-03-06 02:12:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-03-09 09:38:58 +00:00
|
|
|
xlog("[DB] Reading database file: %s\n", bot.db_file);
|
2024-03-06 08:50:22 +00:00
|
|
|
bot.db = db_read(bot.db_file);
|
|
|
|
set_bot_db(bot.db);
|
2024-03-06 02:12:10 +00:00
|
|
|
}
|
|
|
|
|
2024-03-06 08:50:22 +00:00
|
|
|
// run autoload
|
|
|
|
run_autoload(&bot);
|
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
// Connect to the server
|
2024-03-09 09:38:58 +00:00
|
|
|
xlog("[IRC] Connecting to %s...\n", bot.host);
|
2015-03-24 10:12:35 +00:00
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
irc_connect(&bot);
|
2024-02-24 01:57:59 +00:00
|
|
|
trespond = time(NULL);
|
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
irc_auth(&bot);
|
2016-02-22 04:40:41 +00:00
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
for (;;)
|
|
|
|
{
|
2024-02-21 14:24:49 +00:00
|
|
|
fire_timers();
|
|
|
|
fire_handler(&bot, TICK, NULL);
|
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
FD_ZERO(&rd);
|
|
|
|
|
2024-03-11 10:22:05 +00:00
|
|
|
if (bot.use_ssl)
|
|
|
|
{
|
|
|
|
FD_SET(SSL_get_fd(bot.ssl), &rd);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-03-13 11:50:58 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
FD_SET(bot.srv_fd, &rd);
|
|
|
|
#else
|
2024-03-11 10:22:05 +00:00
|
|
|
FD_SET(0, &rd);
|
|
|
|
FD_SET(fileno(bot.srv_fd), &rd);
|
2024-02-13 07:22:10 +00:00
|
|
|
#endif
|
2024-03-13 11:50:58 +00:00
|
|
|
}
|
|
|
|
|
2024-02-21 14:24:49 +00:00
|
|
|
tv.tv_sec = 1;
|
2024-02-13 07:22:10 +00:00
|
|
|
tv.tv_usec = 0;
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
n = select(bot.srv_fd, &rd, NULL, NULL, &tv);
|
|
|
|
if (n == SOCKET_ERROR)
|
2016-02-22 04:40:41 +00:00
|
|
|
{
|
2024-02-13 07:22:10 +00:00
|
|
|
eprint("xbot: error on select(): %d\n", WSAGetLastError());
|
|
|
|
closesocket(bot.srv_fd);
|
|
|
|
WSACleanup();
|
2016-02-22 04:40:41 +00:00
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
return -1;
|
2016-02-22 04:40:41 +00:00
|
|
|
}
|
2024-02-13 07:22:10 +00:00
|
|
|
#else
|
2024-03-11 10:22:05 +00:00
|
|
|
n = select(bot.use_ssl ? bot.ssl_fd + 1 : fileno(bot.srv_fd) + 1, &rd, 0, 0, &tv);
|
2024-02-24 01:57:59 +00:00
|
|
|
if (n < 0)
|
2016-02-22 04:40:41 +00:00
|
|
|
{
|
2024-02-13 07:22:10 +00:00
|
|
|
if (errno == EINTR)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
eprint("xbot: error on select()\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
else if (n == 0)
|
|
|
|
{
|
|
|
|
if (time(NULL) - trespond >= 300)
|
|
|
|
{
|
|
|
|
eprint("xbot shutting down: parse timeout\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-02-21 14:24:49 +00:00
|
|
|
if (time(NULL) - last_ping.tv_sec >= 120)
|
|
|
|
{
|
|
|
|
last_ping.tv_sec = time(NULL);
|
|
|
|
irc_raw(&bot, "PING %s", bot.host);
|
|
|
|
}
|
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
continue;
|
|
|
|
}
|
2024-03-13 11:50:58 +00:00
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
#ifdef _WIN32
|
2024-03-13 11:50:58 +00:00
|
|
|
if (FD_ISSET(bot.use_ssl ? bot.ssl_fd : bot.srv_fd, &rd))
|
|
|
|
#else
|
|
|
|
if (FD_ISSET(bot.use_ssl ? bot.ssl_fd : fileno(bot.srv_fd), &rd))
|
|
|
|
#endif
|
2024-02-13 07:22:10 +00:00
|
|
|
{
|
2024-03-13 11:50:58 +00:00
|
|
|
if (bot.use_ssl)
|
2024-03-13 00:38:52 +00:00
|
|
|
{
|
2024-03-13 11:50:58 +00:00
|
|
|
bytesRecv = SSL_read(bot.ssl, bot.in, INBUF_SIZE);
|
|
|
|
if (bytesRecv <= 0)
|
2024-03-13 00:38:52 +00:00
|
|
|
{
|
2024-03-13 11:50:58 +00:00
|
|
|
eprint("xbot: error on SSL_read()\n");
|
|
|
|
|
|
|
|
ssl_err = ERR_get_error();
|
|
|
|
if (ssl_err)
|
|
|
|
{
|
|
|
|
eprint("SSL error: %s\n", ERR_error_string(ssl_err, NULL));
|
|
|
|
}
|
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
|
2024-03-13 00:38:52 +00:00
|
|
|
return -1;
|
2024-03-13 11:50:58 +00:00
|
|
|
|
2024-03-13 00:38:52 +00:00
|
|
|
}
|
2016-02-22 04:40:41 +00:00
|
|
|
|
2024-03-13 11:50:58 +00:00
|
|
|
bot.in[bytesRecv] = '\0';
|
|
|
|
printf("recv: %s\r\n", bot.in);
|
|
|
|
|
|
|
|
while (1)
|
2024-03-13 00:38:52 +00:00
|
|
|
{
|
2024-03-13 11:50:58 +00:00
|
|
|
// remove \r
|
|
|
|
p = strchr(bot.in, '\r');
|
|
|
|
p = strchr(bot.in, '\n');
|
|
|
|
if (p == NULL)
|
|
|
|
break;
|
2024-03-13 00:38:52 +00:00
|
|
|
|
2024-03-13 11:50:58 +00:00
|
|
|
*p = '\0';
|
2024-03-13 00:38:52 +00:00
|
|
|
|
2024-03-13 11:50:58 +00:00
|
|
|
// remove \r at end of line
|
|
|
|
if (p[-1] == '\r')
|
|
|
|
p[-1] = '\0';
|
2024-03-13 00:38:52 +00:00
|
|
|
|
|
|
|
|
2024-03-13 11:50:58 +00:00
|
|
|
printf("recv: %s\r\n", bot.in);
|
|
|
|
irc_parse_raw(&bot, bot.in);
|
|
|
|
memmove(bot.in, p + 1, strlen(p + 1) + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(p);
|
2024-02-13 23:47:20 +00:00
|
|
|
}
|
2024-03-13 00:38:52 +00:00
|
|
|
else
|
|
|
|
{
|
2024-03-13 11:50:58 +00:00
|
|
|
#ifdef _WIN32
|
2024-03-13 00:38:52 +00:00
|
|
|
bytesRecv = recv(bot.srv_fd, bot.in, INBUF_SIZE, 0);
|
|
|
|
if (bytesRecv == SOCKET_ERROR)
|
|
|
|
{
|
|
|
|
eprint("Error receiving data: %d\n", WSAGetLastError());
|
|
|
|
closesocket(bot.srv_fd);
|
|
|
|
WSACleanup();
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bytesRecv == 0)
|
|
|
|
{
|
|
|
|
eprint("xbot: remote host closed connection\n");
|
|
|
|
return 0;
|
|
|
|
}
|
2024-02-13 23:47:20 +00:00
|
|
|
|
2024-03-13 11:50:58 +00:00
|
|
|
bot.in[bytesRecv] = '\0';
|
2024-03-11 10:22:05 +00:00
|
|
|
|
2024-03-13 11:50:58 +00:00
|
|
|
printf("recv: %s\r\n", bot.in);
|
2024-03-11 10:22:05 +00:00
|
|
|
|
2024-03-13 11:50:58 +00:00
|
|
|
// split bot.in into lines by \r\n and parse each one
|
2024-03-11 10:22:05 +00:00
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
// remove \r
|
|
|
|
p = strchr(bot.in, '\r');
|
|
|
|
p = strchr(bot.in, '\n');
|
|
|
|
if (p == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
*p = '\0';
|
|
|
|
irc_parse_raw(&bot, bot.in);
|
|
|
|
memmove(bot.in, p + 1, strlen(p + 1) + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(p);
|
2024-03-13 11:50:58 +00:00
|
|
|
#else
|
2024-03-11 10:22:05 +00:00
|
|
|
if (fgets(bot.in, INBUF_SIZE, bot.srv_fd) == NULL)
|
|
|
|
{
|
|
|
|
eprint("xbot: remote host closed connection\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("recv: [%s]\n", bot.in);
|
|
|
|
irc_parse_raw(&bot, bot.in);
|
2024-03-13 11:50:58 +00:00
|
|
|
#endif
|
2024-02-13 07:22:10 +00:00
|
|
|
}
|
2024-02-16 21:28:11 +00:00
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
trespond = time(NULL);
|
|
|
|
}
|
2024-02-21 14:24:49 +00:00
|
|
|
|
2024-02-13 07:22:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2016-02-22 04:40:41 +00:00
|
|
|
}
|