rearranged NeonServ code to be modular
[NeonServV5.git] / src / modules / NeonServ.mod / cmd_neonserv_trace.c
diff --git a/src/modules/NeonServ.mod/cmd_neonserv_trace.c b/src/modules/NeonServ.mod/cmd_neonserv_trace.c
new file mode 100644 (file)
index 0000000..eacb67f
--- /dev/null
@@ -0,0 +1,113 @@
+/* cmd_neonserv_trace.c - NeonServ v5.3
+ * Copyright (C) 2011-2012  Philipp Kreil (pk910)
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License 
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include "cmd_neonserv.h"
+
+#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;
+};
+
+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_TABLE_COUNT", matches);
+}