@@ -18,8 +18,7 @@ struct spam_params_t { | |||
irc_session_t *session; | |||
const char *phrase; | |||
const char *channel; | |||
int timer; | |||
int unused; | |||
float timer; | |||
}; | |||
/* | |||
@@ -9,11 +9,6 @@ | |||
#include "strings.h" | |||
#include "unused.h" | |||
struct params { | |||
int type; | |||
void *arg; | |||
}; | |||
static int print_col(sqlite3_stmt * pTableInfo, int col) { | |||
int n, rc; | |||
static int ct = 0; | |||
@@ -60,19 +55,21 @@ static int run_script_callback(void *NotUsed, int argc, char **argv, char **azCo | |||
return 0; | |||
} | |||
int run_script(sqlite3 * db, const char *script_filename) { | |||
int rc; | |||
int j, rc; | |||
char *statements, *zErrMsg; | |||
char *str1, *saveptr1, *token; | |||
zErrMsg = 0; | |||
if (!(statements = file_read(script_filename, NULL))) { | |||
fprintf(stderr, string_errmsg_readfile, script_filename); | |||
return -1; | |||
} | |||
#if 0 | |||
rc = sqlite3_exec(db, statements, run_script_callback, 0, &zErrMsg); | |||
if (SQLITE_OK != rc) { | |||
fprintf(stderr, " !! SQL error: %s\n", sqlite3_errmsg(db)); | |||
sqlite3_free(zErrMsg); | |||
} | |||
#if 0 | |||
#else | |||
for (j = 1, str1 = statements;; j++, str1 = NULL) { | |||
token = strtok_r(str1, "\n", &saveptr1); | |||
if (token == NULL) | |||
@@ -9,14 +9,17 @@ | |||
#include "events.h" | |||
#include "strings.h" | |||
#include "threads.h" | |||
#ifndef UNUSED | |||
#define UNUSED(x) (void)(x) | |||
#endif | |||
#include "unused.h" | |||
char F_SPAM_THREADS = STOPPED; | |||
char say_hi = 1; | |||
static char say_hi = 1; | |||
static const char *admins[] = { | |||
"Bubblegumdrop", | |||
}; | |||
static int nadmins = 1; | |||
THREAD_FUNCTION(gen_spam) { | |||
struct spam_params_t *sp = (struct spam_params_t *)arg; | |||
@@ -24,12 +27,14 @@ THREAD_FUNCTION(gen_spam) { | |||
if (irc_cmd_msg(sp->session, sp->channel, sp->phrase)) | |||
break; | |||
if (sp->timer > 0) | |||
sleep((unsigned int)sp->timer); | |||
sleep(sp->timer); | |||
} | |||
return 0; | |||
} | |||
EVENT_SIGNATURE(start_spam) { | |||
/* XXX this is a nasty shortcut to copy the signature of the other functions | |||
* easily */ | |||
EVENT_GENERIC_SIGNATURE(start_spam) { | |||
struct irc_ctx_t *ctx; | |||
static struct spam_params_t spam1; | |||
static struct spam_params_t spam2; | |||
@@ -47,38 +52,40 @@ EVENT_SIGNATURE(start_spam) { | |||
spam1.phrase = "HEHE"; | |||
spam2.phrase = "HAHA"; | |||
spam3.phrase = "HUHU"; | |||
spam1.timer = 2; | |||
spam2.timer = 3; | |||
spam3.timer = 4; | |||
spam1.timer = 1; | |||
spam2.timer = 2; | |||
spam3.timer = 3; | |||
F_SPAM_THREADS = RUNNING; | |||
if (CREATE_THREAD(&tid, gen_spam, &spam1) | |||
|| CREATE_THREAD(&tid, gen_spam, &spam2) | |||
|| CREATE_THREAD(&tid, gen_spam, &spam3)) | |||
printf("CREATE_THREAD failed: %s\n", strerror(errno)); | |||
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)); | |||
else | |||
printf(string_spam_success); | |||
printf("%s", string_spam_success); | |||
} | |||
void dump_event(irc_session_t * session, const char *event, const char *origin, const char **params, unsigned int count) { | |||
EVENT_GENERIC_SIGNATURE(dump_event) { | |||
char buf[1024]; | |||
unsigned int cnt; | |||
size_t bufsize, nwritten; | |||
UNUSED(session); | |||
bufsize = sizeof buf; | |||
buf[0] = '\0'; | |||
memset(buf, 0, sizeof buf); | |||
for (cnt = 0; cnt < count; cnt++) { | |||
memset(buf, 0, bufsize); | |||
nwritten = 0; | |||
cnt = 0; | |||
while (cnt < count && nwritten < (bufsize-1)) { | |||
if (cnt) | |||
strcat(buf, "|"); | |||
strcat(buf, params[cnt]); | |||
nwritten += snprintf(buf + nwritten, 2, "|"); | |||
nwritten += snprintf(buf + nwritten, bufsize - nwritten - 1, "%s", params[cnt]); | |||
cnt++; | |||
} | |||
buf[nwritten+1] = '\0'; | |||
printf("[%s] %s : [%d] %s\n", event, origin ? origin : "(null)", cnt, buf); | |||
} | |||
EVENT_SIGNATURE(event_connect) { | |||
EVENT_GENERIC_SIGNATURE(irc_event_connect) { | |||
struct irc_ctx_t *ctx; | |||
UNUSED(event); | |||
@@ -92,7 +99,7 @@ EVENT_SIGNATURE(event_connect) { | |||
irc_cmd_join(session, ctx->channel, 0); | |||
} | |||
EVENT_NUMERIC_SIGNATURE(event_numeric) { | |||
EVENT_NUMERIC_SIGNATURE(irc_event_numeric) { | |||
char buf[24]; | |||
snprintf(buf, sizeof buf, "%d", event); | |||
@@ -104,11 +111,18 @@ EVENT_NUMERIC_SIGNATURE(event_numeric) { | |||
} | |||
} | |||
int IsAdmin(const char *name) { | |||
return !strcmp(name, "Bubblegumdrop"); | |||
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; | |||
} | |||
EVENT_SIGNATURE(event_channel) { | |||
EVENT_GENERIC_SIGNATURE(irc_event_channel) { | |||
struct irc_ctx_t *ctx; | |||
char nickbuf[128]; | |||
@@ -180,7 +194,7 @@ EVENT_SIGNATURE(event_channel) { | |||
#endif | |||
} | |||
EVENT_SIGNATURE(event_join) { | |||
EVENT_GENERIC_SIGNATURE(irc_event_join) { | |||
char buf[128]; | |||
struct irc_ctx_t *ctx; | |||
@@ -211,7 +225,7 @@ EVENT_SIGNATURE(event_join) { | |||
} | |||
} | |||
EVENT_SIGNATURE(event_nick) { | |||
EVENT_GENERIC_SIGNATURE(irc_event_nick) { | |||
char nickbuf[128]; | |||
struct irc_ctx_t *ctx; | |||
@@ -233,3 +247,74 @@ EVENT_SIGNATURE(event_nick) { | |||
} | |||
#endif | |||
} | |||
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]); | |||
} |
@@ -1,27 +1,55 @@ | |||
#ifndef EVENTS_H | |||
#define EVENTS_H | |||
#define EVENT_SIGNATURE(event_name) \ | |||
void event_name \ | |||
(irc_session_t * session, \ | |||
const char *event, \ | |||
const char *origin, \ | |||
const char **params, \ | |||
#define EVENT_DCC_CHAT_SIGNATURE(event_name) \ | |||
void event_name \ | |||
(irc_session_t * session, \ | |||
const char * nick, \ | |||
const char * addr, \ | |||
irc_dcc_t dccid) | |||
#define EVENT_DCC_SEND_SIGNATURE(event_name) \ | |||
void event_name \ | |||
(irc_session_t * session, \ | |||
const char * nick, \ | |||
const char * addr, \ | |||
const char * filename, \ | |||
unsigned long size, \ | |||
irc_dcc_t dccid) | |||
#define EVENT_GENERIC_SIGNATURE(event_name) \ | |||
void event_name \ | |||
(irc_session_t * session, \ | |||
const char *event, \ | |||
const char *origin, \ | |||
const char **params, \ | |||
unsigned int count) | |||
#define EVENT_NUMERIC_SIGNATURE(event_name) \ | |||
void event_name \ | |||
(irc_session_t * session, \ | |||
unsigned int event, \ | |||
const char *origin, \ | |||
const char **params, \ | |||
#define EVENT_NUMERIC_SIGNATURE(event_name) \ | |||
void event_name \ | |||
(irc_session_t * session, \ | |||
unsigned int event, \ | |||
const char *origin, \ | |||
const char **params, \ | |||
unsigned int count) | |||
#define DCC_RECV_SIGNATURE(event_name) \ | |||
void event_name \ | |||
(irc_session_t * session, \ | |||
irc_dcc_t id, \ | |||
int status, \ | |||
void * ctx, \ | |||
const char * data, \ | |||
unsigned int length) | |||
EVENT_NUMERIC_SIGNATURE(event_numeric); | |||
EVENT_SIGNATURE(event_channel); | |||
EVENT_SIGNATURE(event_connect); | |||
EVENT_SIGNATURE(event_join); | |||
EVENT_SIGNATURE(event_nick); | |||
EVENT_DCC_CHAT_SIGNATURE(irc_event_dcc_chat); | |||
EVENT_DCC_SEND_SIGNATURE(irc_event_dcc_send); | |||
EVENT_GENERIC_SIGNATURE(dump_event); | |||
EVENT_GENERIC_SIGNATURE(irc_event_channel); | |||
EVENT_GENERIC_SIGNATURE(irc_event_connect); | |||
EVENT_GENERIC_SIGNATURE(irc_event_join); | |||
EVENT_GENERIC_SIGNATURE(irc_event_nick); | |||
EVENT_GENERIC_SIGNATURE(irc_event_privmsg); | |||
EVENT_NUMERIC_SIGNATURE(irc_event_numeric); | |||
#endif /* EVENTS_H */ |
@@ -42,21 +42,24 @@ | |||
#include <stdio.h> /* size_t */ | |||
#include <unistd.h> /* getopt */ | |||
#include "libircclient.h" | |||
#include "data.h" | |||
#include "db.h" | |||
#include "events.h" | |||
#include "levenshtein.h" | |||
#include "strings.h" | |||
#include "threads.h" | |||
#ifndef UNUSED | |||
#define UNUSED(x) (void)(x) | |||
#endif | |||
#include "unused.h" | |||
extern void install_signal_handler(void); | |||
char F_IRC_THREAD = STOPPED; | |||
char F_MAIN_THREAD = STOPPED; | |||
char IsIPv6Enabled = 0; | |||
irc_session_t *irc_session = NULL; | |||
const char create_db_query[] = "create table if not exists quotedb (date_added text not null, added_by text not null, channel text not null, subject text not null, words text not null)"; | |||
THREAD_FUNCTION(IrcSessionThread) { | |||
int rc; | |||
const char *server; | |||
struct irc_ctx_t *ctx; | |||
irc_callbacks_t callbacks; | |||
@@ -70,11 +73,28 @@ THREAD_FUNCTION(IrcSessionThread) { | |||
/* Initialize the callbacks */ | |||
memset(&callbacks, 0, sizeof(callbacks)); | |||
/* Set up the callbacks we will use */ | |||
callbacks.event_channel = event_channel; | |||
callbacks.event_connect = event_connect; | |||
callbacks.event_join = event_join; | |||
callbacks.event_nick = event_nick; | |||
callbacks.event_numeric = event_numeric; | |||
callbacks.event_channel = irc_event_channel; | |||
callbacks.event_connect = irc_event_connect; | |||
callbacks.event_dcc_chat_req = irc_event_dcc_chat; | |||
callbacks.event_dcc_send_req = irc_event_dcc_send; | |||
callbacks.event_join = irc_event_join; | |||
callbacks.event_nick = irc_event_nick; | |||
callbacks.event_numeric = irc_event_numeric; | |||
callbacks.event_privmsg = irc_event_privmsg; | |||
callbacks.event_ctcp_action = dump_event; | |||
callbacks.event_ctcp_rep = dump_event; | |||
callbacks.event_invite = dump_event; | |||
callbacks.event_kick = dump_event; | |||
callbacks.event_mode = dump_event; | |||
callbacks.event_nick = dump_event; | |||
callbacks.event_notice = dump_event; | |||
callbacks.event_part = dump_event; | |||
callbacks.event_quit = dump_event; | |||
callbacks.event_topic = dump_event; | |||
callbacks.event_umode = dump_event; | |||
callbacks.event_unknown = dump_event; | |||
/* And create the IRC session; 0 means error */ | |||
irc_session = irc_create_session(&callbacks); | |||
if (!irc_session) { | |||
@@ -96,7 +116,13 @@ THREAD_FUNCTION(IrcSessionThread) { | |||
irc_option_set(irc_session, LIBIRC_OPTION_SSL_NO_VERIFY); | |||
} | |||
/* Initiate the IRC server connection */ | |||
if (irc_connect(irc_session, server, ctx->port, 0, ctx->nick, 0, 0)) { | |||
rc = 1; | |||
if (IsIPv6Enabled) { | |||
rc = irc_connect6(irc_session, server, ctx->port, 0, ctx->nick, 0, 0); | |||
} else { | |||
rc = irc_connect(irc_session, server, ctx->port, 0, ctx->nick, 0, 0); | |||
} | |||
if (rc) { | |||
fprintf(stderr, string_connect_failure, irc_strerror(irc_errno(irc_session))); | |||
F_IRC_THREAD = STOPPED; | |||
} | |||
@@ -116,6 +142,7 @@ THREAD_FUNCTION(IrcSessionThread) { | |||
#endif | |||
} | |||
int main(int argc, char *argv[]) { | |||
int c; | |||
int rc; | |||
int opt; | |||
const char *db_name; | |||
@@ -137,8 +164,14 @@ int main(int argc, char *argv[]) { | |||
db = NULL; | |||
memset(&ctx, 0, sizeof(struct irc_ctx_t)); | |||
ctx.port = 6667; | |||
while ((opt = getopt(argc, argv, "c:d:f:hn:p:q:s:")) != -1) { | |||
while ((opt = getopt(argc, argv, "c:d:f:hn:p:q:s:46")) != -1) { | |||
switch (opt) { | |||
case '4': | |||
IsIPv6Enabled = 0; | |||
break; | |||
case '6': | |||
IsIPv6Enabled = 1; | |||
break; | |||
case 'c': | |||
ctx.channel = optarg; | |||
break; | |||
@@ -169,7 +202,7 @@ int main(int argc, char *argv[]) { | |||
} | |||
if (NULL != db_name) { | |||
if (SQLITE_OK == (rc = sqlite3_open(db_name, &db))) { | |||
printf(string_opendb_success); | |||
printf("%s", string_opendb_success); | |||
sqlite_version(db); | |||
} | |||
} else { | |||
@@ -197,12 +230,18 @@ int main(int argc, char *argv[]) { | |||
F_IRC_THREAD = RUNNING; | |||
F_MAIN_THREAD = RUNNING; | |||
if (CREATE_THREAD(&tid, IrcSessionThread, &ctx)) { | |||
printf(string_ircthread_failure, strerror(errno)); | |||
printf(string_thread_failure, strerror(errno)); | |||
} else { | |||
printf(string_ircthread_success); | |||
printf("%s", string_ircthread_success); | |||
} | |||
while (RUNNING == F_MAIN_THREAD) { | |||
sleep(1); | |||
c = getchar(); | |||
if ('q' == c) { | |||
if (irc_session) | |||
irc_cmd_quit(irc_session, "Bye!"); | |||
F_MAIN_THREAD = STOPPED; | |||
} | |||
} | |||
F_IRC_THREAD = STOPPED; | |||
F_SPAM_THREADS = STOPPED; | |||
@@ -26,6 +26,10 @@ ifeq ($(O),s) | |||
OPT := -g0 -Os | |||
endif | |||
FLAGS := -D_FORTIFY_SOURCE=2 -fasynchronous-unwind-tables -fexceptions -fpie -Wl,-pie -fpic -fstack-clash-protection -fstack-protector-all -fstack-protector-strong -g -grecord-gcc-switches -fcf-protection -pipe -Wformat -Werror=format-security -Werror=implicit-function-declaration -Wl,-z,defs -Wl,-z,now -Wl,-z,relro | |||
CFLAGS += $(FLAGS) | |||
LDFLAGS += $(FLAGS) | |||
CFLAGS += $(OPT) -std=c99 $(WARN) | |||
CFLAGS += -I. | |||
@@ -11,15 +11,14 @@ const char string_errmsg_readfile[] = "Error reading file: %s\n"; | |||
const char string_errmsg_reset[] = "Error resetting statement: %s\n"; | |||
const char string_errmsg_update[] = "Error updating data: %s\n"; | |||
const char string_ircthread_success[] = "IRC thread was started successfully.\n"; | |||
const char string_ircthread_failure[] = "CREATE_THREAD failed: %s\n"; | |||
const char string_opendb_failure[] = "Can't open database: %s\n"; | |||
const char string_opendb_success[] = "Open database successfully\n"; | |||
const char string_signal_fmt[] = "Received %s, exiting.\n"; | |||
const char string_signal_unknown_fmt[] = "(Unknown Signal)"; | |||
const char string_spam_success[] = "Spammer thread was started successfully.\n"; | |||
const char string_usage_fmt[] = "Usage: %s [-46] [-q query] [-d sqlite db] [-h] [-p port] [-f script file] <[-s] server addr> [[-p] server port] <[-n] irc name> <[-c] irc channel>\n"; | |||
const char string_usage_fmt[] = "Usage: %s [-q query] [-d sqlite db] [-h] [-p port] [-f script file]\n"; | |||
const char string_spam_success[] = "Spammer thread was started successfully.\n"; | |||
const char string_ircthread_success[] = "IRC thread was started successfully.\n"; | |||
const char string_thread_failure[] = "CREATE_THREAD failed: %s\n"; |
@@ -18,11 +18,14 @@ extern const char string_opendb_success[]; | |||
extern const char string_signal_fmt[]; | |||
extern const char string_signal_unknown_fmt[]; | |||
extern const char string_spam_success[]; | |||
extern const char string_usage_fmt[]; | |||
/* Threads */ | |||
extern const char string_spam_success[]; | |||
extern const char string_ircthread_success[]; | |||
extern const char string_ircthread_failure[]; | |||
/* Generic thread failure */ | |||
extern const char string_thread_failure[]; | |||
#endif /* STRINGS_H */ |
@@ -6,7 +6,7 @@ | |||
#define CREATE_THREAD(id,func,param) (CreateThread(0, 0, func, param, 0, id) == 0) | |||
#define THREAD_FUNCTION(funcname) static DWORD WINAPI funcname (LPVOID arg) | |||
#define thread_id_t DWORD | |||
#define sleep(a) Sleep (a*1000) | |||
#define sleep(a) Sleep ((float)(a)*(float)1000) | |||
#else | |||
#include <unistd.h> | |||
#include <pthread.h> | |||