added cmd_addban & simple time queue system
authorpk910 <philipp@zoelle1.de>
Thu, 8 Sep 2011 03:02:27 +0000 (05:02 +0200)
committerpk910 <philipp@zoelle1.de>
Thu, 8 Sep 2011 03:11:20 +0000 (05:11 +0200)
DATABASE.txt
Makefile
bot_NeonServ.c
cmd_neonserv_addban.c [new file with mode: 0644]
cmd_neonserv_ban.c
main.c
timeq.c [new file with mode: 0644]
timeq.h [new file with mode: 0644]

index 09ca9c4f647eda8aca72b28edac557bf9659153e..c2688f022210d6df2f588deb2bcb1a086adeea1b 100644 (file)
@@ -29,3 +29,5 @@ ALTER TABLE `chanusers` ADD INDEX ( `chanuser_uid` ) ;
 ALTER TABLE `bot_binds` ADD `chan_access` VARCHAR( 256 ) NULL DEFAULT NULL AFTER `parameters` 
 
 ALTER TABLE `bot_binds` CHANGE `global_access` `global_access` INT( 3 ) NULL 
+
+ALTER TABLE `bans` CHANGE `ban_owner` `ban_owner` INT( 11 ) NOT NULL 
index bd3f3c89a0fbe0493d91929c04a7bf588e4cfc9f..0f5bdbda87af0e69bde65bc4113a48ad1461d3d3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ all:
        gcc -g -O2 ${LIBS} -c lang.c -o lang.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c HandleInfoHandler.c -o HandleInfoHandler.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c tools.c -o tools.o ${CFLAGS}
+       gcc -g -O2 ${LIBS} -c timeq.c -o timeq.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c DBHelper.c -o DBHelper.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c bots.c -o bots.o ${CFLAGS}
        gcc -g -O2 ${LIBS} -c bot_NeonServ.c -o bot_NeonServ.o ${CFLAGS}
index ec6615a17137c99169c37f7a1a83f578e790ab25..7a0a772cf372a9106f33dc300407921846acec4b 100644 (file)
@@ -13,6 +13,7 @@
 #include "WHOHandler.h"
 #include "DBHelper.h"
 #include "tools.h"
+#include "timeq.h"
 
 #define BOTID 1
 
@@ -119,6 +120,7 @@ static const struct default_language_entry msgtab[] = {
     {"NS_WIPEINFO_DONE", "Removed \002%s\002's infoline in \002%s\002."},
     {"NS_TRACE_HEADER", "The following users were found:"},
     {"NS_TRACE_FOUND", "Found \002%d\002 matches."},
+    {"NS_ADDBAN_DONE", "\002%s\002 permantly added to the %s ban list. (matching %d users)"},
     {NULL, NULL}
 };
 
@@ -158,7 +160,7 @@ INCLUDE ALL CMD's HERE
 #include "cmd_neonserv_suspend.c"
 #include "cmd_neonserv_unsuspend.c"
 #include "cmd_neonserv_wipeinfo.c"
-//#include "cmd_neonserv_addban.c"
+#include "cmd_neonserv_addban.c"
 //#include "cmd_neonserv_addtimeban.c"
 //#include "cmd_neonserv_delban.c"
 //#include "cmd_neonserv_banlist.c"
@@ -300,6 +302,7 @@ void init_NeonServ() {
     register_command(BOTID, "kickban",      neonserv_cmd_kickban,   1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,  "#channel_cankick,#channel_canban", 0);
     register_command(BOTID, "ban",          neonserv_cmd_ban,       1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,  "#channel_canban",      0);
     register_command(BOTID, "wipeinfo",     neonserv_cmd_wipeinfo,  1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,  "#channel_wipeinfo",    0);
+    register_command(BOTID, "addban",       neonserv_cmd_addban,    1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,  "#channel_staticban",   0);
     
     register_command(BOTID, "trace",        neonserv_cmd_trace,     1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,                                                   NULL,                   400);
     
diff --git a/cmd_neonserv_addban.c b/cmd_neonserv_addban.c
new file mode 100644 (file)
index 0000000..91202d9
--- /dev/null
@@ -0,0 +1,81 @@
+
+/*
+* argv[0]    nick|*auth|*!*@mask
+* argv[1-*]  reason
+*/
+static USERLIST_CALLBACK(neonserv_cmd_addban_userlist_lookup);
+static void neonserv_cmd_addban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *mas, char *reason);
+
+struct neonserv_cmd_addban_cache {
+    struct ClientSocket *client, *textclient;
+    struct UserNode *user;
+    char *mask;
+    char *reason;
+};
+
+static CMD_BIND(neonserv_cmd_addban) {
+    struct neonserv_cmd_addban_cache *cache = malloc(sizeof(*cache));
+    if (!cache) {
+        perror("malloc() failed");
+        return;
+    }
+    cache->client = client;
+    cache->textclient = getTextBot();
+    cache->user = user;
+    cache->mask = strdup(argv[0]);
+    if(argc > 1) {
+        cache->reason = strdup(merge_argv(argv, 1, argc));
+    } else
+        cache->reason = NULL;
+    get_userlist(chan, neonserv_cmd_addban_userlist_lookup, cache);
+}
+
+static USERLIST_CALLBACK(neonserv_cmd_addban_userlist_lookup) {
+    struct neonserv_cmd_addban_cache *cache = data;
+    neonserv_cmd_addban_async1(cache->client, cache->textclient, cache->user, chan, cache->mask, (cache->reason ? cache->reason : "Bye."));
+    free(cache->mask);
+    if(cache->reason)
+        free(cache->reason);
+    free(cache);
+}
+
+static void neonserv_cmd_addban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *mask, char *reason) {
+    int match_count = 0;
+    char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3];
+    char usermask[NICKLEN+USERLEN+HOSTLEN+3];
+    struct UserNode *cuser;
+    struct ChanUser *chanuser;
+    check_mysql();
+    mask = make_banmask(mask, hostmask_buffer);
+    for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+        cuser = chanuser->user;
+        sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+        if(!match(mask, usermask)) {
+            if(isNetworkService(chanuser->user)) {
+                reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick);
+                return;
+            }
+            if(isUserProtected(chan, cuser, user)) {
+                reply(textclient, user, "NS_USER_PROTECTED", cuser->nick);
+                return;
+            }
+            match_count++;
+            if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) {
+                reply(textclient, user, "NS_LAME_MASK", mask);
+                return;
+            }
+        }
+    }
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
+    int userid;
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL)
+        userid = atoi(row[0]);
+    else
+        return;
+    //add the ban
+    printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', '%u', '%d', '%s')", chan->channel_id, escape_string(mask), (unsigned int) time(0), userid, escape_string(reason));
+    reply(getTextBot(), user, "NS_ADDBAN_DONE", mask, chan->name, match_count);
+}
index b3291311d0f8a1ede66a01b76b1a4a7fc8fbe18e..e51934d4a38d98224ce879ac013868ad1ac72b3c 100644 (file)
@@ -1,7 +1,6 @@
 
 /*
-* argv[0]    nick[,*auth[,*!*@mask[...]]]
-* argv[1-*]  reason
+* argv[0-*]    nick[,*auth[,*!*@mask[...]]]
 */
 static USERLIST_CALLBACK(neonserv_cmd_ban_userlist_lookup);
 static void neonserv_cmd_ban_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *masks);
diff --git a/main.c b/main.c
index 56305fca32d8b4b7abf35a7c22c303a7211f8a09..bcf2fb22a2112baeb9887c9aa67d37aacad1edcd 100644 (file)
--- a/main.c
+++ b/main.c
@@ -12,6 +12,7 @@
 #include "HandleInfoHandler.h"
 #include "lang.h"
 #include "tools.h"
+#include "timeq.h"
 
 void cleanup() {
     free_sockets();
@@ -46,6 +47,7 @@ int main(void)
         do {
             socket_loop(SOCKET_SELECT_TIME);
         } while(time(0) < socket_wait);
+        timeq_tick();
         clearTempUsers();
     }
 }
diff --git a/timeq.c b/timeq.c
new file mode 100644 (file)
index 0000000..60d92f7
--- /dev/null
+++ b/timeq.c
@@ -0,0 +1,62 @@
+
+#include "timeq.h"
+
+static struct timeq_entry *timeq_events;
+
+void timeq_tick() {
+    struct timeq_entry *entry, *next;
+    time_t now = time(0);
+    for(entry = timeq_events; entry; entry = next) {
+        if(entry->execute <= now) {
+            entry->callback(entry->data);
+            next = entry->next;
+            free(entry);
+        } else
+            break;
+    }
+}
+
+struct timeq_entry* timeq_add(int seconds, timeq_callback_t *callback, void *data) {
+    time_t now = time(0);
+    struct timeq_entry *entry = malloc(sizeof(*entry));
+    if (!entry)
+    {
+        perror("malloc() failed");
+        return NULL;
+    }
+    entry->execute = now + seconds;
+    entry->callback = callback;
+    entry->data = data;
+    struct timeq_entry *next, *prev = NULL;
+    for(next = timeq_events; next; next = next->next) {
+        if(next->execute >= entry->execute)
+            break;
+        else
+            prev = next;
+    }
+    if(prev == NULL) {
+        entry->next = timeq_events;
+        timeq_events = entry;
+    } else {
+        entry->next = next;
+        prev->next = entry;
+    }
+    return entry;
+}
+
+int timeq_del(struct timeq_entry* entry) {
+    struct timeq_entry *centry, *last = NULL;
+    for(centry = timeq_events; centry; centry = centry->next) {
+        if(centry == entry) {
+            if(last)
+                last->next = centry->next;
+            else
+                timeq_events = centry->next;
+            free(centry);
+            return 1;
+        } else {
+            last = centry;
+        }
+    }
+    return 0;
+}
diff --git a/timeq.h b/timeq.h
new file mode 100644 (file)
index 0000000..d683c9a
--- /dev/null
+++ b/timeq.h
@@ -0,0 +1,21 @@
+#ifndef _timeq_h
+#define _timeq_h
+
+#include "main.h"
+
+#define TIMEQ_CALLBACK(NAME) int NAME(UNUSED_ARG(void *data))
+typedef TIMEQ_CALLBACK(timeq_callback_t);
+
+struct timeq_entry {
+    time_t execute;
+    timeq_callback_t *callback;
+    void *data;
+    
+    struct timeq_entry *next;
+};
+
+void timeq_tick();
+struct timeq_entry* timeq_add(int seconds, timeq_callback_t *callback, void *data);
+int timeq_del(struct timeq_entry* entry);
+
+#endif
\ No newline at end of file