added cmd_trace and cmd_wipeinfo
authorpk910 <philipp@zoelle1.de>
Mon, 5 Sep 2011 21:50:09 +0000 (23:50 +0200)
committerpk910 <philipp@zoelle1.de>
Thu, 8 Sep 2011 03:11:14 +0000 (05:11 +0200)
UserNode.c
UserNode.h
bot_NeonServ.c
cmd_neonserv_trace.c [new file with mode: 0644]
cmd_neonserv_wipeinfo.c [new file with mode: 0644]

index a20fb1e49b9ee1dd4627f24f4079e0f091663d72..dccdad9d7a14579c958159af4225b100924de22d 100644 (file)
@@ -128,6 +128,21 @@ char *getAuthFakehost(char *auth) {
     return NULL;
 }
 
+struct UserNode* getAllUsers(struct UserNode *last) {
+    if(last == NULL || last->next == NULL) {
+        int cindex;
+        if(last == NULL)
+            cindex = 0;
+        else
+            cindex = get_nicklist_entry(last->nick[0]) + 1;
+        while(userList[cindex] == NULL && cindex <= VALID_NICK_CHARS_FIRST_LEN)
+            cindex++;
+        if(cindex > VALID_NICK_CHARS_FIRST_LEN) return NULL;
+        return userList[cindex];
+    } else
+        return last->next;
+}
+
 struct UserNode* addUser(const char *nick) {
     int userListIndex = get_nicklist_entry(*nick);
     if(userListIndex == -1 || !is_valid_nick(nick))
index 4aebb54efabde07e4479edb1d5b7a334012a1227..0048398f4a38b63f354aea0e58cdfb1caa720569 100644 (file)
@@ -42,6 +42,7 @@ struct UserNode* getUserByMask(const char *mask);
 int countUsersWithHost(char *host);
 char *getAuthFakehost(char *auth);
 struct UserNode* searchUserByNick(const char *nick);
+struct UserNode* getAllUsers(struct UserNode *last);
 struct UserNode* addUser(const char *nick);
 struct UserNode* addUserMask(const char *mask);
 struct UserNode* createTempUser(const char *mask);
index 181eaa4ac5e52986cfad001d1bbd42efed5a7412..ec6615a17137c99169c37f7a1a83f578e790ab25 100644 (file)
@@ -116,6 +116,9 @@ static const struct default_language_entry msgtab[] = {
     {"NS_SET_DEFAULTS_CODE", "To reset %s's settings to the defaults, you must use 'set defaults %s'."},
     {"NS_SET_DEFAULTS_DONE", "All settings for %s have been reset to default values."},
     {"NS_SET_TRIGGER_OWNER", "You must have access 500 in %s to change the channel trigger."},
+    {"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."},
     {NULL, NULL}
 };
 
@@ -154,7 +157,7 @@ INCLUDE ALL CMD's HERE
 //#include "cmd_neonserv_unbanme.c"
 #include "cmd_neonserv_suspend.c"
 #include "cmd_neonserv_unsuspend.c"
-//#include "cmd_neonserv_wipeinfo.c"
+#include "cmd_neonserv_wipeinfo.c"
 //#include "cmd_neonserv_addban.c"
 //#include "cmd_neonserv_addtimeban.c"
 //#include "cmd_neonserv_delban.c"
@@ -189,7 +192,7 @@ INCLUDE ALL CMD's HERE
 //#include "cmd_neonserv_move.c"
 //#include "cmd_neonserv_dnrsearch.c"
 //#include "cmd_neonserv_search.c"
-//#include "cmd_neonserv_trace.c"
+#include "cmd_neonserv_trace.c"
 //#include "cmd_neonserv_say.c"
 //#include "cmd_neonserv_emote.c"
 //#include "cmd_neonserv_notice.c"
@@ -296,6 +299,10 @@ void init_NeonServ() {
     register_command(BOTID, "kick",         neonserv_cmd_kick,      1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,  "#channel_cankick",     0);
     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, "trace",        neonserv_cmd_trace,     1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,                                                   NULL,                   400);
+    
     
     start_bots();
     bind_bot_ready(neonserv_bot_ready);
diff --git a/cmd_neonserv_trace.c b/cmd_neonserv_trace.c
new file mode 100644 (file)
index 0000000..b1e1507
--- /dev/null
@@ -0,0 +1,95 @@
+
+#define NS_TRACE_CRITERIA_AUTHED  0x01
+#define NS_TRACE_CRITERIA_NUMCHAN 0x02
+
+struct neonserv_cmd_trace_criteria {
+    char *mask;
+    char *nick;
+    char *ident;
+    char *host;
+    char *account;
+    unsigned int flags : 4;
+    unsigned int authed : 1;
+    unsigned int used_channel : 5; //32 max
+    char *channel[10];
+    unsigned int numchannels;
+    unsigned int limit : 16;
+};
+
+static CMD_BIND(neonserv_cmd_trace) {
+    //ok parse the criterias
+    struct neonserv_cmd_trace_criteria *criteria = malloc(sizeof(*criteria));
+    if (!criteria) {
+        perror("malloc() failed");
+        return;
+    }
+    memset(criteria, 0, sizeof(*criteria));
+    criteria->limit = 50;
+    int i, show_user = 0;
+    if(!stricmp(argv[0], "print")) {
+        show_user = 1;
+    }
+    for(i = 1; i < argc; i += 2) {
+        if(argc <= i+1) {
+            reply(getTextBot(), user, "MODCMD_LESS_PARAM_COUNT");
+            return;
+        }
+        if(!stricmp(argv[i], "mask")) criteria->mask = argv[i+1];
+        else if(!stricmp(argv[i], "nick")) criteria->nick = argv[i+1];
+        else if(!stricmp(argv[i], "ident")) criteria->ident = argv[i+1];
+        else if(!stricmp(argv[i], "host")) criteria->host = argv[i+1];
+        else if(!stricmp(argv[i], "account")) criteria->account = argv[i+1];
+        else if(!stricmp(argv[i], "authed")) {
+            if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) {
+                criteria->authed = 1;
+            } else if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) {
+                criteria->authed = 0;
+            } else {
+                reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argv[i+1]);
+                return;
+            }
+            criteria->flags |= NS_TRACE_CRITERIA_AUTHED;
+        }
+        else if(!stricmp(argv[i], "channel")) criteria->channel[criteria->used_channel++] = argv[i+1];
+        else if(!stricmp(argv[i], "numchannels")) {
+            criteria->numchannels = atoi(argv[i+1]);
+            criteria->flags |= NS_TRACE_CRITERIA_NUMCHAN;
+        }
+        else if(!stricmp(argv[i], "limit")) {
+            criteria->limit = atoi(argv[i+1]);
+        }
+    }
+    char tmp[MAXLEN];
+    int matches = 0;
+    struct UserNode *cuser;
+    reply(getTextBot(), user, "NS_TRACE_HEADER");
+    for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) {
+        if(show_user && matches == criteria->limit) {
+            //too many
+            break;
+        }
+        if(criteria->mask) {
+            sprintf(tmp, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
+            if(match(criteria->mask, tmp)) continue;
+        }
+        if(criteria->nick && match(criteria->nick, cuser->nick)) continue;
+        if(criteria->ident && match(criteria->ident, cuser->ident)) continue;
+        if(criteria->host && match(criteria->host, cuser->host)) continue;
+        if(criteria->account && (!(cuser->flags & USERFLAG_ISAUTHED) || match(criteria->account, cuser->auth))) continue;
+        if((criteria->flags & NS_TRACE_CRITERIA_AUTHED) && (criteria->authed ^ (cuser->flags & USERFLAG_ISAUTHED))) continue;
+        if((criteria->flags & NS_TRACE_CRITERIA_NUMCHAN)) {
+            int ccount = 0;
+            struct ChanUser *chanuser;
+            for(chanuser = getUserChannels(cuser, NULL); chanuser; chanuser = getUserChannels(cuser, chanuser))
+                ccount++;
+            if(ccount < criteria->numchannels)
+                continue;
+        }
+        matches++;
+        //output
+        if(show_user) {
+            reply(getTextBot(), user, "%s!%s@%s %s", cuser->nick, cuser->ident, cuser->host, ((cuser->flags & USERFLAG_ISAUTHED) ? cuser->auth : "*"));
+        }
+    }
+    reply(getTextBot(), user, "NS_TRACE_FOUND", matches);
+}
diff --git a/cmd_neonserv_wipeinfo.c b/cmd_neonserv_wipeinfo.c
new file mode 100644 (file)
index 0000000..72275ab
--- /dev/null
@@ -0,0 +1,85 @@
+
+/*
+* argv[0] - nick / *auth
+*/
+static USERAUTH_CALLBACK(neonserv_cmd_wipeinfo_nick_lookup);
+static void neonserv_cmd_wipeinfo_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth);
+
+struct neonserv_cmd_wipeinfo_cache {
+    struct ClientSocket *client, *textclient;
+    struct UserNode *user;
+    struct ChanNode *chan;
+    char *nick;
+};
+
+static CMD_BIND(neonserv_cmd_wipeinfo) {
+    check_mysql();
+    if(argv[0][0] == '*') {
+        //we've got an auth
+        argv[0]++;
+        neonserv_cmd_wipeinfo_async1(client, getTextBot(), user, chan, argv[0], argv[0]);
+    } else {
+        struct UserNode *cuser = getUserByNick(argv[0]);
+        if(!cuser) {
+            cuser = createTempUser(argv[0]);
+            cuser->flags |= USERFLAG_ISTMPUSER;
+        }
+        if(cuser->flags & USERFLAG_ISAUTHED) {
+            neonserv_cmd_wipeinfo_async1(client, getTextBot(), user, chan, argv[0], cuser->auth);
+        } else {
+            struct neonserv_cmd_wipeinfo_cache *cache = malloc(sizeof(*cache));
+            if (!cache) {
+                perror("malloc() failed");
+                return;
+            }
+            cache->client = client;
+            cache->textclient = getTextBot();
+            cache->user = user;
+            cache->chan = chan;
+            cache->nick = strdup(argv[0]);
+            get_userauth(cuser, neonserv_cmd_wipeinfo_nick_lookup, cache);
+        }
+    }
+}
+
+static USERAUTH_CALLBACK(neonserv_cmd_wipeinfo_nick_lookup) {
+    struct neonserv_cmd_wipeinfo_cache *cache = data;
+    if(!user) {
+        //USER_DOES_NOT_EXIST
+        reply(cache->textclient, cache->user, "NS_USER_UNKNOWN", cache->nick);
+    }
+    else if(!(user->flags & USERFLAG_ISAUTHED)) {
+        //USER_NOT_AUTHED
+        reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
+    }
+    else
+        neonserv_cmd_wipeinfo_async1(cache->client, cache->textclient, cache->user, cache->chan, user->nick, user->auth);
+    free(cache->nick);
+    free(cache);
+}
+
+static void neonserv_cmd_wipeinfo_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth) {
+    //we've got a valid auth now...
+    MYSQL_RES *res;
+    MYSQL_ROW row;
+    int userid;
+    printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
+    res = mysql_use();
+    if ((row = mysql_fetch_row(res)) != NULL) {
+        userid = atoi(row[0]);
+        //check if the user is already added
+        printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid);
+        res = mysql_use();
+        if ((row = mysql_fetch_row(res)) != NULL) {
+            if(atoi(row[0]) >= getChannelAccess(user, chan, 1)) {
+                reply(textclient, user, "NS_USER_OUTRANKED", nick);
+                return;
+            }
+            //delete
+            printf_mysql_query("UPDATE `chanusers` SET `chanuser_infoline` = '' WHERE `chanuser_id` = '%s'", row[1]);
+            reply(textclient, user, "NS_WIPEINFO_DONE", nick, chan->name);
+            return;
+        }
+    }
+    reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name);
+}