This commit is contained in:
Aaron Blakely 2024-02-23 19:57:59 -06:00
parent c4e1ad5af7
commit 4d025dde85
14 changed files with 263 additions and 37 deletions

View File

@ -50,6 +50,8 @@ struct channel
struct user *users; struct user *users;
}; };
extern struct channel *channels[60];
void add_channel(char *name); void add_channel(char *name);
void remove_channel(char *name); void remove_channel(char *name);
void add_user_to_channel(char *user, char *host, char *chan); void add_user_to_channel(char *user, char *host, char *chan);
@ -61,6 +63,10 @@ void update_server(char *nick, char *server);
void update_realname(char *nick, char *real_name); void update_realname(char *nick, char *real_name);
void user_quit(char *nick); void user_quit(char *nick);
void set_realname(char *nick, char *real_name); void set_realname(char *nick, char *real_name);
struct user *get_user(char *nick);
MY_API char *get_user_host(char *nick);
MY_API char *get_user_user(char *nick);
#ifdef _WIN32 #ifdef _WIN32
MY_API BOOL is_op(char *chan, char *nick); MY_API BOOL is_op(char *chan, char *nick);

View File

@ -34,6 +34,7 @@ struct handler
struct ev_handler *evhands; struct ev_handler *evhands;
}; };
extern struct handler *handlers[512];
void init_events(); void init_events();
MY_API int add_handler(char *type, void *handler); MY_API int add_handler(char *type, void *handler);

View File

@ -13,6 +13,8 @@
#include <winsock2.h> #include <winsock2.h>
#endif #endif
#define OUTBUF_SIZE 60000
#define INBUF_SIZE 60000
struct irc_conn struct irc_conn
{ {
@ -29,8 +31,8 @@ struct irc_conn
char real_name[512]; char real_name[512];
// I/O Buffers // I/O Buffers
char out[4096]; char *out;
char in[4096]; char *in;
}; };
typedef struct handler event_handler; typedef struct handler event_handler;
@ -53,7 +55,9 @@ MY_API void irc_privmsg(struct irc_conn *bot, char *to, char *fmt, ...);
MY_API void irc_raw(struct irc_conn *bot, char *fmt, ...); MY_API void irc_raw(struct irc_conn *bot, char *fmt, ...);
MY_API void irc_join(struct irc_conn *bot, char *channel); MY_API void irc_join(struct irc_conn *bot, char *channel);
MY_API void irc_part(struct irc_conn *bot, char *channel, char *reason); MY_API void irc_part(struct irc_conn *bot, char *channel, char *reason);
MY_API void irc_ban(struct irc_conn *bot, char *channel, char *nick);
MY_API void irc_kick(struct irc_conn *bot, char *channel, char *user, char *reason);
MY_API void irc_mode(struct irc_conn *bot, char *channel, char *mode);
void irc_parse_raw(struct irc_conn *bot, char *raw); void irc_parse_raw(struct irc_conn *bot, char *raw);

View File

@ -32,6 +32,8 @@ struct mods {
struct module *modules; struct module *modules;
}; };
extern struct mods *mods;
void init_mods(); void init_mods();
void load_module(struct irc_conn *bot, char *where, char *stype, char *file); void load_module(struct irc_conn *bot, char *where, char *stype, char *file);
void unload_module(struct irc_conn *bot, char *where, char *file); void unload_module(struct irc_conn *bot, char *where, char *file);

View File

@ -37,6 +37,8 @@ struct timers
struct timer *timers; struct timer *timers;
}; };
extern struct timers *timers;;
void init_timers(); void init_timers();
MY_API int add_timer(struct irc_conn *bot, int interval, int repeat, void *handler, void *data); MY_API int add_timer(struct irc_conn *bot, int interval, int repeat, void *handler, void *data);

7
mods/chanop/Makefile Executable file
View File

@ -0,0 +1,7 @@
CC=gcc
CFLAGS=-fPIC -I../../lib
OBJ=../chanop.so
main:
$(CC) -shared -o $(OBJ) $(CFLAGS) ./chanop.c
@echo "All Done!"

108
mods/chanop/chanop.c Executable file
View File

@ -0,0 +1,108 @@
#include "channel.h"
#define MY_DLL_EXPORTS 1
#include "util.h"
#include "irc.h"
#include "events.h"
#include "module.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <windef.h>
BOOL hasAccess(char *user, char *chan)
{
if (is_op(chan, user) || is_halfop(chan, user))
{
return TRUE;
}
else
{
return FALSE;
}
}
#else
#include <stdbool.h>
bool hasAccess(char *user, char *chan)
{
if (is_op(chan, user) || is_halfop(chan, user))
{
return true;
}
else
{
return false;
}
}
#endif
MY_API void chanop_privmsg_handler(struct irc_conn *bot, char *user, char *host, char *chan, const char *text)
{
char *nick;
char *buf = (char *)malloc(sizeof(char *) * 500);
int sn = 1;
if (strstr(text, "!kb") != NULL)
{
if (!hasAccess(user, chan))
goto NO_ACCESS;
nick = skip((char *)text, ' ');
sprintf(buf, "Requested by %s", user);
irc_ban(bot, chan, nick);
irc_kick(bot, chan, nick, buf);
}
else if (strstr(text, "!op") != NULL)
{
if (!hasAccess(user, chan))
goto NO_ACCESS;
nick = skip((char *)text, ' ');
irc_raw(bot, "MODE %s +o %s", chan, nick);
}
else if (strstr(text, "!deop") != NULL)
{
if (!hasAccess(user, chan))
goto NO_ACCESS;
nick = skip((char *)text, ' ');
irc_raw(bot, "MODE %s -o %s", chan, nick);
}
else if (strstr(text, "!voice") != NULL)
{
if (!hasAccess(user, chan))
goto NO_ACCESS;
nick = skip((char *)text, ' ');
irc_raw(bot, "MODE %s +v %s", chan, nick);
}
else if (strstr(text, "!devoice") != NULL)
{
if (!hasAccess(user, chan))
goto NO_ACCESS;
nick = skip((char *)text, ' ');
irc_raw(bot, "MODE %s -v %s", chan, nick);
}
sn = 0;
NO_ACCESS:
if (sn)
irc_notice(bot, user, "You do not have access to use that command in %s", chan);
free(buf);
}
MY_API void mod_init()
{
register_module("chanop", "Aaron Blakely", "v0.1", "Channel Operator module");
add_handler(PRIVMSG_CHAN, chanop_privmsg_handler);
}
MY_API void mod_unload()
{
unregister_module("chanop");
del_handler(PRIVMSG_CHAN, chanop_privmsg_handler);
}

View File

@ -10,7 +10,6 @@
#ifdef _WIN32 #ifdef _WIN32
#define BUFFER_SIZE 512 #define BUFFER_SIZE 512
#include <windows.h> #include <windows.h>
DWORD startTick;
void parseUptime(const char *output, struct irc_conn *bot, const char *where) { void parseUptime(const char *output, struct irc_conn *bot, const char *where) {
const char *keyword = "Statistics since "; const char *keyword = "Statistics since ";
@ -140,12 +139,13 @@ char *executeCommand(const char *command)
MY_API void up(struct irc_conn *bot, char *user, char *host, char *chan, char *text) MY_API void up(struct irc_conn *bot, char *user, char *host, char *chan, char *text)
{ {
#ifdef _WIN32 #ifdef _WIN32
const char *command = "net statistics server"; char *output;
char *output = executeCommand(command);
if (!strcmp(text, "!uptime")) if (!strcmp(text, "!uptime"))
{ {
output = executeCommand("net statistics server");
parseUptime(output, bot, chan); parseUptime(output, bot, chan);
free(output); free(output);
} }
#else #else
@ -165,10 +165,6 @@ MY_API void up(struct irc_conn *bot, char *user, char *host, char *chan, char *t
MY_API void mod_init() MY_API void mod_init()
{ {
#ifdef _WIN32
startTick = GetTickCount();
#endif
register_module("uptime", "Aaron Blakely", "v0.1", "Uptime module"); register_module("uptime", "Aaron Blakely", "v0.1", "Uptime module");
printf("installing up handler\n"); printf("installing up handler\n");
add_handler(PRIVMSG_CHAN, up); add_handler(PRIVMSG_CHAN, up);

View File

@ -49,9 +49,28 @@ void remove_channel(char *name)
} }
} }
struct user *get_user(char *nick)
{
int i, j;
for (i = 0; i < chan_count; i++)
{
for (j = 0; j < channels[i]->user_count; j++)
{
if (!strcmp(channels[i]->users[j].nick, nick))
{
return &channels[i]->users[j];
}
}
}
return NULL;
}
void add_user_to_channel(char *user, char *host, char *chan) void add_user_to_channel(char *user, char *host, char *chan)
{ {
int i; int i;
struct user *u, *uc;
#ifdef _WIN32 #ifdef _WIN32
BOOL is_op, is_voice, is_halfop, is_owner, is_admin; BOOL is_op, is_voice, is_halfop, is_owner, is_admin;
@ -107,6 +126,21 @@ void add_user_to_channel(char *user, char *host, char *chan)
{ {
if (!strcmp(channels[i]->name, chan)) if (!strcmp(channels[i]->name, chan))
{ {
if (get_user(user) != NULL)
{
u = get_user(user);
u->is_op = is_op | is_owner | is_admin;
u->is_voice = is_voice | is_halfop | is_op | is_owner | is_admin;
u->is_halfop = is_halfop;
u->is_owner = is_owner;
u->is_admin = is_admin;
channels[i]->users[channels[i]->user_count] = *u;
channels[i]->user_count++;
return;
}
strlcpy(channels[i]->users[channels[i]->user_count].nick, user, 50); strlcpy(channels[i]->users[channels[i]->user_count].nick, user, 50);
strlcpy(channels[i]->users[channels[i]->user_count].host, host, 256); strlcpy(channels[i]->users[channels[i]->user_count].host, host, 256);
@ -267,6 +301,43 @@ void set_realname(char *nick, char *real_name)
} }
} }
MY_API char *get_user_host(char *nick)
{
int i, j;
for (i = 0; i < chan_count; i++)
{
for (j = 0; j < channels[i]->user_count; j++)
{
if (!strcmp(channels[i]->users[j].nick, nick))
{
return channels[i]->users[j].host;
}
}
}
return NULL;
}
char *get_user_user(char *nick)
{
int i, j;
for (i = 0; i < chan_count; i++)
{
for (j = 0; j < channels[i]->user_count; j++)
{
if (!strcmp(channels[i]->users[j].nick, nick))
{
return channels[i]->users[j].user;
}
}
}
return NULL;
}
#ifdef _WIN32 #ifdef _WIN32
MY_API BOOL is_op(char *chan, char *nick) MY_API BOOL is_op(char *chan, char *nick)
#else #else

View File

@ -11,13 +11,8 @@
#include <ctype.h> #include <ctype.h>
#endif #endif
struct handler *privmsg_self;
struct handler *privmsg_chan;
struct handler *chan_join;
struct handler *irc_connected;
int handlers_count = 0;
struct handler *handlers[512]; struct handler *handlers[512];
int handlers_count = 0;
void init_event_type(char *type) void init_event_type(char *type)
{ {
@ -94,10 +89,10 @@ MY_API void del_handler(char *type, void *handler)
void fire_handler(struct irc_conn *bot, char *type, ...) void fire_handler(struct irc_conn *bot, char *type, ...)
{ {
va_list args; va_list args;
char *usr = calloc(1, 64); char *usr;
char *host = calloc(1, 512); char *host;
char *chan = calloc(1, 64); char *chan;
char *text = calloc(1, 512); char *text;
int i, j; int i, j;
void (*handler)(); void (*handler)();
char *cmd, *arg, *modpath; char *cmd, *arg, *modpath;

View File

@ -68,6 +68,9 @@ void irc_connect(struct irc_conn *bot)
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *res, *r; struct addrinfo *res, *r;
bot->in = calloc(60000, sizeof(char));
bot->out = calloc(60000, sizeof(char));
memset(&hints, 0, sizeof hints); memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
@ -142,9 +145,10 @@ void irc_raw(struct irc_conn *bot, char *fmt, ...)
{ {
va_list ap; va_list ap;
char outbuf[4096]; char outbuf[4096];
char *p;
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(bot->out, sizeof bot->out, fmt, ap); vsnprintf(bot->out, OUTBUF_SIZE, fmt, ap);
va_end(ap); va_end(ap);
sprintf(outbuf, "%s\r\n", bot->out); sprintf(outbuf, "%s\r\n", bot->out);
@ -175,6 +179,29 @@ void irc_part(struct irc_conn *bot, char *chan, char *reason)
irc_raw(bot, "PART %s :%s", chan, reason); irc_raw(bot, "PART %s :%s", chan, reason);
} }
void irc_ban(struct irc_conn *bot, char *channel, char *user)
{
char *host = get_user_host(user);
char *un = get_user_user(user);
irc_raw(bot, "MODE %s +b *!%s@%s", channel, un, host);
}
void irc_kick(struct irc_conn *bot, char *channel, char *user, char *reason)
{
if (!reason)
{
reason = "";
}
irc_raw(bot, "KICK %s %s :%s", channel, user, reason);
}
void irc_mode(struct irc_conn *bot, char *channel, char *mode)
{
irc_raw(bot, "MODE %s %s", channel, mode);
}
void irc_ctcp(struct irc_conn *bot, char *to, char *fmt, ...) void irc_ctcp(struct irc_conn *bot, char *to, char *fmt, ...)
{ {
char msg_[4096]; char msg_[4096];
@ -192,8 +219,6 @@ void irc_parse_raw(struct irc_conn *bot, char *raw)
char *user, *host, *par, *text, *chan, *nick, *nicks, *tmp; char *user, *host, *par, *text, *chan, *nick, *nicks, *tmp;
user = bot->host; user = bot->host;
text = calloc(1, strlen(raw) + 1);
if (!raw || !*raw) if (!raw || !*raw)
{ {
return; return;
@ -334,14 +359,20 @@ void irc_parse_raw(struct irc_conn *bot, char *raw)
while (nick) while (nick)
{ {
add_user_to_channel(nick, "", chan);
tmp = nick; tmp = nick;
if (nick[0] == '@' || nick[0] == '+' || nick[0] == '%' || nick[0] == '~' || nick[0] == '&') if (nick[0] == '@' || nick[0] == '+' || nick[0] == '%' || nick[0] == '~' || nick[0] == '&')
{ {
tmp++; tmp++;
} }
if (get_user(tmp))
{
nick = strtok(NULL, " ");
continue;
}
add_user_to_channel(nick, "", chan);
irc_raw(bot, "WHO %s", tmp); irc_raw(bot, "WHO %s", tmp);
nick = strtok(NULL, " "); nick = strtok(NULL, " ");
} }
@ -376,4 +407,5 @@ void irc_parse_raw(struct irc_conn *bot, char *raw)
fire_handler(bot, NICK_MYSELF, user, text); fire_handler(bot, NICK_MYSELF, user, text);
} }
} }
} }

View File

@ -23,7 +23,6 @@
#include <sys/select.h> #include <sys/select.h>
#endif #endif
static time_t trespond; static time_t trespond;
int main() int main()
@ -32,15 +31,15 @@ int main()
fd_set rd; fd_set rd;
struct irc_conn bot; struct irc_conn bot;
struct timeval tv; struct timeval tv;
struct timeval last_ping; struct timeval last_ping;
char *p; char *p;
int bytesRecv; int bytesRecv;
bot.in = calloc(INBUF_SIZE, sizeof(char));
bot.out = calloc(OUTBUF_SIZE, sizeof(char));
last_ping.tv_sec = time(NULL); last_ping.tv_sec = time(NULL);
init_events(); init_events();
@ -54,6 +53,8 @@ int main()
printf("Connecting to %s...\n", bot.host); printf("Connecting to %s...\n", bot.host);
irc_connect(&bot); irc_connect(&bot);
trespond = time(NULL);
irc_auth(&bot); irc_auth(&bot);
for (;;) for (;;)
@ -84,7 +85,7 @@ int main()
} }
#else #else
n = select(fileno(bot.srv_fd) + 1, &rd, 0, 0, &tv); n = select(fileno(bot.srv_fd) + 1, &rd, 0, 0, &tv);
if (n < 0) if (n < 0)
{ {
if (errno == EINTR) if (errno == EINTR)
continue; continue;
@ -112,7 +113,7 @@ int main()
#ifdef _WIN32 #ifdef _WIN32
if (FD_ISSET(bot.srv_fd, &rd)) if (FD_ISSET(bot.srv_fd, &rd))
{ {
bytesRecv = recv(bot.srv_fd, bot.in, sizeof(bot.in), 0); bytesRecv = recv(bot.srv_fd, bot.in, INBUF_SIZE, 0);
if (bytesRecv == SOCKET_ERROR) if (bytesRecv == SOCKET_ERROR)
{ {
eprint("Error receiving data: %d\n", WSAGetLastError()); eprint("Error receiving data: %d\n", WSAGetLastError());
@ -134,7 +135,6 @@ int main()
// split bot.in into lines by \r\n and parse each one // split bot.in into lines by \r\n and parse each one
while (1) while (1)
{ {
// remove \r // remove \r
@ -147,10 +147,12 @@ int main()
irc_parse_raw(&bot, bot.in); irc_parse_raw(&bot, bot.in);
memmove(bot.in, p + 1, strlen(p + 1) + 1); memmove(bot.in, p + 1, strlen(p + 1) + 1);
} }
free(p);
#else #else
if (FD_ISSET(fileno(bot.srv_fd), &rd)) if (FD_ISSET(fileno(bot.srv_fd), &rd))
{ {
if (fgets(bot.in, sizeof bot.in, bot.srv_fd) == NULL) if (fgets(bot.in, INBUF_SIZE, bot.srv_fd) == NULL)
{ {
eprint("xbot: remote host closed connection\n"); eprint("xbot: remote host closed connection\n");
return 0; return 0;

View File

@ -6,7 +6,7 @@
#include "util.h" #include "util.h"
#include "irc.h" #include "irc.h"
struct timers *timers;; struct timers *timers;
int delete_queue[512]; int delete_queue[512];
void init_timers() void init_timers()

View File

@ -3,7 +3,7 @@
bot: bot:
{ {
verbose = 1; verbose = 1;
nick = "X"; nick = "_";
user = "xbot"; user = "xbot";
admin = "ab3800"; admin = "ab3800";
}; };
@ -16,7 +16,7 @@ server:
mods: mods:
{ {
autoload = ("autojoin", "hello", "uptime"); autoload = ("chanop", "autojoin", "hello", "uptime");
blacklist = (); blacklist = ();
# config option for mods/autojoin.so # config option for mods/autojoin.so