From b80aa547eaaeee84b4cd43c1d81f35e176cc9df6 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 21 Jul 2011 22:58:53 +0200 Subject: [PATCH] changed type of shitlist to dict_t and added cmd_listbad, cmd_addbad & cmd_delbad --- src/mod-watchdog.c | 202 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 159 insertions(+), 43 deletions(-) diff --git a/src/mod-watchdog.c b/src/mod-watchdog.c index 4cfcd34..3f48feb 100644 --- a/src/mod-watchdog.c +++ b/src/mod-watchdog.c @@ -29,6 +29,7 @@ */ #include "chanserv.h" +#include "opserv.h" #include "conf.h" #include "modcmd.h" #include "saxdb.h" @@ -39,17 +40,21 @@ #define KEY_BADWORD_TRIGGERED "count" #define KEY_BADWORD_ACTION "action" #define KEY_CHANNELS "channel" +#define KEY_BADWORDID "badwordid" static const struct message_entry msgtab[] = { - { "WD_REGISTER_SUCCESS", "$b%s$b is now registered with %s." }, - { "WD_NOT_REGISTERED", "$b%s$b is not registered with %s." }, + { "WDMSG_REGISTER_SUCCESS", "$b%s$b is now registered with %s." }, + { "WDMSG_NOT_REGISTERED", "$b%s$b is not registered with %s." }, + { "WDMSG_ALREADY_ADDED", "$b%s$b is already added. (ID: %s)" }, + { "WDMSG_BADWORD_ADDED", "added '$b%s$b' to the badword list with ID %s." }, + { "WDMSG_BADWORD_NOT_FOUND", "badword with ID %s does not exist." }, + { "WDMSG_BADWORD_REMOVED", "badword ID $b%s$b has been removed (mask: '%s')" }, + { "ID_DEBUG", "%s: %s" }, { NULL, NULL } }; -DECLARE_LIST(shitList, struct badword*); -DEFINE_LIST(shitList, struct badword*) - struct badword { + char *id; char *badword_mask; unsigned int triggered : 29; unsigned int action : 3; @@ -74,20 +79,52 @@ const char *watchdog_module_deps[] = { NULL }; struct userNode *watchdog; static struct module *watchdog_module; static struct service *watchdog_service; -static struct shitList shitlist; +static dict_t shitlist; static dict_t chanlist; static struct log_type *MS_LOG; +static unsigned int last_badword_id = 0; +static struct watchdog_channel *add_channel(const char *name); +static struct badword *add_badword(const char *badword_mask, unsigned int triggered, unsigned int action, const char *id); +#define watchdog_notice(target, format...) send_message(target , watchdog , ## format) static MODCMD_FUNC(cmd_addbad) { - //to be continued... + dict_iterator_t it; + char *mask = unsplit_string(argv + 1, argc - 1, NULL); + for (it = dict_first(shitlist); it; it = iter_next(it)) { + struct badword *badword = iter_data(it); + if(match_ircglob(mask,badword->badword_mask)) { + reply("WDMSG_ALREADY_ADDED", mask, badword->id); + return 1; + } + } + + struct badword *new_badword = add_badword(mask, 0, BADACTION_KICK, NULL); + for (it = dict_first(shitlist); it; it = iter_next(it)) { + struct badword *badword = iter_data(it); + if(match_ircglob(badword->badword_mask, new_badword->badword_mask) && badword != new_badword) { + dict_remove(shitlist, badword->id); + } + } + + reply("WDMSG_BADWORD_ADDED", new_badword->badword_mask, new_badword->id); return 1; } static MODCMD_FUNC(cmd_delbad) { - //to be continued... + unsigned int n; + + for (n=1; nbadword_mask); + dict_remove(shitlist, argv[n]); + } return 1; } @@ -97,14 +134,79 @@ static MODCMD_FUNC(cmd_editbad) return 1; } +int +badwords_sort(const void *pa, const void *pb) +{ + struct badword *a = *(struct badword**)pa; + struct badword *b = *(struct badword**)pb; + + return strtoul(a->id, NULL, 0) - strtoul(b->id, NULL, 0); +} + static MODCMD_FUNC(cmd_listbad) { - //to be continued... + struct helpfile_table tbl; + unsigned int count = 0, ii = 0; + struct badword **badwords; + + dict_iterator_t it; + for (it = dict_first(shitlist); it; it = iter_next(it)) { + count++; + } + tbl.length = count+1; + tbl.width = 4; + tbl.flags = 0; + tbl.flags = TABLE_NO_FREE; + tbl.contents = malloc(tbl.length * sizeof(tbl.contents[0])); + tbl.contents[0] = malloc(tbl.width * sizeof(tbl.contents[0][0])); + tbl.contents[0][0] = "#"; + tbl.contents[0][1] = "Badword"; + tbl.contents[0][2] = "Action"; + tbl.contents[0][3] = "(Triggered)"; + if(!count) + { + table_send(cmd->parent->bot, user->nick, 0, NULL, tbl); + reply("MSG_NONE"); + free(tbl.contents[0]); + free(tbl.contents); + return 0; + } + badwords = alloca(count * sizeof(badwords[0])); + for (it = dict_first(shitlist); it; it = iter_next(it)) { + struct badword *bw = iter_data(it); + badwords[ii++] = bw; + } + qsort(badwords, count, sizeof(badwords[0]), badwords_sort); + for (ii = 1; ii <= count; ii++) { + struct badword *bw = badwords[ii-1]; + tbl.contents[ii] = malloc(tbl.width * sizeof(tbl.contents[0][0])); + tbl.contents[ii][0] = strdup(bw->id); + tbl.contents[ii][1] = strdup(bw->badword_mask); + switch(bw->action) { + case BADACTION_KICK: + tbl.contents[ii][2] = "KICK"; + break; + case BADACTION_KILL: + tbl.contents[ii][2] = "KILL"; + break; + case BADACTION_GLINE: + tbl.contents[ii][2] = "GLINE"; + break; + default: + tbl.contents[ii][2] = "*undef*"; + } + tbl.contents[ii][3] = strtab(bw->triggered); + } + table_send(cmd->parent->bot, user->nick, 0, NULL, tbl); + for(ii = 1; ii < tbl.length; ++ii) + { + free(tbl.contents[ii]); + } + free(tbl.contents[0]); + free(tbl.contents); return 1; } -static struct watchdog_channel *add_channel(const char *name); - static MODCMD_FUNC(cmd_register) { dict_iterator_t it; @@ -132,7 +234,7 @@ static MODCMD_FUNC(cmd_register) } add_channel(channel->name); - reply("WD_REGISTER_SUCCESS", channel->name, watchdog->nick); + reply("WDMSG_REGISTER_SUCCESS", channel->name, watchdog->nick); return 1; } @@ -154,7 +256,7 @@ static MODCMD_FUNC(cmd_unregister) reply("CSMSG_UNREG_SUCCESS", channel->name); return 1; } else { - reply("WD_NOT_REGISTERED", channel->name, watchdog->nick); + reply("WDMSG_NOT_REGISTERED", channel->name, watchdog->nick); return 0; } @@ -167,7 +269,7 @@ watchdog_channel_message(struct userNode *user, struct chanNode *chan, const cha } static struct badword* -add_badword(char *badword_mask, unsigned int triggered, unsigned int action) +add_badword(const char *badword_mask, unsigned int triggered, unsigned int action, const char *id) { struct badword *badword; @@ -175,17 +277,23 @@ add_badword(char *badword_mask, unsigned int triggered, unsigned int action) if (!badword) return NULL; + if(!id) { + last_badword_id++; + badword->id = strtab(last_badword_id); + } else + badword->id = strdup(id); badword->badword_mask = strdup(badword_mask); badword->triggered = triggered; badword->action = action; - shitList_append(&shitlist, badword); + dict_insert(shitlist, badword->id, badword); return badword; } static void -delete_badword(struct badword *badword) +free_shitlist_entry(void *data) { - shitList_remove(&shitlist, badword); + struct badword *badword = data; + free(badword->id); free(badword->badword_mask); free(badword); } @@ -258,10 +366,9 @@ watchdog_saxdb_read_shitlist(const char *name, void *data, UNUSED_ARG(void *extr triggered = database_get_data(obj, KEY_BADWORD_TRIGGERED, RECDB_QSTRING); action = database_get_data(obj, KEY_BADWORD_ACTION, RECDB_QSTRING); - add_badword(badword, strtoul(triggered, NULL, 0), strtoul(action, NULL, 0)); - return 1; - } else - return 0; + add_badword(badword, strtoul(triggered, NULL, 0), strtoul(action, NULL, 0), name); + } + return 0; } static int @@ -274,41 +381,49 @@ watchdog_saxdb_read_chanlist(const char *name, void *data, UNUSED_ARG(void *extr /* nothing in here, yet */ add_channel(name); - return 1; - } else - return 0; + } + return 0; } static int watchdog_saxdb_read(struct dict *db) { struct dict *object; + char *str; + str = database_get_data(db, KEY_BADWORDID, RECDB_QSTRING); + last_badword_id = str ? strtoul(str, NULL, 0) : 0; + if ((object = database_get_data(db, KEY_BADWORDS, RECDB_OBJECT))) dict_foreach(object, watchdog_saxdb_read_shitlist, NULL); + if ((object = database_get_data(db, KEY_CHANNELS, RECDB_OBJECT))) dict_foreach(object, watchdog_saxdb_read_chanlist, NULL); + return 1; } static int watchdog_saxdb_write(struct saxdb_context *ctx) { - struct badword *badword; - char str[17]; - unsigned int id = 0, ii; + char str[10]; dict_iterator_t it; - saxdb_start_record(ctx, KEY_BADWORDS, 1); - for (ii = 0; ii < shitlist.used; ++ii) { - badword = shitlist.list[ii]; - snprintf(str, sizeof(str), "%x", id++); - saxdb_start_record(ctx, str, 0); - saxdb_write_string(ctx, KEY_BADWORD_MASK, badword->badword_mask); - saxdb_write_int(ctx, KEY_BADWORD_TRIGGERED, badword->triggered); - saxdb_write_int(ctx, KEY_BADWORD_ACTION, badword->action); + saxdb_write_int(ctx, KEY_BADWORDID, last_badword_id); + + if (dict_size(shitlist)) { + saxdb_start_record(ctx, KEY_BADWORDS, 1); + for (it = dict_first(shitlist); it; it = iter_next(it)) { + struct badword *badword = iter_data(it); + saxdb_start_record(ctx, iter_key(it), 0); + + saxdb_write_string(ctx, KEY_BADWORD_MASK, badword->badword_mask); + saxdb_write_int(ctx, KEY_BADWORD_TRIGGERED, badword->triggered); + saxdb_write_int(ctx, KEY_BADWORD_ACTION, badword->action); + + saxdb_end_record(ctx); + } saxdb_end_record(ctx); } - saxdb_end_record(ctx); if (dict_size(chanlist)) { saxdb_start_record(ctx, KEY_CHANNELS, 1); @@ -327,9 +442,7 @@ watchdog_saxdb_write(struct saxdb_context *ctx) static void watchdog_cleanup(void) { - while (shitlist.used) - delete_badword(shitlist.list[0]); - shitList_clean(&shitlist); + dict_delete(shitlist); dict_delete(chanlist); } @@ -338,7 +451,10 @@ watchdog_init(void) { MS_LOG = log_register_type("Watchdog", "file:watchdog.log"); - shitList_init(&shitlist); + /* set up shitlist dict */ + dict_delete(shitlist); + shitlist = dict_new(); + dict_set_free_data(shitlist, free_shitlist_entry); /* set up chanlist dict */ dict_delete(chanlist); chanlist = dict_new(); @@ -358,11 +474,11 @@ watchdog_init(void) saxdb_register("Watchdog", watchdog_saxdb_read, watchdog_saxdb_write); watchdog_module = module_register("Watchdog", MS_LOG, "mod-watchdog.help", NULL); - modcmd_register(watchdog_module, "addbad", cmd_addbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); - modcmd_register(watchdog_module, "delbad", cmd_delbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); + modcmd_register(watchdog_module, "addbad", cmd_addbad, 2, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); + modcmd_register(watchdog_module, "delbad", cmd_delbad, 2, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); modcmd_register(watchdog_module, "editbad", cmd_editbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); modcmd_register(watchdog_module, "listbad", cmd_listbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL); - modcmd_register(watchdog_module, "register", cmd_register, 1, MODCMD_REQUIRE_AUTHED, "flags", "+helping", NULL); + modcmd_register(watchdog_module, "register", cmd_register, 2, MODCMD_REQUIRE_AUTHED, "flags", "+helping", NULL); modcmd_register(watchdog_module, "unregister", cmd_unregister, 1, MODCMD_REQUIRE_AUTHED | MODCMD_REQUIRE_CHANNEL, "flags", "+helping", NULL); message_register_table(msgtab); -- 2.20.1