IRC functionality in place: .start .stop spam and .quit
This commit is contained in:
parent
542e8395ef
commit
90f6bdbb7a
13
data.h
13
data.h
@ -4,32 +4,33 @@
|
|||||||
/*
|
/*
|
||||||
* We store data in IRC session context.
|
* We store data in IRC session context.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
struct irc_ctx_t {
|
||||||
|
unsigned short port;
|
||||||
char *channel;
|
char *channel;
|
||||||
char *nick;
|
char *nick;
|
||||||
char *server;
|
char *server;
|
||||||
} irc_ctx_t;
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Params that we give to our threads.
|
* Params that we give to our threads.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
struct spam_params_t {
|
||||||
irc_session_t *session;
|
irc_session_t *session;
|
||||||
const char *phrase;
|
const char *phrase;
|
||||||
const char *channel;
|
const char *channel;
|
||||||
int timer;
|
int timer;
|
||||||
int unused;
|
int unused;
|
||||||
} spam_params_t;
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Eventually I'd like to be able to do insert_struct with filled out info or similar.
|
* Eventually I'd like to be able to do insert_struct with filled out info or similar.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
struct quote_t {
|
||||||
int rowid;
|
int rowid;
|
||||||
const char *added_by;
|
const char *added_by;
|
||||||
const char *channel;
|
const char *channel;
|
||||||
const char *subject;
|
const char *subject;
|
||||||
const char *words;
|
const char *words;
|
||||||
} quote_t;
|
};
|
||||||
|
|
||||||
#endif /* DATA_H */
|
#endif /* DATA_H */
|
||||||
|
|||||||
8
db.c
8
db.c
@ -5,7 +5,7 @@
|
|||||||
#include <assert.h> /* assert */
|
#include <assert.h> /* assert */
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <stdio.h> /* size_t */
|
#include <stdio.h> /* size_t */
|
||||||
#include <stdlib.h> /* malloc */
|
#include <stdlib.h> /* free */
|
||||||
|
|
||||||
#ifndef UNUSED
|
#ifndef UNUSED
|
||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
@ -21,7 +21,7 @@ const char errmsg_readfile[] = "Error reading file: %s\n";
|
|||||||
const char errmsg_reset[] = "Error resetting statement: %s\n";
|
const char errmsg_reset[] = "Error resetting statement: %s\n";
|
||||||
const char errmsg_update[] = "Error updating data: %s\n";
|
const char errmsg_update[] = "Error updating data: %s\n";
|
||||||
|
|
||||||
int print_col(sqlite3_stmt * pTableInfo, int col) {
|
static int print_col(sqlite3_stmt * pTableInfo, int col) {
|
||||||
int n, rc;
|
int n, rc;
|
||||||
static int ct = 0;
|
static int ct = 0;
|
||||||
char outfile[50];
|
char outfile[50];
|
||||||
@ -61,7 +61,7 @@ int print_col(sqlite3_stmt * pTableInfo, int col) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int callback_run_script(void *NotUsed, int argc, char **argv, char **azColName) {
|
static int run_script_callback(void *NotUsed, int argc, char **argv, char **azColName) {
|
||||||
int i;
|
int i;
|
||||||
UNUSED(NotUsed);
|
UNUSED(NotUsed);
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
@ -90,7 +90,7 @@ int run_script(sqlite3 * db, const char *script_filename) {
|
|||||||
if (strlen(token) > 2 && token[0] == '-' && token[1] == '-')
|
if (strlen(token) > 2 && token[0] == '-' && token[1] == '-')
|
||||||
continue; /* Comment line; TODO multiline comment */
|
continue; /* Comment line; TODO multiline comment */
|
||||||
printf("%d: %s\n", j, token);
|
printf("%d: %s\n", j, token);
|
||||||
rc = sqlite3_exec(db, token, callback_run_script, 0, &zErrMsg);
|
rc = sqlite3_exec(db, token, run_script_callback, 0, &zErrMsg);
|
||||||
if (SQLITE_OK != rc) {
|
if (SQLITE_OK != rc) {
|
||||||
fprintf(stderr, " !! SQL error: %s\n", sqlite3_errmsg(db));
|
fprintf(stderr, " !! SQL error: %s\n", sqlite3_errmsg(db));
|
||||||
sqlite3_free(zErrMsg);
|
sqlite3_free(zErrMsg);
|
||||||
|
|||||||
144
events.c
144
events.c
@ -2,7 +2,6 @@
|
|||||||
#include <assert.h> /* assert */
|
#include <assert.h> /* assert */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h> /* size_t */
|
#include <stdio.h> /* size_t */
|
||||||
#include <stdlib.h> /* malloc */
|
|
||||||
|
|
||||||
#include "libircclient.h"
|
#include "libircclient.h"
|
||||||
|
|
||||||
@ -14,56 +13,134 @@
|
|||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char F_SPAM_THREADS = STOPPED;
|
||||||
|
|
||||||
THREAD_FUNCTION(gen_spam) {
|
THREAD_FUNCTION(gen_spam) {
|
||||||
spam_params_t *sp = (spam_params_t *) arg;
|
struct spam_params_t *sp = (struct spam_params_t *)arg;
|
||||||
while (1) {
|
while (RUNNING == F_SPAM_THREADS) {
|
||||||
if (irc_cmd_msg(sp->session, sp->channel, sp->phrase))
|
if (irc_cmd_msg(sp->session, sp->channel, sp->phrase))
|
||||||
break;
|
break;
|
||||||
if (sp->timer > 0)
|
if (sp->timer > 0)
|
||||||
sleep((unsigned int)
|
sleep((unsigned int)sp->timer);
|
||||||
sp->timer);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EVENT_SIGNATURE(start_spam) {
|
||||||
|
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;
|
||||||
|
UNUSED(count);
|
||||||
|
UNUSED(event);
|
||||||
|
UNUSED(origin);
|
||||||
|
UNUSED(params);
|
||||||
|
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";
|
||||||
|
spam1.timer = 2;
|
||||||
|
spam2.timer = 3;
|
||||||
|
spam3.timer = 4;
|
||||||
|
printf("We just joined the channel %s; starting the spam threads\n", params[0]);
|
||||||
|
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));
|
||||||
|
else
|
||||||
|
printf("Spammer thread was started successfully.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dump_event(irc_session_t * session, const char *event, const char *origin, const char **params, unsigned int count) {
|
||||||
|
char buf[1024];
|
||||||
|
unsigned int cnt;
|
||||||
|
|
||||||
|
UNUSED(session);
|
||||||
|
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof buf);
|
||||||
|
for (cnt = 0; cnt < count; cnt++) {
|
||||||
|
if (cnt)
|
||||||
|
strcat(buf, "|");
|
||||||
|
|
||||||
|
strcat(buf, params[cnt]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Event \"%s\", origin: \"%s\", params: %d [%s]\n", event, origin ? origin : "NULL", cnt, buf);
|
||||||
|
}
|
||||||
|
|
||||||
EVENT_SIGNATURE(event_connect) {
|
EVENT_SIGNATURE(event_connect) {
|
||||||
irc_ctx_t *ctx;
|
struct irc_ctx_t *ctx;
|
||||||
|
|
||||||
UNUSED(event);
|
UNUSED(event);
|
||||||
UNUSED(origin);
|
UNUSED(origin);
|
||||||
UNUSED(params);
|
UNUSED(params);
|
||||||
UNUSED(count);
|
UNUSED(count);
|
||||||
ctx = (irc_ctx_t *)
|
|
||||||
irc_get_ctx(session);
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
||||||
|
|
||||||
|
printf("Server: %s\nPort: %d\nNick: %s\nChannel: %s\n", ctx->server, ctx->port, ctx->nick, ctx->channel);
|
||||||
irc_cmd_join(session, ctx->channel, 0);
|
irc_cmd_join(session, ctx->channel, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EVENT_NUMERIC_SIGNATURE(event_numeric) {
|
EVENT_NUMERIC_SIGNATURE(event_numeric) {
|
||||||
UNUSED(session);
|
char buf[24];
|
||||||
UNUSED(origin);
|
|
||||||
UNUSED(params);
|
snprintf(buf, sizeof buf, "%d", event);
|
||||||
UNUSED(count);
|
|
||||||
|
dump_event (session, buf, origin, params, count);
|
||||||
|
|
||||||
if (event > 400) {
|
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] : "");
|
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] : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EVENT_SIGNATURE(event_channel) {
|
EVENT_SIGNATURE(event_channel) {
|
||||||
irc_ctx_t *ctx;
|
struct irc_ctx_t *ctx;
|
||||||
char nickbuf[128];
|
char nickbuf[128];
|
||||||
|
|
||||||
UNUSED(event);
|
UNUSED(event);
|
||||||
UNUSED(params);
|
UNUSED(params);
|
||||||
UNUSED(count);
|
UNUSED(count);
|
||||||
|
|
||||||
if (!origin || count != 2)
|
dump_event (session, event, origin, params, count);
|
||||||
return;
|
|
||||||
|
|
||||||
if (strstr(params[1], "fuck") == 0)
|
if (NULL == origin || count < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
irc_target_get_nick(origin, nickbuf, sizeof(nickbuf));
|
irc_target_get_nick(origin, nickbuf, sizeof(nickbuf));
|
||||||
ctx = (irc_ctx_t *) irc_get_ctx(session);
|
|
||||||
|
if (strcmp(nickbuf, "Bubblegumdrop")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
||||||
UNUSED(ctx);
|
UNUSED(ctx);
|
||||||
|
|
||||||
|
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;
|
||||||
|
start_spam (session, ctx->nick, origin, params, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(params[1], ".quit")) {
|
||||||
|
F_MAIN_THREAD = STOPPED;
|
||||||
|
F_IRC_THREAD = STOPPED;
|
||||||
|
F_MAIN_THREAD = STOPPED;
|
||||||
|
irc_cmd_quit(session, "Bye!");
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (ctx->insolents.find(nickbuf) == ctx->insolents.end())
|
if (ctx->insolents.find(nickbuf) == ctx->insolents.end())
|
||||||
ctx->insolents[nickbuf]
|
ctx->insolents[nickbuf]
|
||||||
@ -97,38 +174,23 @@ EVENT_SIGNATURE(event_channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EVENT_SIGNATURE(event_join) {
|
EVENT_SIGNATURE(event_join) {
|
||||||
irc_ctx_t *ctx;
|
struct irc_ctx_t *ctx;
|
||||||
|
|
||||||
UNUSED(count);
|
UNUSED(count);
|
||||||
UNUSED(event);
|
UNUSED(event);
|
||||||
|
|
||||||
if (!origin)
|
if (!origin)
|
||||||
return;
|
return;
|
||||||
ctx = (irc_ctx_t *)
|
|
||||||
irc_get_ctx(session);
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to know whether WE are joining the channel, or someone else.
|
* We need to know whether WE are joining the channel, or someone else.
|
||||||
* To do this, we compare the origin with our nick.
|
* To do this, we compare the origin with our nick.
|
||||||
* Note that we have set LIBIRC_OPTION_STRIPNICKS to obtain 'parsed' nicks.
|
* Note that we have set LIBIRC_OPTION_STRIPNICKS to obtain 'parsed' nicks.
|
||||||
*/
|
*/
|
||||||
if (!strcmp(origin, ctx->nick)) {
|
if (!strcmp(origin, ctx->nick)) {
|
||||||
static spam_params_t spam1;
|
/* start_spam (session, ctx->nick, origin, params, count); */
|
||||||
static spam_params_t spam2;
|
|
||||||
static spam_params_t spam3;
|
|
||||||
thread_id_t tid;
|
|
||||||
spam1.session = spam2.session = spam3.session = session;
|
|
||||||
spam1.channel = spam2.channel = spam3.channel = ctx->channel;
|
|
||||||
spam1.phrase = "HEHE";
|
|
||||||
spam2.phrase = "HAHA";
|
|
||||||
spam3.phrase = "HUHU";
|
|
||||||
spam1.timer = 2;
|
|
||||||
spam2.timer = 3;
|
|
||||||
spam3.timer = 4;
|
|
||||||
printf("We just joined the channel %s; starting the spam threads\n", params[1]);
|
|
||||||
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));
|
|
||||||
else
|
|
||||||
printf("Spammer thread was started successfully.\n");
|
|
||||||
} else {
|
} else {
|
||||||
char textbuf[168];
|
char textbuf[168];
|
||||||
sprintf(textbuf, "Hey, %s, hi!", origin);
|
sprintf(textbuf, "Hey, %s, hi!", origin);
|
||||||
@ -138,7 +200,7 @@ EVENT_SIGNATURE(event_join) {
|
|||||||
|
|
||||||
EVENT_SIGNATURE(event_nick) {
|
EVENT_SIGNATURE(event_nick) {
|
||||||
char nickbuf[128];
|
char nickbuf[128];
|
||||||
irc_ctx_t *ctx;
|
struct irc_ctx_t *ctx;
|
||||||
|
|
||||||
UNUSED(event);
|
UNUSED(event);
|
||||||
UNUSED(params);
|
UNUSED(params);
|
||||||
@ -147,7 +209,7 @@ EVENT_SIGNATURE(event_nick) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
irc_target_get_nick(origin, nickbuf, sizeof(nickbuf));
|
irc_target_get_nick(origin, nickbuf, sizeof(nickbuf));
|
||||||
ctx = (irc_ctx_t *) irc_get_ctx(session);
|
ctx = (struct irc_ctx_t *)irc_get_ctx(session);
|
||||||
UNUSED(ctx);
|
UNUSED(ctx);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
22
io.c
22
io.c
@ -1,6 +1,7 @@
|
|||||||
#include <assert.h> /* assert */
|
#include <assert.h> /* assert */
|
||||||
#include <stdio.h> /* FILE* */
|
#include <stdio.h> /* FILE* */
|
||||||
#include <stdlib.h> /* malloc, free */
|
#include <stdlib.h> /* malloc, free */
|
||||||
|
#include <unistd.h> /* unlink */
|
||||||
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ char *file_read(const char *filename, size_t *readSize) {
|
|||||||
size = ftell(fh);
|
size = ftell(fh);
|
||||||
rewind(fh);
|
rewind(fh);
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
buffer = (char*)malloc((size_t)size);
|
buffer = (char *)malloc((size_t)size);
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
assert(buffer != NULL);
|
assert(buffer != NULL);
|
||||||
nread = fread(buffer, 1, (size_t)size, fh);
|
nread = fread(buffer, 1, (size_t)size, fh);
|
||||||
@ -57,3 +58,22 @@ size_t file_write(const char *fileName, const void *data, const size_t size) {
|
|||||||
}
|
}
|
||||||
return numberBytesWritten;
|
return numberBytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int copy_file(const char *srcname, const char *dstname) {
|
||||||
|
int rc;
|
||||||
|
char *buf;
|
||||||
|
size_t nread, nwrite;
|
||||||
|
rc = -1;
|
||||||
|
buf = file_read(srcname, &nread);
|
||||||
|
if (buf) {
|
||||||
|
nwrite = file_write(dstname, buf, nread);
|
||||||
|
if (nread != nwrite) {
|
||||||
|
fprintf(stderr, "Incorrect write size (%ld != %ld)\n", nread, nwrite);
|
||||||
|
unlink(dstname);
|
||||||
|
}
|
||||||
|
assert(nread == nwrite);
|
||||||
|
free(buf);
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|||||||
81
main.c
81
main.c
@ -32,12 +32,13 @@
|
|||||||
* Quote bot. WIP.
|
* Quote bot. WIP.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _POSIX_C_SOURCE 200809L /* strtok_r, strndup */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h> /* assert */
|
#include <assert.h> /* assert */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <getopt.h> /* getopt */
|
||||||
#include <stdio.h> /* size_t */
|
#include <stdio.h> /* size_t */
|
||||||
#include <unistd.h> /* getopt */
|
#include <unistd.h> /* getopt */
|
||||||
#include <getopt.h> /* getopt */
|
|
||||||
|
|
||||||
#include "libircclient.h"
|
#include "libircclient.h"
|
||||||
|
|
||||||
@ -51,23 +52,26 @@
|
|||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void install_signal_handler(void);
|
||||||
|
|
||||||
char F_IRC_THREAD = STOPPED;
|
char F_IRC_THREAD = STOPPED;
|
||||||
char F_MAIN_THREAD = STOPPED;
|
char F_MAIN_THREAD = STOPPED;
|
||||||
|
irc_session_t *irc_session = NULL;
|
||||||
|
|
||||||
THREAD_FUNCTION(irc_thread) {
|
THREAD_FUNCTION(irc_thread) {
|
||||||
const char *server;
|
const char *server;
|
||||||
unsigned short port = 6667;
|
|
||||||
irc_callbacks_t callbacks;
|
irc_callbacks_t callbacks;
|
||||||
irc_session_t *s;
|
struct irc_ctx_t *ctx;
|
||||||
irc_ctx_t *ctx;
|
|
||||||
|
|
||||||
ctx = (irc_ctx_t *) arg;
|
ctx = (struct irc_ctx_t *)arg;
|
||||||
assert(NULL != ctx);
|
assert(NULL != ctx);
|
||||||
server = ctx->server;
|
server = ctx->server;
|
||||||
assert(NULL != server);
|
assert(NULL != server);
|
||||||
assert(NULL != ctx->nick);
|
assert(NULL != ctx->nick);
|
||||||
assert(NULL != ctx->channel);
|
assert(NULL != ctx->channel);
|
||||||
|
|
||||||
|
printf("Server: %s\nPort: %d\nNick: %s\nChannel: %s\n", ctx->server, ctx->port, ctx->nick, ctx->channel);
|
||||||
|
|
||||||
while (RUNNING == F_IRC_THREAD) {
|
while (RUNNING == F_IRC_THREAD) {
|
||||||
/* Initialize the callbacks */
|
/* Initialize the callbacks */
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
@ -78,16 +82,16 @@ THREAD_FUNCTION(irc_thread) {
|
|||||||
callbacks.event_nick = event_nick;
|
callbacks.event_nick = event_nick;
|
||||||
callbacks.event_numeric = event_numeric;
|
callbacks.event_numeric = event_numeric;
|
||||||
/* And create the IRC session; 0 means error */
|
/* And create the IRC session; 0 means error */
|
||||||
s = irc_create_session(&callbacks);
|
irc_session = irc_create_session(&callbacks);
|
||||||
if (!s) {
|
if (!irc_session) {
|
||||||
printf("Could not create IRC session\n");
|
fprintf(stderr, "Could not create IRC session\n");
|
||||||
return (void *)-1;
|
F_IRC_THREAD = STOPPED;
|
||||||
}
|
}
|
||||||
irc_set_ctx(s, &ctx);
|
irc_set_ctx(irc_session, ctx);
|
||||||
irc_option_set(s, LIBIRC_OPTION_STRIPNICKS);
|
irc_option_set(irc_session, LIBIRC_OPTION_STRIPNICKS);
|
||||||
/* If the port number is specified in the server string, use the port 0 so it gets parsed */
|
/* If the port number is specified in the server string, use the port 0 so it gets parsed */
|
||||||
if (strchr(server, ':') != 0)
|
if (strchr(server, ':') != 0)
|
||||||
port = 0;
|
ctx->port = 0;
|
||||||
/*
|
/*
|
||||||
* To handle the "SSL certificate verify failed" from command line we allow passing ## in front
|
* To handle the "SSL certificate verify failed" from command line we allow passing ## in front
|
||||||
* of the server name, and in this case tell libircclient not to verify the cert
|
* of the server name, and in this case tell libircclient not to verify the cert
|
||||||
@ -95,32 +99,36 @@ THREAD_FUNCTION(irc_thread) {
|
|||||||
if (server[0] == '#' && server[0] == '#') {
|
if (server[0] == '#' && server[0] == '#') {
|
||||||
/* Skip the first character as libircclient needs only one # for SSL support, i.e. #irc.freenode.net */
|
/* Skip the first character as libircclient needs only one # for SSL support, i.e. #irc.freenode.net */
|
||||||
server++;
|
server++;
|
||||||
irc_option_set(s, LIBIRC_OPTION_SSL_NO_VERIFY);
|
irc_option_set(irc_session, LIBIRC_OPTION_SSL_NO_VERIFY);
|
||||||
}
|
}
|
||||||
/* Initiate the IRC server connection */
|
/* Initiate the IRC server connection */
|
||||||
if (irc_connect(s, server, port, 0, ctx->nick, 0, 0)) {
|
if (irc_connect(irc_session, server, ctx->port, 0, ctx->nick, 0, 0)) {
|
||||||
printf("Could not connect: %s\n", irc_strerror(irc_errno(s)));
|
fprintf(stderr, "Could not connect: %s\n", irc_strerror(irc_errno(irc_session)));
|
||||||
return (void *)-1;
|
F_IRC_THREAD = STOPPED;
|
||||||
}
|
}
|
||||||
/* and run into forever loop, generating events */
|
/* and run into forever loop, generating events */
|
||||||
if (irc_run(s)) {
|
if (irc_run(irc_session)) {
|
||||||
printf("Could not connect or I/O error: %s\n", irc_strerror(irc_errno(s)));
|
fprintf(stderr, "Could not connect or I/O error: %s\n", irc_strerror(irc_errno(irc_session)));
|
||||||
return (void *)-1;
|
F_IRC_THREAD = STOPPED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void *)0;
|
F_MAIN_THREAD = STOPPED;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char *argv[]) {
|
||||||
int rc, opt;
|
int rc, opt;
|
||||||
const char *db_name = NULL;
|
const char *db_name = NULL;
|
||||||
const char *script_filename = NULL;
|
const char *script_filename = NULL;
|
||||||
const char *query_str = NULL;
|
const char *query_str = NULL;
|
||||||
irc_ctx_t ctx;
|
struct irc_ctx_t ctx;
|
||||||
sqlite3 *db = NULL;
|
sqlite3 *db = NULL;
|
||||||
thread_id_t tid;
|
thread_id_t tid;
|
||||||
|
size_t maxlen = 1024;
|
||||||
|
|
||||||
|
install_signal_handler();
|
||||||
#if 0
|
#if 0
|
||||||
const char *s1 = "rosettacode";
|
const char *s1 = "rosettacode";
|
||||||
const char *s2 = "raisethysword";
|
const char *s2 = "raisethysword";
|
||||||
@ -128,21 +136,26 @@ int main(int argc, char **argv) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
db_name = "familyGuy.sqlite3";
|
db_name = "familyGuy.sqlite3";
|
||||||
|
memset(&ctx, 0, sizeof(struct irc_ctx_t));
|
||||||
|
ctx.port = 6667;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "c:d:s:h")) != -1) {
|
while ((opt = getopt(argc, argv, "q:d:hp:f:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'c':
|
case 'q':
|
||||||
query_str = optarg;
|
query_str = optarg;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
db_name = optarg;
|
db_name = optarg;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 'p':
|
||||||
|
ctx.port = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
script_filename = optarg;
|
script_filename = optarg;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Usage: %s [-h]\n", argv[0]);
|
fprintf(stderr, "Usage: %s [-q query] [-d sqlite db] [-h] [-p port] [-f script file]\n", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -165,10 +178,12 @@ int main(int argc, char **argv) {
|
|||||||
} else if (script_filename) {
|
} else if (script_filename) {
|
||||||
run_script(db, script_filename);
|
run_script(db, script_filename);
|
||||||
} else if (argc == 4) {
|
} else if (argc == 4) {
|
||||||
ctx.server = argv[1];
|
ctx.server = strndup(argv[1], maxlen);
|
||||||
ctx.nick = argv[2];
|
ctx.nick = strndup(argv[2], maxlen);
|
||||||
ctx.channel = argv[3];
|
ctx.channel = strndup(argv[3], maxlen);
|
||||||
F_IRC_THREAD = F_MAIN_THREAD = RUNNING;
|
|
||||||
|
F_IRC_THREAD = RUNNING;
|
||||||
|
F_MAIN_THREAD = RUNNING;
|
||||||
if (CREATE_THREAD(&tid, irc_thread, &ctx)) {
|
if (CREATE_THREAD(&tid, irc_thread, &ctx)) {
|
||||||
printf("CREATE_THREAD failed: %s\n", strerror(errno));
|
printf("CREATE_THREAD failed: %s\n", strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
@ -178,10 +193,16 @@ int main(int argc, char **argv) {
|
|||||||
while (RUNNING == F_MAIN_THREAD) {
|
while (RUNNING == F_MAIN_THREAD) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(ctx.server);
|
||||||
|
free(ctx.nick);
|
||||||
|
free(ctx.channel);
|
||||||
} else {
|
} else {
|
||||||
printf("Usage: %s <server> <nick> <channel>\n", argv[0]);
|
printf("Usage: %s <server> <nick> <channel>\n", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
F_IRC_THREAD = STOPPED;
|
F_IRC_THREAD = STOPPED;
|
||||||
|
F_SPAM_THREADS = STOPPED;
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
33
makefile
33
makefile
@ -1,39 +1,22 @@
|
|||||||
INLINE_SQLITE ?= 0
|
INLINE_SQLITE ?= 0
|
||||||
|
WARN := -W -Wall -Wextra -pedantic -pedantic-errors
|
||||||
|
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
WARN := -W -Wall -Wextra -pedantic -pedantic-errors \
|
|
||||||
-Wcast-qual -Wconversion \
|
|
||||||
-Wdisabled-optimization \
|
|
||||||
-Werror -Wfloat-equal -Wformat=2 \
|
|
||||||
-Wformat-nonliteral -Wformat-security \
|
|
||||||
-Wformat-y2k \
|
|
||||||
-Wimport -Winit-self -Winline \
|
|
||||||
-Winvalid-pch \
|
|
||||||
-Wmissing-field-initializers -Wmissing-format-attribute \
|
|
||||||
-Wmissing-include-dirs -Wmissing-noreturn \
|
|
||||||
-Wpointer-arith \
|
|
||||||
-Wredundant-decls \
|
|
||||||
-Wshadow -Wstack-protector \
|
|
||||||
-Wstrict-aliasing=2 -Wswitch-default \
|
|
||||||
-Wswitch-enum \
|
|
||||||
-Wunreachable-code -Wunused \
|
|
||||||
-Wunused-parameter \
|
|
||||||
-Wvariadic-macros \
|
|
||||||
-Wwrite-strings
|
|
||||||
#-Wpacked -Wpadded
|
|
||||||
CFLAGS += -ggdb -O0 -std=c99 $(WARN)
|
|
||||||
CFLAGS += -I.
|
|
||||||
|
|
||||||
LDFLAGS += -lpthread -lircclient -ldl
|
SRC := $(wildcard *.c)
|
||||||
|
OBJ := $(SRC:.c=.o)
|
||||||
|
|
||||||
SRC = $(wildcard *.c)
|
|
||||||
OBJ = $(SRC:.c=.o)
|
|
||||||
ifeq ($(INLINE_SQLITE),0)
|
ifeq ($(INLINE_SQLITE),0)
|
||||||
TMP := $(OBJ)
|
TMP := $(OBJ)
|
||||||
OBJ := $(filter-out sqlite3.o,$(TMP))
|
OBJ := $(filter-out sqlite3.o,$(TMP))
|
||||||
LDFLAGS += -lsqlite3
|
LDFLAGS += -lsqlite3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
CFLAGS += -ggdb -O0 -std=c99 $(WARN)
|
||||||
|
CFLAGS += -I.
|
||||||
|
|
||||||
|
LDFLAGS += -lpthread -lircclient -ldl
|
||||||
|
|
||||||
all: spammer
|
all: spammer
|
||||||
|
|
||||||
sqlite3.o: sqlite3.c
|
sqlite3.o: sqlite3.c
|
||||||
|
|||||||
54
signal.c
Normal file
54
signal.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include <signal.h> /* signal */
|
||||||
|
#include <stdio.h> /* fprintf */
|
||||||
|
#include <stdlib.h> /* exit */
|
||||||
|
#include <string.h> /* memset */
|
||||||
|
|
||||||
|
#include "libircclient.h"
|
||||||
|
|
||||||
|
#include "threads.h" /* F_* */
|
||||||
|
|
||||||
|
extern irc_session_t *irc_session;
|
||||||
|
|
||||||
|
const char signal_fmt[] = "Received %s, exiting.\n";
|
||||||
|
const char signal_unknown_fmt[] = "(Unknown Signal)";
|
||||||
|
|
||||||
|
static void SignalHandler(int sig) {
|
||||||
|
char buf[512];
|
||||||
|
const char *s = signal_unknown_fmt;
|
||||||
|
#define CASE(x) case x: s = #x; break
|
||||||
|
switch (sig) {
|
||||||
|
CASE(SIGTERM);
|
||||||
|
CASE(SIGINT);
|
||||||
|
#ifndef _WIN32
|
||||||
|
CASE(SIGQUIT);
|
||||||
|
CASE(SIGKILL);
|
||||||
|
CASE(SIGHUP);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#undef CASE
|
||||||
|
|
||||||
|
memset(&buf, 0, sizeof buf);
|
||||||
|
snprintf(buf, (sizeof buf) - 1, signal_fmt, s);
|
||||||
|
fprintf(stderr, "%s", buf);
|
||||||
|
|
||||||
|
F_IRC_THREAD = STOPPED;
|
||||||
|
F_MAIN_THREAD = STOPPED;
|
||||||
|
F_SPAM_THREADS = STOPPED;
|
||||||
|
|
||||||
|
if (NULL != irc_session)
|
||||||
|
irc_cmd_quit(irc_session, buf);
|
||||||
|
|
||||||
|
/* TODO: clean exit */
|
||||||
|
}
|
||||||
|
|
||||||
|
void install_signal_handler(void) {
|
||||||
|
signal(SIGTERM, SignalHandler);
|
||||||
|
signal(SIGINT, SignalHandler);
|
||||||
|
#ifndef _WIN32
|
||||||
|
signal(SIGQUIT, SignalHandler);
|
||||||
|
signal(SIGKILL, SignalHandler);
|
||||||
|
signal(SIGHUP, SignalHandler);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user