#include #include /* assert */ #include #include /* size_t */ #include "libircclient.h" #include "data.h" #include "events.h" #include "strings.h" #include "threads.h" #include "unused.h" char F_SPAM_THREADS = STOPPED; 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; while (RUNNING == F_SPAM_THREADS) { if (irc_cmd_msg(sp->session, sp->channel, sp->phrase)) break; if (sp->timer > 0) sleep(sp->timer); } return 0; } /* 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; 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 = 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(string_thread_failure, strerror(errno)); else printf("%s", string_spam_success); } EVENT_GENERIC_SIGNATURE(dump_event) { char buf[1024]; unsigned int cnt; size_t bufsize, nwritten; UNUSED(session); bufsize = sizeof buf; memset(buf, 0, bufsize); nwritten = 0; cnt = 0; while (cnt < count && nwritten < (bufsize-1)) { if (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_GENERIC_SIGNATURE(irc_event_connect) { struct irc_ctx_t *ctx; UNUSED(event); UNUSED(origin); UNUSED(params); UNUSED(count); ctx = (struct irc_ctx_t *)irc_get_ctx(session); printf(string_connect_success, ctx->server, ctx->port, ctx->nick, ctx->channel); irc_cmd_join(session, ctx->channel, 0); } EVENT_NUMERIC_SIGNATURE(irc_event_numeric) { char buf[24]; snprintf(buf, sizeof buf, "%d", event); dump_event(session, buf, origin, params, 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 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_GENERIC_SIGNATURE(irc_event_channel) { struct irc_ctx_t *ctx; char nickbuf[128]; UNUSED(event); UNUSED(params); UNUSED(count); dump_event(session, event, origin, params, count); if (NULL == origin || count < 2) return; irc_target_get_nick(origin, nickbuf, sizeof(nickbuf)); if (!IsAdmin(nickbuf)) { return; } ctx = (struct irc_ctx_t *)irc_get_ctx(session); 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 (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_GENERIC_SIGNATURE(irc_event_join) { char buf[128]; struct irc_ctx_t *ctx; UNUSED(count); UNUSED(event); if (!origin) return; ctx = (struct 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)) { 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); } } EVENT_GENERIC_SIGNATURE(irc_event_nick) { char nickbuf[128]; struct irc_ctx_t *ctx; UNUSED(event); UNUSED(params); if (!origin || count != 1) return; irc_target_get_nick(origin, nickbuf, sizeof(nickbuf)); ctx = (struct 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 } 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]); }