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
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}
#include "WHOHandler.h"
#include "DBHelper.h"
#include "tools.h"
+#include "timeq.h"
#define BOTID 1
{"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}
};
#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"
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);
--- /dev/null
+
+/*
+* 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);
+}
/*
-* 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);
#include "HandleInfoHandler.h"
#include "lang.h"
#include "tools.h"
+#include "timeq.h"
void cleanup() {
free_sockets();
do {
socket_loop(SOCKET_SELECT_TIME);
} while(time(0) < socket_wait);
+ timeq_tick();
clearTempUsers();
}
}
--- /dev/null
+
+#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;
+}
--- /dev/null
+#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