d2568a54936e8c142e86e138bfca0d2de1c3845e
[NeonServV5.git] / cmd_neonserv_trace.c
1
2 #include "cmd_neonserv.h"
3
4 #define NS_TRACE_CRITERIA_AUTHED  0x01
5 #define NS_TRACE_CRITERIA_NUMCHAN 0x02
6
7 struct neonserv_cmd_trace_criteria {
8     char *mask;
9     char *nick;
10     char *ident;
11     char *host;
12     char *account;
13     unsigned int flags : 4;
14     unsigned int authed : 1;
15     unsigned int used_channel : 5; //32 max
16     char *channel[10];
17     unsigned int numchannels;
18     unsigned int limit : 16;
19 };
20
21 CMD_BIND(neonserv_cmd_trace) {
22     //ok parse the criterias
23     struct neonserv_cmd_trace_criteria *criteria = malloc(sizeof(*criteria));
24     if (!criteria) {
25         perror("malloc() failed");
26         return;
27     }
28     memset(criteria, 0, sizeof(*criteria));
29     criteria->limit = 50;
30     int i, show_user = 0;
31     if(!stricmp(argv[0], "print")) {
32         show_user = 1;
33     }
34     for(i = 1; i < argc; i += 2) {
35         if(argc <= i+1) {
36             reply(getTextBot(), user, "MODCMD_LESS_PARAM_COUNT");
37             return;
38         }
39         if(!stricmp(argv[i], "mask")) criteria->mask = argv[i+1];
40         else if(!stricmp(argv[i], "nick")) criteria->nick = argv[i+1];
41         else if(!stricmp(argv[i], "ident")) criteria->ident = argv[i+1];
42         else if(!stricmp(argv[i], "host")) criteria->host = argv[i+1];
43         else if(!stricmp(argv[i], "account")) criteria->account = argv[i+1];
44         else if(!stricmp(argv[i], "authed")) {
45             if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) {
46                 criteria->authed = 1;
47             } else if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) {
48                 criteria->authed = 0;
49             } else {
50                 reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argv[i+1]);
51                 return;
52             }
53             criteria->flags |= NS_TRACE_CRITERIA_AUTHED;
54         }
55         else if(!stricmp(argv[i], "channel")) criteria->channel[criteria->used_channel++] = argv[i+1];
56         else if(!stricmp(argv[i], "numchannels")) {
57             criteria->numchannels = atoi(argv[i+1]);
58             criteria->flags |= NS_TRACE_CRITERIA_NUMCHAN;
59         }
60         else if(!stricmp(argv[i], "limit")) {
61             criteria->limit = atoi(argv[i+1]);
62         }
63     }
64     char tmp[MAXLEN];
65     int matches = 0;
66     struct UserNode *cuser;
67     reply(getTextBot(), user, "NS_TRACE_HEADER");
68     for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) {
69         if(show_user && matches == criteria->limit) {
70             //too many
71             break;
72         }
73         if(criteria->mask) {
74             sprintf(tmp, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host);
75             if(match(criteria->mask, tmp)) continue;
76         }
77         if(criteria->nick && match(criteria->nick, cuser->nick)) continue;
78         if(criteria->ident && match(criteria->ident, cuser->ident)) continue;
79         if(criteria->host && match(criteria->host, cuser->host)) continue;
80         if(criteria->account && (!(cuser->flags & USERFLAG_ISAUTHED) || match(criteria->account, cuser->auth))) continue;
81         if((criteria->flags & NS_TRACE_CRITERIA_AUTHED) && (criteria->authed ^ (cuser->flags & USERFLAG_ISAUTHED))) continue;
82         if((criteria->flags & NS_TRACE_CRITERIA_NUMCHAN)) {
83             int ccount = 0;
84             struct ChanUser *chanuser;
85             for(chanuser = getUserChannels(cuser, NULL); chanuser; chanuser = getUserChannels(cuser, chanuser))
86                 ccount++;
87             if(ccount < criteria->numchannels)
88                 continue;
89         }
90         matches++;
91         //output
92         if(show_user) {
93             reply(getTextBot(), user, "%s!%s@%s %s", cuser->nick, cuser->ident, cuser->host, ((cuser->flags & USERFLAG_ISAUTHED) ? cuser->auth : "*"));
94         }
95     }
96     reply(getTextBot(), user, "NS_TABLE_COUNT", matches);
97 }