@@ -0,0 +1,2 @@ | |||
spammer | |||
*.o |
@@ -6,3 +6,11 @@ it takes text from irc and stores it in a database | |||
13:56 <@kashire> We need to make our own dictionary. | |||
13:56 <@kashire> The (un)Official Lain's Diction Book. | |||
# TODO | |||
- Perhaps a database backend and a client frontend that's separate. | |||
- SQL schema | |||
- SQL interface | |||
- Option arguments w/ getopt | |||
- Exit codes |
@@ -0,0 +1,23 @@ | |||
#ifndef DATA_H | |||
#define DATA_H | |||
/* | |||
* We store data in IRC session context. | |||
*/ | |||
typedef struct { | |||
char *channel; | |||
char *nick; | |||
} irc_ctx_t; | |||
/* | |||
* Params that we give to our threads. | |||
*/ | |||
typedef struct { | |||
irc_session_t *session; | |||
const char *phrase; | |||
const char *channel; | |||
int timer; | |||
int unused; | |||
} spam_params_t; | |||
#endif /* DATA_H */ |
@@ -1,10 +1,11 @@ | |||
/* <https://gist.github.com/enile8/2424514> */ | |||
#define _POSIX_C_SOURCE 200809L /* strtok_r, strndup */ | |||
#include <string.h> | |||
#include <assert.h> /* assert */ | |||
#include <sqlite3.h> | |||
#include <stdio.h> /* size_t */ | |||
#include <stdlib.h> /* malloc */ | |||
#include <string.h> /* strdup */ | |||
/* TODO: libircclient for basic IRC functionality. | |||
* Perhaps a database backend and a client frontend that's separate. */ | |||
@@ -12,7 +13,7 @@ | |||
#define UNUSED(x) (void)(x) | |||
#endif | |||
#include "io.c" | |||
#include "io.h" | |||
static int callback(void *NotUsed, int argc, char **argv, char **azColName) { | |||
int i; | |||
@@ -32,10 +33,8 @@ int test_db(char *script_filename) { | |||
const char *db_name; | |||
int j; | |||
int rc; | |||
int nstatements; | |||
sqlite3 *db; | |||
nstatements = 0; | |||
zErrMsg = 0; | |||
orig_statements = file_read(script_filename); | |||
if (orig_statements) { | |||
@@ -57,6 +56,8 @@ int test_db(char *script_filename) { | |||
token = strtok_r(str1, "\n", &saveptr1); | |||
if (token == NULL) | |||
break; | |||
if (strlen(token) > 2 && token[0] == '-' && token[1] == '-') | |||
continue; | |||
printf("%d: %s\n", j, token); | |||
rc = sqlite3_exec(db, token, callback, 0, &zErrMsg); | |||
if (rc != SQLITE_OK) { | |||
@@ -64,7 +65,6 @@ int test_db(char *script_filename) { | |||
sqlite3_free(zErrMsg); | |||
break; | |||
} | |||
nstatements++; /* Number of successfully executed statements */ | |||
} | |||
free(orig_statements); | |||
@@ -0,0 +1,6 @@ | |||
#ifndef DB_H | |||
#define DB_H | |||
int test_db(char *script_filename); | |||
#endif /* DB_H */ |
@@ -0,0 +1,65 @@ | |||
void event_channel (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) | |||
{ | |||
irc_ctx_t * ctx = (irc_ctx_t *) irc_get_ctx (session); | |||
if ( !origin || count != 2 ) | |||
return; | |||
if ( strstr (params[1], "fuck") == 0 ) | |||
return; | |||
char nickbuf[128], text[256]; | |||
irc_target_get_nick (origin, nickbuf, sizeof(nickbuf)); | |||
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; | |||
} | |||
} | |||
void event_nick (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) | |||
{ | |||
char nickbuf[128]; | |||
irc_ctx_t * ctx = (irc_ctx_t *) irc_get_ctx (session); | |||
if ( !origin || count != 1 ) | |||
return; | |||
irc_target_get_nick (origin, nickbuf, sizeof(nickbuf)); | |||
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); | |||
} | |||
} |
@@ -0,0 +1,173 @@ | |||
#include <string.h> | |||
#include <assert.h> /* assert */ | |||
#include <errno.h> | |||
#include <stdio.h> /* size_t */ | |||
#include <stdlib.h> /* malloc */ | |||
#if defined (_WIN32) | |||
#include <windows.h> | |||
#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) | |||
#else | |||
#include <unistd.h> | |||
#include <pthread.h> | |||
#define CREATE_THREAD(id,func,param) (pthread_create (id, 0, func, (void *) param) != 0) | |||
#define THREAD_FUNCTION(funcname) static void * funcname (void * arg) | |||
#define thread_id_t pthread_t | |||
#endif | |||
#include "libircclient.h" | |||
#include "data.h" | |||
#include "events.h" | |||
#ifndef UNUSED | |||
#define UNUSED(x) (void)(x) | |||
#endif | |||
THREAD_FUNCTION(gen_spam) { | |||
spam_params_t *sp = (spam_params_t *) arg; | |||
while (1) { | |||
if (irc_cmd_msg(sp->session, sp->channel, sp->phrase)) | |||
break; | |||
if (sp->timer > 0) | |||
sleep((unsigned int) | |||
sp->timer); | |||
} | |||
return 0; | |||
} | |||
EVENT_SIGNATURE(event_connect) { | |||
irc_ctx_t *ctx; | |||
UNUSED(event); | |||
UNUSED(origin); | |||
UNUSED(params); | |||
UNUSED(count); | |||
ctx = (irc_ctx_t *) | |||
irc_get_ctx(session); | |||
irc_cmd_join(session, ctx->channel, 0); | |||
} | |||
EVENT_NUMERIC_SIGNATURE(event_numeric) { | |||
UNUSED(session); | |||
UNUSED(origin); | |||
UNUSED(params); | |||
UNUSED(count); | |||
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] : ""); | |||
} | |||
} | |||
EVENT_SIGNATURE(event_channel) { | |||
irc_ctx_t *ctx; | |||
char nickbuf[128]; | |||
UNUSED(event); | |||
UNUSED(params); | |||
UNUSED(count); | |||
if (!origin || count != 2) | |||
return; | |||
if (strstr(params[1], "fuck") == 0) | |||
return; | |||
irc_target_get_nick(origin, nickbuf, sizeof(nickbuf)); | |||
ctx = (irc_ctx_t *) irc_get_ctx(session); | |||
UNUSED(ctx); | |||
#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 | |||
} | |||
EVENT_SIGNATURE(event_join) { | |||
irc_ctx_t *ctx; | |||
UNUSED(count); | |||
UNUSED(event); | |||
if (!origin) | |||
return; | |||
ctx = (irc_ctx_t *) | |||
irc_get_ctx(session); | |||
/* | |||
* 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)) { | |||
static spam_params_t spam1; | |||
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 { | |||
char textbuf[168]; | |||
sprintf(textbuf, "Hey, %s, hi!", origin); | |||
irc_cmd_msg(session, params[0], textbuf); | |||
} | |||
} | |||
EVENT_SIGNATURE(event_nick) { | |||
char nickbuf[128]; | |||
irc_ctx_t *ctx; | |||
UNUSED(event); | |||
UNUSED(params); | |||
if (!origin || count != 1) | |||
return; | |||
irc_target_get_nick(origin, nickbuf, sizeof(nickbuf)); | |||
ctx = (irc_ctx_t *) irc_get_ctx(session); | |||
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 | |||
} |
@@ -0,0 +1,26 @@ | |||
#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, \ | |||
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, \ | |||
unsigned int count) | |||
EVENT_SIGNATURE(event_connect); | |||
EVENT_SIGNATURE(event_join); | |||
EVENT_SIGNATURE(event_nick); | |||
EVENT_NUMERIC_SIGNATURE(event_numeric); | |||
#endif /* EVENTS_H */ |
@@ -2,6 +2,8 @@ | |||
#include <stdio.h> /* FILE* */ | |||
#include <stdlib.h> /* malloc, free */ | |||
#include "io.h" | |||
/* <https://rosettacode.org/wiki/Read_entire_file#C> */ | |||
char *file_read(const char *filename) { | |||
char *buffer; | |||
@@ -15,10 +17,11 @@ char *file_read(const char *filename) { | |||
fseek(fh, 0L, SEEK_END); | |||
size = ftell(fh); | |||
rewind(fh); | |||
buffer = malloc(size); | |||
if (size > 0) | |||
buffer = (char*)malloc((size_t)size); | |||
if (buffer != NULL) { | |||
assert(buffer != NULL); | |||
nread = fread(buffer, 1, size, fh); | |||
nread = fread(buffer, 1, (size_t)size, fh); | |||
fclose(fh); | |||
fh = NULL; | |||
if (size != (long)nread) { | |||
@@ -0,0 +1,8 @@ | |||
#ifndef IO_H | |||
#define IO_H | |||
char *file_read(const char *filename); | |||
size_t file_write(const char *fileName, const void *data, const size_t size); | |||
#endif /* IO_H */ |
@@ -1,14 +1,36 @@ | |||
CFLAGS += -ggdb -O0 -std=c89 -W -Wall -Wextra -pedantic | |||
CC = g++ | |||
CFLAGS += -g -O -Wall -Weffc++ -pedantic \ | |||
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \ | |||
-Wcast-qual -Wconversion \ | |||
-Wdisabled-optimization \ | |||
-Werror -Wfloat-equal -Wformat=2 \ | |||
-Wformat-nonliteral -Wformat-security \ | |||
-Wformat-y2k \ | |||
-Wimport -Winit-self -Winline \ | |||
-Winvalid-pch \ | |||
-Wlong-long \ | |||
-Wmissing-field-initializers -Wmissing-format-attribute \ | |||
-Wmissing-include-dirs -Wmissing-noreturn \ | |||
-Wpacked -Wpadded -Wpointer-arith \ | |||
-Wredundant-decls \ | |||
-Wshadow -Wstack-protector \ | |||
-Wstrict-aliasing=2 -Wswitch-default \ | |||
-Wswitch-enum \ | |||
-Wunreachable-code -Wunused \ | |||
-Wunused-parameter \ | |||
-Wvariadic-macros \ | |||
-Wwrite-strings | |||
#-ggdb -O0 -std=c89 -W -Wall -Wextra -pedantic | |||
LDFLAGS += -lpthread -lircclient -lsqlite3 | |||
all: spammer | |||
spammer: spammer.c | |||
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) | |||
spammer: spammer.o io.o db.o events.o | |||
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) | |||
# TODO: client side / offline access | |||
db: db.c | |||
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) -DTEST_DB | |||
db: db.o io.o | |||
$(CC) -DTEST_DB $(CFLAGS) $^ -o $@ $(LDFLAGS) | |||
clean: | |||
$(RM) -rf spammer db a.out *.o *.db |
@@ -1,7 +1,7 @@ | |||
create table if not exists quotedb (date_added text not null, added_by text not null, subject text not null, words text not null) | |||
create table if not exists quotedb (quote_id integer primary key autoincrement, date_added text not null, added_by text not null, channel text not null, subject text not null, words text not null) | |||
insert into quotedb (date_added, added_by , subject, words) values (datetime('now'), 'strike', 'Flisk', "<Flisk> yeah hate when hookers who give free blowjobs won't finger my asshole for free too") | |||
insert into quotedb (date_added, added_by , subject, words) values (datetime('now'), 'oda', 'nimbius', ' * nimbius is no longer thinking about those beans') | |||
insert into quotedb (date_added, channel, added_by, subject, words) values (datetime('now'), '#lainchan', 'strike', 'Flisk', "<Flisk> yeah hate when hookers who give free blowjobs won't finger my asshole for free too") | |||
insert into quotedb (date_added, channel, added_by, subject, words) values (datetime('now'), '#lainchan', 'oda', 'nimbius', '* nimbius is no longer thinking about those beans') | |||
select * from quotedb | |||
@@ -1,4 +1,5 @@ | |||
/* code adapted from: | |||
/* | |||
* code adapted from: | |||
* <https://gist.github.com/enile8/2424514> | |||
* <https://www.rosettacode.org/wiki/Write_entire_file#C> | |||
* <https://rosettacode.org/wiki/Read_entire_file#C> | |||
@@ -30,61 +31,32 @@ | |||
* | |||
* Quote bot. WIP. | |||
*/ | |||
#define _XOPEN_SOURCE 500 /* strdup */ | |||
#define _POSIX_C_SOURCE 200809L /* strtok_r, strndup */ | |||
#include <string.h> | |||
#include <assert.h> /* assert */ | |||
#include <errno.h> | |||
#include <stdio.h> /* size_t */ | |||
#include <stdlib.h> /* malloc */ | |||
/* TODO: libircclient for basic IRC functionality. | |||
* Perhaps a database backend and a client frontend that's separate. */ | |||
#if defined (_WIN32) | |||
#include <windows.h> | |||
#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) | |||
#else | |||
#include <unistd.h> | |||
#include <pthread.h> | |||
#define CREATE_THREAD(id,func,param) (pthread_create (id, 0, func, (void *) param) != 0) | |||
#define THREAD_FUNCTION(funcname) static void * funcname (void * arg) | |||
#define thread_id_t pthread_t | |||
#endif | |||
#include "libircclient.h" | |||
#include "data.h" | |||
#include "db.h" | |||
#include "events.h" | |||
#ifndef UNUSED | |||
#define UNUSED(x) (void)(x) | |||
#endif | |||
/* | |||
* We store data in IRC session context. | |||
*/ | |||
typedef struct { | |||
char *channel; | |||
char *nick; | |||
} irc_ctx_t; | |||
/* | |||
* Params that we give to our threads. | |||
*/ | |||
typedef struct { | |||
irc_session_t *session; | |||
const char *phrase; | |||
const char *channel; | |||
int timer; | |||
} spam_params_t; | |||
#include "db.c" | |||
/* <https://rosettacode.org/wiki/Levenshtein_distance#C> | |||
* TODO: use this for quote duplicate removal */ | |||
int dist(const char *s, const char *t, int *d, int ls, int lt, int i, int j) { | |||
int x, y; | |||
int *n = d + i * ls + j; | |||
if (*(d + i * ls + j) >= 0) | |||
return *(d + i * ls + j); | |||
if (*n >= 0) | |||
return *n; | |||
if (i == ls) | |||
x = lt - j; | |||
@@ -101,14 +73,14 @@ int dist(const char *s, const char *t, int *d, int ls, int lt, int i, int j) { | |||
x = y; | |||
x++; | |||
} | |||
return *(d + i * ls + j) = x; | |||
return *n = x; | |||
} | |||
int levenshtein(const char *s, const char *t) { | |||
int i, j, n; | |||
int ls = strnlen(s, 128), lt = strnlen(t, 128); | |||
int ls = (int)strnlen(s, 128), lt = (int)strnlen(t, 128); | |||
int *d; | |||
d = malloc(sizeof(int) * ((ls + 1) * (lt + 1))); | |||
d = (int*)malloc(sizeof(int) * (unsigned long)((ls + 1) * (lt + 1))); | |||
for (i = 0; i <= ls; i++) | |||
for (j = 0; j <= lt; j++) | |||
*(d + i * ls + j) = -1; | |||
@@ -118,76 +90,8 @@ int levenshtein(const char *s, const char *t) { | |||
return n; | |||
} | |||
THREAD_FUNCTION(gen_spam) { | |||
spam_params_t *sp = (spam_params_t *) arg; | |||
while (1) { | |||
if (irc_cmd_msg(sp->session, sp->channel, sp->phrase)) | |||
break; | |||
sleep(sp->timer); | |||
} | |||
return 0; | |||
} | |||
void event_join(irc_session_t * session, const char *event, const char *origin, const char **params, unsigned int count) { | |||
irc_ctx_t *ctx; | |||
UNUSED(count); | |||
UNUSED(event); | |||
if (!origin) | |||
return; | |||
ctx = (irc_ctx_t *) irc_get_ctx(session); | |||
/* | |||
* 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)) { | |||
static spam_params_t spam1; | |||
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 { | |||
char textbuf[168]; | |||
sprintf(textbuf, "Hey, %s, hi!", origin); | |||
irc_cmd_msg(session, params[0], textbuf); | |||
} | |||
} | |||
void event_connect(irc_session_t * session, const char *event, const char *origin, const char **params, unsigned int count) { | |||
irc_ctx_t *ctx; | |||
UNUSED(event); | |||
UNUSED(origin); | |||
UNUSED(params); | |||
UNUSED(count); | |||
ctx = (irc_ctx_t *) irc_get_ctx(session); | |||
irc_cmd_join(session, ctx->channel, 0); | |||
} | |||
void event_numeric(irc_session_t * session, unsigned int event, const char *origin, const char **params, unsigned int count) { | |||
UNUSED(session); | |||
UNUSED(origin); | |||
UNUSED(params); | |||
UNUSED(count); | |||
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] : ""); | |||
} | |||
} | |||
int main(int argc, char **argv) { | |||
int dirty_exit; | |||
char *script_filename; | |||
irc_callbacks_t callbacks; | |||
irc_ctx_t ctx; | |||
@@ -198,7 +102,6 @@ int main(int argc, char **argv) { | |||
const char *s2 = "raisethysword"; | |||
printf("distance between `%s' and `%s': %d\n", s1, s2, levenshtein(s1, s2)); | |||
/* TODO: getopt */ | |||
if (argc == 2) { | |||
script_filename = argv[1]; | |||
return test_db(script_filename); | |||
@@ -208,6 +111,7 @@ int main(int argc, char **argv) { | |||
return 1; | |||
} | |||
} | |||
/* Initialize the callbacks */ | |||
memset(&callbacks, 0, sizeof(callbacks)); | |||
/* Set up the callbacks we will use */ | |||
@@ -246,5 +150,6 @@ int main(int argc, char **argv) { | |||
printf("Could not connect or I/O error: %s\n", irc_strerror(irc_errno(s))); | |||
return 1; | |||
} | |||
return 1; | |||
dirty_exit = 0; | |||
return dirty_exit; | |||
} |