2021-03-08 23:16:14 -05:00
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h> /* assert */
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h> /* size_t */
|
|
|
|
|
|
|
|
#include "libircclient.h"
|
|
|
|
|
|
|
|
#include "data.h"
|
|
|
|
#include "events.h"
|
2021-03-11 20:48:32 -05:00
|
|
|
#include "strings.h"
|
2021-03-09 01:39:19 -05:00
|
|
|
#include "threads.h"
|
2021-03-12 12:41:17 -05:00
|
|
|
#include "unused.h"
|
2021-03-08 23:16:14 -05:00
|
|
|
|
2021-03-11 17:23:43 -05:00
|
|
|
char F_SPAM_THREADS = STOPPED;
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
static char say_hi = 1;
|
|
|
|
|
|
|
|
static const char *admins[] = {
|
|
|
|
"Bubblegumdrop",
|
|
|
|
};
|
|
|
|
|
|
|
|
static int nadmins = 1;
|
2021-03-11 20:48:32 -05:00
|
|
|
|
2021-03-08 23:16:14 -05:00
|
|
|
THREAD_FUNCTION(gen_spam) {
|
2021-03-11 17:23:43 -05:00
|
|
|
struct spam_params_t *sp = (struct spam_params_t *)arg;
|
|
|
|
while (RUNNING == F_SPAM_THREADS) {
|
2021-03-08 23:16:14 -05:00
|
|
|
if (irc_cmd_msg(sp->session, sp->channel, sp->phrase))
|
|
|
|
break;
|
|
|
|
if (sp->timer > 0)
|
2021-03-12 12:41:17 -05:00
|
|
|
sleep(sp->timer);
|
2021-03-08 23:16:14 -05:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
/* XXX this is a nasty shortcut to copy the signature of the other functions
|
|
|
|
* easily */
|
|
|
|
EVENT_GENERIC_SIGNATURE(start_spam) {
|
2021-03-11 17:23:43 -05:00
|
|
|
struct irc_ctx_t *ctx;
|
|
|
|
static struct spam_params_t spam1;
|
|
|
|
static struct spam_params_t spam2;
|
|
|
|
static struct spam_params_t spam3;
|
|
|
|
thread_id_t tid;
|
2021-03-11 20:48:32 -05:00
|
|
|
|
2021-03-11 17:23:43 -05:00
|
|
|
UNUSED(count);
|
2021-03-08 23:16:14 -05:00
|
|
|
UNUSED(event);
|
|
|
|
UNUSED(origin);
|
|
|
|
UNUSED(params);
|
2021-03-11 20:48:32 -05:00
|
|
|
|
2021-03-11 17:23:43 -05:00
|
|
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
|
|
|
spam1.session = spam2.session = spam3.session = session;
|
|
|
|
spam1.channel = spam2.channel = spam3.channel = ctx->channel;
|
|
|
|
spam1.phrase = "HEHE";
|
|
|
|
spam2.phrase = "HAHA";
|
|
|
|
spam3.phrase = "HUHU";
|
2021-03-12 12:41:17 -05:00
|
|
|
spam1.timer = 1;
|
|
|
|
spam2.timer = 2;
|
|
|
|
spam3.timer = 3;
|
2021-03-11 17:23:43 -05:00
|
|
|
F_SPAM_THREADS = RUNNING;
|
2021-03-12 12:41:17 -05:00
|
|
|
|
|
|
|
if (CREATE_THREAD(&tid, gen_spam, &spam1) || CREATE_THREAD(&tid, gen_spam, &spam2) || CREATE_THREAD(&tid, gen_spam, &spam3))
|
|
|
|
printf(string_thread_failure, strerror(errno));
|
2021-03-11 17:23:43 -05:00
|
|
|
else
|
2021-03-12 12:41:17 -05:00
|
|
|
printf("%s", string_spam_success);
|
2021-03-08 23:16:14 -05:00
|
|
|
}
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
EVENT_GENERIC_SIGNATURE(dump_event) {
|
2021-03-11 17:23:43 -05:00
|
|
|
char buf[1024];
|
|
|
|
unsigned int cnt;
|
2021-03-12 12:41:17 -05:00
|
|
|
size_t bufsize, nwritten;
|
2021-03-11 17:23:43 -05:00
|
|
|
|
2021-03-08 23:16:14 -05:00
|
|
|
UNUSED(session);
|
2021-03-12 12:41:17 -05:00
|
|
|
bufsize = sizeof buf;
|
2021-03-11 17:23:43 -05:00
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
memset(buf, 0, bufsize);
|
|
|
|
nwritten = 0;
|
|
|
|
cnt = 0;
|
|
|
|
while (cnt < count && nwritten < (bufsize-1)) {
|
2021-03-11 17:23:43 -05:00
|
|
|
if (cnt)
|
2021-03-12 12:41:17 -05:00
|
|
|
nwritten += snprintf(buf + nwritten, 2, "|");
|
|
|
|
nwritten += snprintf(buf + nwritten, bufsize - nwritten - 1, "%s", params[cnt]);
|
|
|
|
cnt++;
|
2021-03-11 17:23:43 -05:00
|
|
|
}
|
2021-03-12 12:41:17 -05:00
|
|
|
buf[nwritten+1] = '\0';
|
2021-03-11 17:23:43 -05:00
|
|
|
|
2021-03-11 20:48:32 -05:00
|
|
|
printf("[%s] %s : [%d] %s\n", event, origin ? origin : "(null)", cnt, buf);
|
2021-03-11 17:23:43 -05:00
|
|
|
}
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
EVENT_GENERIC_SIGNATURE(irc_event_connect) {
|
2021-03-11 17:23:43 -05:00
|
|
|
struct irc_ctx_t *ctx;
|
|
|
|
|
|
|
|
UNUSED(event);
|
2021-03-08 23:16:14 -05:00
|
|
|
UNUSED(origin);
|
|
|
|
UNUSED(params);
|
|
|
|
UNUSED(count);
|
2021-03-11 17:23:43 -05:00
|
|
|
|
|
|
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
|
|
|
|
2021-03-11 20:48:32 -05:00
|
|
|
printf(string_connect_success, ctx->server, ctx->port, ctx->nick, ctx->channel);
|
2021-03-11 17:23:43 -05:00
|
|
|
irc_cmd_join(session, ctx->channel, 0);
|
|
|
|
}
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
EVENT_NUMERIC_SIGNATURE(irc_event_numeric) {
|
2021-03-11 17:23:43 -05:00
|
|
|
char buf[24];
|
|
|
|
|
|
|
|
snprintf(buf, sizeof buf, "%d", event);
|
|
|
|
|
2021-03-11 20:48:32 -05:00
|
|
|
dump_event(session, buf, origin, params, count);
|
2021-03-11 17:23:43 -05:00
|
|
|
|
2021-03-08 23:16:14 -05:00
|
|
|
if (event > 400) {
|
|
|
|
printf("ERROR %d: %s: %s %s %s %s\n", event, origin ? origin : "unknown", params[0], count > 1 ? params[1] : "", count > 2 ? params[2] : "", count > 3 ? params[3] : "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
int IsAdmin(const char *name) {
|
|
|
|
int n, rc;
|
|
|
|
rc = 0;
|
|
|
|
for (n = 0; n < nadmins; n++) {
|
|
|
|
rc = !strcmp(name, admins[n]);
|
|
|
|
if (rc)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return rc;
|
2021-03-11 20:48:32 -05:00
|
|
|
}
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
EVENT_GENERIC_SIGNATURE(irc_event_channel) {
|
2021-03-11 17:23:43 -05:00
|
|
|
struct irc_ctx_t *ctx;
|
2021-03-08 23:16:14 -05:00
|
|
|
char nickbuf[128];
|
|
|
|
|
|
|
|
UNUSED(event);
|
|
|
|
UNUSED(params);
|
|
|
|
UNUSED(count);
|
|
|
|
|
2021-03-11 20:48:32 -05:00
|
|
|
dump_event(session, event, origin, params, count);
|
2021-03-08 23:16:14 -05:00
|
|
|
|
2021-03-11 17:23:43 -05:00
|
|
|
if (NULL == origin || count < 2)
|
2021-03-08 23:16:14 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
irc_target_get_nick(origin, nickbuf, sizeof(nickbuf));
|
2021-03-11 17:23:43 -05:00
|
|
|
|
2021-03-11 20:48:32 -05:00
|
|
|
if (!IsAdmin(nickbuf)) {
|
2021-03-11 17:23:43 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
2021-03-08 23:16:14 -05:00
|
|
|
UNUSED(ctx);
|
2021-03-11 17:23:43 -05:00
|
|
|
|
|
|
|
if (!strcmp(params[1], ".stop")) {
|
|
|
|
irc_cmd_msg(session, params[0], ":x");
|
|
|
|
F_SPAM_THREADS = STOPPED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(params[1], ".start")) {
|
|
|
|
irc_cmd_msg(session, params[0], ":v");
|
|
|
|
F_SPAM_THREADS = RUNNING;
|
2021-03-11 20:48:32 -05:00
|
|
|
start_spam(session, ctx->nick, origin, params, count);
|
2021-03-11 17:23:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(params[1], ".quit")) {
|
|
|
|
F_MAIN_THREAD = STOPPED;
|
|
|
|
F_IRC_THREAD = STOPPED;
|
|
|
|
F_MAIN_THREAD = STOPPED;
|
|
|
|
irc_cmd_quit(session, "Bye!");
|
|
|
|
}
|
|
|
|
|
2021-03-08 23:16:14 -05:00
|
|
|
#if 0
|
|
|
|
if (ctx->insolents.find(nickbuf) == ctx->insolents.end())
|
|
|
|
ctx->insolents[nickbuf]
|
|
|
|
= 0;
|
|
|
|
|
|
|
|
ctx->insolents[nickbuf]++;
|
|
|
|
|
|
|
|
printf("'%s' swears in the channel '%s' %d times\n", nickbuf, params[1], ctx->insolents[nickbuf]);
|
|
|
|
|
|
|
|
switch (ctx->insolents[nickbuf]) {
|
|
|
|
case 1:
|
|
|
|
// Send a private message
|
|
|
|
sprintf(text, "%s, please do not swear in this channel.", nickbuf);
|
|
|
|
irc_cmd_msg(session, nickbuf, text);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
// Send a channel message
|
|
|
|
sprintf(text, "%s, do not swear in this channel, or you'll leave it.", nickbuf);
|
|
|
|
irc_cmd_msg(session, params[0], text);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Send a channel notice, and kick the insolent
|
|
|
|
sprintf(text, "kicked %s from %s for swearing.", nickbuf, params[0]);
|
|
|
|
irc_cmd_me(session, params[0], text);
|
|
|
|
irc_cmd_kick(session, nickbuf, params[0], "swearing");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
EVENT_GENERIC_SIGNATURE(irc_event_join) {
|
2021-03-11 20:48:32 -05:00
|
|
|
char buf[128];
|
2021-03-11 17:23:43 -05:00
|
|
|
struct irc_ctx_t *ctx;
|
|
|
|
|
2021-03-08 23:16:14 -05:00
|
|
|
UNUSED(count);
|
|
|
|
UNUSED(event);
|
2021-03-11 17:23:43 -05:00
|
|
|
|
2021-03-08 23:16:14 -05:00
|
|
|
if (!origin)
|
|
|
|
return;
|
2021-03-11 17:23:43 -05:00
|
|
|
|
|
|
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
|
|
|
|
2021-03-08 23:16:14 -05:00
|
|
|
/*
|
|
|
|
* We need to know whether WE are joining the channel, or someone else.
|
|
|
|
* To do this, we compare the origin with our nick.
|
|
|
|
* Note that we have set LIBIRC_OPTION_STRIPNICKS to obtain 'parsed' nicks.
|
|
|
|
*/
|
|
|
|
if (!strcmp(origin, ctx->nick)) {
|
2021-03-11 20:48:32 -05:00
|
|
|
if (say_hi)
|
|
|
|
irc_cmd_msg(session, params[0], "Hi");
|
|
|
|
/*
|
|
|
|
printf("We just joined the channel %s; starting the spam threads\n", params[0]);
|
|
|
|
start_spam (session, ctx->nick, origin, params, count);
|
|
|
|
*/
|
|
|
|
} else if (say_hi) {
|
|
|
|
memset(&buf, 0, sizeof buf);
|
|
|
|
snprintf(buf, (sizeof buf) - 1, "Hey, %s, hi!", origin);
|
|
|
|
irc_cmd_msg(session, params[0], buf);
|
2021-03-08 23:16:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-12 12:41:17 -05:00
|
|
|
EVENT_GENERIC_SIGNATURE(irc_event_nick) {
|
2021-03-08 23:16:14 -05:00
|
|
|
char nickbuf[128];
|
2021-03-11 17:23:43 -05:00
|
|
|
struct irc_ctx_t *ctx;
|
2021-03-08 23:16:14 -05:00
|
|
|
|
|
|
|
UNUSED(event);
|
|
|
|
UNUSED(params);
|
|
|
|
|
|
|
|
if (!origin || count != 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
irc_target_get_nick(origin, nickbuf, sizeof(nickbuf));
|
2021-03-11 17:23:43 -05:00
|
|
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
2021-03-08 23:16:14 -05:00
|
|
|
UNUSED(ctx);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (ctx->insolents.find(nickbuf) != ctx->insolents.end()) {
|
|
|
|
printf("%s has changed its nick to %s to prevent penalties - no way!\n", nickbuf, params[0]);
|
|
|
|
ctx->insolents[params[0]] = ctx->insolents[nickbuf];
|
|
|
|
ctx->insolents.erase(nickbuf);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2021-03-12 12:41:17 -05:00
|
|
|
|
|
|
|
DCC_RECV_SIGNATURE(dcc_recv_callback) {
|
|
|
|
static int count = 1;
|
|
|
|
char buf[12];
|
|
|
|
|
|
|
|
UNUSED(ctx);
|
|
|
|
UNUSED(length);
|
|
|
|
|
|
|
|
switch (status) {
|
|
|
|
case LIBIRC_ERR_CLOSED:
|
|
|
|
printf("DCC %d: chat closed\n", id);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
if (!data) {
|
|
|
|
printf("DCC %d: chat connected\n", id);
|
|
|
|
irc_dcc_msg(session, id, "Hehe");
|
|
|
|
} else {
|
|
|
|
printf("DCC %d: %s\n", id, data);
|
|
|
|
sprintf(buf, "DCC [%d]: %d", id, count++);
|
|
|
|
irc_dcc_msg(session, id, buf);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printf("DCC %d: error %s\n", id, irc_strerror(status));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EVENT_DCC_CHAT_SIGNATURE(irc_event_dcc_chat) {
|
|
|
|
printf("DCC chat [%d] requested from '%s' (%s)\n", dccid, nick, addr);
|
|
|
|
|
|
|
|
irc_dcc_accept(session, dccid, 0, dcc_recv_callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
DCC_RECV_SIGNATURE(dcc_file_recv_callback) {
|
|
|
|
UNUSED(session);
|
|
|
|
UNUSED(id);
|
|
|
|
if (status == 0 && length == 0) {
|
|
|
|
printf("File sent successfully\n");
|
|
|
|
|
|
|
|
if (ctx)
|
|
|
|
fclose((FILE *) ctx);
|
|
|
|
} else if (status) {
|
|
|
|
printf("File sent error: %d\n", status);
|
|
|
|
|
|
|
|
if (ctx)
|
|
|
|
fclose((FILE *) ctx);
|
|
|
|
} else {
|
|
|
|
if (ctx)
|
|
|
|
fwrite(data, 1, length, (FILE *) ctx);
|
|
|
|
printf("File sent progress: %d\n", length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EVENT_DCC_SEND_SIGNATURE(irc_event_dcc_send) {
|
|
|
|
FILE *fp;
|
|
|
|
printf("DCC send [%d] requested from '%s' (%s): %s (%lu bytes)\n", dccid, nick, addr, filename, size);
|
|
|
|
|
|
|
|
if ((fp = fopen("file", "wb")) == 0)
|
|
|
|
abort();
|
|
|
|
|
|
|
|
irc_dcc_accept(session, dccid, fp, dcc_file_recv_callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
EVENT_GENERIC_SIGNATURE(irc_event_privmsg) {
|
|
|
|
dump_event(session, event, origin, params, count);
|
|
|
|
|
|
|
|
printf("'%s' said me (%s): %s\n", origin ? origin : "someone", params[0], params[1]);
|
|
|
|
}
|