1 /* cmd_neonserv_search.c - NeonServ v5.3
2 * Copyright (C) 2011-2012 Philipp Kreil (pk910)
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "cmd_neonserv.h"
20 #define CMD_SEARCH_FLAG_HAS_NODELETE 0x001
21 #define CMD_SEARCH_FLAG_NOT_NODELETE 0x002
22 #define CMD_SEARCH_FLAG_HAS_SUSPENDED 0x004
23 #define CMD_SEARCH_FLAG_NOT_SUSPENDED 0x008
24 #define CMD_SEARCH_FLAG_IS_JOINED 0x010
25 #define CMD_SEARCH_FLAG_NOT_JOINED 0x020
26 #define CMD_SEARCH_FLAG_IS_OPPED 0x040
27 #define CMD_SEARCH_FLAG_NOT_OPPED 0x080
28 #define CMD_SEARCH_FLAG_IS_VOICED 0x100
29 #define CMD_SEARCH_FLAG_NOT_VOICED 0x200
30 #define CMD_SEARCH_FLAG_STATES 0x3f0
32 struct neonserv_cmd_search_criteria {
36 unsigned int flags : 16;
37 unsigned int unvisited;
38 unsigned int registered;
39 unsigned int limit : 16;
42 CMD_BIND(neonserv_cmd_search) {
43 //ok parse the criterias
44 struct neonserv_cmd_search_criteria *criteria = malloc(sizeof(*criteria));
46 perror("malloc() failed");
49 memset(criteria, 0, sizeof(*criteria));
51 int i, show_chans = 0, positive;
52 if(!stricmp(argv[0], "print")) {
55 for(i = 1; i < argc; i += 2) {
57 reply(getTextBot(), user, "MODCMD_LESS_PARAM_COUNT");
60 if(!stricmp(argv[i], "name")) criteria->name = argv[i+1];
61 else if(!stricmp(argv[i], "registrar")) criteria->registrar = argv[i+1];
62 else if(!stricmp(argv[i], "onchan")) criteria->onchan = argv[i+1];
63 else if(!stricmp(argv[i], "unvisited")) criteria->unvisited = strToTime(user, argv[i+1]);
64 else if(!stricmp(argv[i], "registered")) criteria->registered = strToTime(user, argv[i+1]);
65 else if(!stricmp(argv[i], "flags")) {
66 if(argv[i+1][0] == '+') {
69 } else if(argv[i+1][0] == '-') {
74 if(!stricmp(argv[i+1], "nodelete")) {
76 criteria->flags |= CMD_SEARCH_FLAG_HAS_NODELETE;
78 criteria->flags |= CMD_SEARCH_FLAG_NOT_NODELETE;
79 } else if(!stricmp(argv[i+1], "suspended")) {
81 criteria->flags |= CMD_SEARCH_FLAG_HAS_SUSPENDED;
83 criteria->flags |= CMD_SEARCH_FLAG_NOT_SUSPENDED;
86 else if(!stricmp(argv[i], "state")) {
87 if(argv[i+1][0] == '+') {
90 } else if(argv[i+1][0] == '-') {
95 if(!stricmp(argv[i+1], "joined")) {
97 criteria->flags |= CMD_SEARCH_FLAG_IS_JOINED;
99 criteria->flags |= CMD_SEARCH_FLAG_NOT_JOINED;
100 } else if(!stricmp(argv[i+1], "opped")) {
102 criteria->flags |= CMD_SEARCH_FLAG_IS_OPPED;
104 criteria->flags |= CMD_SEARCH_FLAG_NOT_OPPED;
105 } else if(!stricmp(argv[i+1], "voiced")) {
107 criteria->flags |= CMD_SEARCH_FLAG_IS_VOICED;
109 criteria->flags |= CMD_SEARCH_FLAG_NOT_VOICED;
112 else if(!stricmp(argv[i], "limit")) {
113 criteria->limit = atoi(argv[i+1]);
117 reply(getTextBot(), user, "NS_SEARCH_HEADER");
118 MYSQL_RES *res, *res2;
120 printf_mysql_query("SELECT `channel_name`, `user_user`, `channel_registered`, `channel_nodelete`, `suspended`, `channel_id` FROM `bot_channels` LEFT JOIN `bots` ON `bots`.`id` = `botid` LEFT JOIN `channels` ON `chanid` = `channel_id` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `botclass` = '%d' AND `active` = '1'", client->botid);
122 while ((row = mysql_fetch_row(res)) != NULL) {
123 if(show_chans && matches == criteria->limit) {
127 if(criteria->name && match(criteria->name, row[0])) continue;
128 if(criteria->registrar && row[1] && match(criteria->registrar, row[1])) continue;
129 if(criteria->unvisited) {
130 printf_mysql_query("SELECT `chanuser_seen` FROM `chanusers` WHERE `chanuser_cid` = '%s' ORDER BY `chanuser_seen` DESC LIMIT 1", row[5]);
132 row2 = mysql_fetch_row(res2);
134 if((time(0) - atoi(row2[0])) < criteria->unvisited) continue;
136 if(criteria->registered && (time(0) - atoi(row[2])) < criteria->registered) continue;
138 if((criteria->flags & CMD_SEARCH_FLAG_HAS_NODELETE) && strcmp(row[3], "1")) continue;
139 if((criteria->flags & CMD_SEARCH_FLAG_NOT_NODELETE) && strcmp(row[3], "0")) continue;
140 if((criteria->flags & CMD_SEARCH_FLAG_HAS_SUSPENDED) && strcmp(row[4], "1")) continue;
141 if((criteria->flags & CMD_SEARCH_FLAG_NOT_SUSPENDED) && strcmp(row[4], "0")) continue;
142 if((criteria->flags & CMD_SEARCH_FLAG_STATES) || criteria->onchan) {
143 struct ChanNode *channel = getChanByName(row[0]);
144 if(criteria->onchan) {
145 if(!channel) continue;
146 struct ChanUser *chanuser = NULL;
147 for(chanuser = getChannelUsers(channel, NULL); chanuser; chanuser = getChannelUsers(channel, chanuser)) {
148 if(!match(criteria->onchan, chanuser->user->nick)) break;
150 if(!chanuser) continue;
152 if((criteria->flags & CMD_SEARCH_FLAG_IS_JOINED) && !channel) continue;
153 if((criteria->flags & CMD_SEARCH_FLAG_NOT_JOINED) && channel) continue;
154 if(channel && (criteria->flags & (CMD_SEARCH_FLAG_IS_OPPED | CMD_SEARCH_FLAG_NOT_OPPED | CMD_SEARCH_FLAG_IS_VOICED | CMD_SEARCH_FLAG_NOT_VOICED))) {
156 struct ClientSocket *bot;
157 for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
158 if(bot->botid == client->botid) {
159 struct ChanUser *chanuser = getChanUser(bot->user, channel);
161 flags = chanuser->flags;
166 if((criteria->flags & CMD_SEARCH_FLAG_IS_OPPED) && !(flags & CHANUSERFLAG_OPPED)) continue;
167 if((criteria->flags & CMD_SEARCH_FLAG_NOT_OPPED) && (flags & CHANUSERFLAG_OPPED)) continue;
168 if((criteria->flags & CMD_SEARCH_FLAG_IS_VOICED) && !(flags & CHANUSERFLAG_VOICED)) continue;
169 if((criteria->flags & CMD_SEARCH_FLAG_NOT_VOICED) && (flags & CHANUSERFLAG_VOICED)) continue;
175 reply(getTextBot(), user, "%s", row[0]);
178 reply(getTextBot(), user, "NS_TABLE_COUNT", matches);