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;
};
extern struct channel *channels[60];
void add_channel(char *name);
void remove_channel(char *name);
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 user_quit(char *nick);
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
MY_API BOOL is_op(char *chan, char *nick);

View File

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

View File

@ -13,6 +13,8 @@
#include <winsock2.h>
#endif
#define OUTBUF_SIZE 60000
#define INBUF_SIZE 60000
struct irc_conn
{
@ -29,8 +31,8 @@ struct irc_conn
char real_name[512];
// I/O Buffers
char out[4096];
char in[4096];
char *out;
char *in;
};
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_join(struct irc_conn *bot, char *channel);
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);

View File

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

View File

@ -37,6 +37,8 @@ struct timers
struct timer *timers;
};
extern struct timers *timers;;
void init_timers();
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
#define BUFFER_SIZE 512
#include <windows.h>
DWORD startTick;
void parseUptime(const char *output, struct irc_conn *bot, const char *where) {
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)
{
#ifdef _WIN32
const char *command = "net statistics server";
char *output = executeCommand(command);
char *output;
if (!strcmp(text, "!uptime"))
{
output = executeCommand("net statistics server");
parseUptime(output, bot, chan);
free(output);
}
#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()
{
#ifdef _WIN32
startTick = GetTickCount();
#endif
register_module("uptime", "Aaron Blakely", "v0.1", "Uptime module");
printf("installing up handler\n");
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)
{
int i;
struct user *u, *uc;
#ifdef _WIN32
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 (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].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
MY_API BOOL is_op(char *chan, char *nick)
#else

View File

@ -11,13 +11,8 @@
#include <ctype.h>
#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];
int handlers_count = 0;
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, ...)
{
va_list args;
char *usr = calloc(1, 64);
char *host = calloc(1, 512);
char *chan = calloc(1, 64);
char *text = calloc(1, 512);
char *usr;
char *host;
char *chan;
char *text;
int i, j;
void (*handler)();
char *cmd, *arg, *modpath;

View File

@ -68,6 +68,9 @@ void irc_connect(struct irc_conn *bot)
struct addrinfo hints;
struct addrinfo *res, *r;
bot->in = calloc(60000, sizeof(char));
bot->out = calloc(60000, sizeof(char));
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
@ -142,9 +145,10 @@ void irc_raw(struct irc_conn *bot, char *fmt, ...)
{
va_list ap;
char outbuf[4096];
char *p;
va_start(ap, fmt);
vsnprintf(bot->out, sizeof bot->out, fmt, ap);
vsnprintf(bot->out, OUTBUF_SIZE, fmt, ap);
va_end(ap);
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);
}
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, ...)
{
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;
user = bot->host;
text = calloc(1, strlen(raw) + 1);
if (!raw || !*raw)
{
return;
@ -334,14 +359,20 @@ void irc_parse_raw(struct irc_conn *bot, char *raw)
while (nick)
{
add_user_to_channel(nick, "", chan);
tmp = nick;
if (nick[0] == '@' || nick[0] == '+' || nick[0] == '%' || nick[0] == '~' || nick[0] == '&')
{
tmp++;
}
if (get_user(tmp))
{
nick = strtok(NULL, " ");
continue;
}
add_user_to_channel(nick, "", chan);
irc_raw(bot, "WHO %s", tmp);
nick = strtok(NULL, " ");
}
@ -376,4 +407,5 @@ void irc_parse_raw(struct irc_conn *bot, char *raw)
fire_handler(bot, NICK_MYSELF, user, text);
}
}
}

View File

@ -23,7 +23,6 @@
#include <sys/select.h>
#endif
static time_t trespond;
int main()
@ -32,15 +31,15 @@ int main()
fd_set rd;
struct irc_conn bot;
struct timeval tv;
struct timeval last_ping;
char *p;
int bytesRecv;
bot.in = calloc(INBUF_SIZE, sizeof(char));
bot.out = calloc(OUTBUF_SIZE, sizeof(char));
last_ping.tv_sec = time(NULL);
init_events();
@ -54,6 +53,8 @@ int main()
printf("Connecting to %s...\n", bot.host);
irc_connect(&bot);
trespond = time(NULL);
irc_auth(&bot);
for (;;)
@ -84,7 +85,7 @@ int main()
}
#else
n = select(fileno(bot.srv_fd) + 1, &rd, 0, 0, &tv);
if (n < 0)
if (n < 0)
{
if (errno == EINTR)
continue;
@ -112,7 +113,7 @@ int main()
#ifdef _WIN32
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)
{
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
while (1)
{
// remove \r
@ -147,10 +147,12 @@ int main()
irc_parse_raw(&bot, bot.in);
memmove(bot.in, p + 1, strlen(p + 1) + 1);
}
free(p);
#else
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");
return 0;

View File

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

View File

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