*** VERSION 5.4.0 ***
[NeonServV5.git] / src / modules / global.mod / cmd_global_modcmd.c
1 /* cmd_global_modcmd.c - NeonServ v5.4
2  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
3  * 
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.
8  * 
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.
13  * 
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/>. 
16  */
17
18 #include "cmd_global.h"
19
20 /*
21 * argv[0]     command
22 * argv[1]     setting
23 * argv[2]     value
24 */
25
26 static int global_cmd_modcmd_params(struct UserNode *user, struct cmd_binding *cbind, char *value);
27 static int global_cmd_modcmd_flags(struct UserNode *user, struct cmd_binding *cbind, char *value);
28 static int global_cmd_modcmd_caccess(struct UserNode *user, struct cmd_binding *cbind, char *value);
29 static int global_cmd_modcmd_oaccess(struct UserNode *user, struct cmd_binding *cbind, char *value);
30
31 CMD_BIND(global_cmd_modcmd) {
32     MYSQL_RES *res;
33     MYSQL_ROW row;
34     struct cmd_binding *cbind = find_botwise_cmd_binding(client->botid, client->clientid, argv[0]);
35     if (!cbind) {
36         reply(getTextBot(), user, "NS_UNBIND_NOT_FOUND", argv[0]);
37         return;
38     }
39     int uaccess = 0;
40     printf_mysql_query("SELECT `user_access` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
41     res = mysql_use();
42     if ((row = mysql_fetch_row(res)) != NULL) {
43         uaccess = atoi(row[0]);
44     }
45     int gaccess = ((cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS) ? cbind->global_access : cbind->func->global_access);
46     if(gaccess > uaccess) {
47         reply(getTextBot(), user, "NS_MODCMD_OUTRANKED", cbind->cmd, gaccess);
48         return;
49     }
50     if(argc > 1) {
51         char *value;
52         if(argc > 2) {
53             value = merge_argv(argv, 2, argc);
54         } else
55             value = NULL;
56         int log_event = 0;
57         if(!stricmp(argv[1], "caccess")) log_event = global_cmd_modcmd_caccess(user, cbind, value);
58         else if(!stricmp(argv[1], "oaccess")) log_event = global_cmd_modcmd_oaccess(user, cbind, value);
59         else if(!stricmp(argv[1], "parameters")) log_event = global_cmd_modcmd_params(user, cbind, value);
60         else if(!stricmp(argv[1], "flags")) log_event = global_cmd_modcmd_flags(user, cbind, value);
61         else {
62             reply(getTextBot(), user, "NS_MODCMD_SETTING", argv[1]);
63         }
64         if(log_event) {
65             logEvent(event);
66         }
67     } else {
68         reply(getTextBot(), user, "NS_MODCMD_HEADER", cbind->cmd);
69         global_cmd_modcmd_params(user, cbind, NULL);
70         global_cmd_modcmd_caccess(user, cbind, NULL);
71         global_cmd_modcmd_oaccess(user, cbind, NULL);
72         global_cmd_modcmd_flags(user, cbind, NULL);
73     }
74 }
75
76 static int global_cmd_modcmd_params(struct UserNode *user, struct cmd_binding *cbind, char *value) {
77     char parameters[MAXLEN];
78     int ret = 0;
79     if(cbind->paramcount) {
80         int i, parampos = 0;
81         for(i = 0; i < cbind->paramcount; i++) {
82             parampos += sprintf(parameters + parampos, (i ? " %s" : "%s"), cbind->parameters[i]);
83         }
84     } else
85         parameters[0] = '\0';
86     if(value) {
87         if(!strcmp(value, "*")) 
88             value = NULL;
89         bind_botwise_set_parameters(cbind->botid, cbind->clientid, cbind->cmd, value);
90         if(cbind->botid == 0)
91             printf_mysql_query("UPDATE `bot_binds` SET `parameters` = '%s' WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? escape_string(value) : ""), cbind->clientid, escape_string(cbind->cmd));
92         else
93             printf_mysql_query("UPDATE `bot_binds` SET `parameters` = '%s' WHERE `botclass` = '%d' AND `command` = '%s'", (value ? escape_string(value) : ""), cbind->botid, escape_string(cbind->cmd));
94         strcpy(parameters, (value ? value : ""));
95         ret = 1;
96     }
97     reply(getTextBot(), user, "\002PARAMETERS \002 %s", parameters);
98     return ret;
99 }
100
101 static const struct {
102     const char *name;
103     unsigned int flag;
104 } global_cmd_modcmd_show_flags[] = {
105     {"REQUIRE_CHAN",        CMDFLAG_REQUIRE_CHAN},      //The command requires a valid channel (at least one bot in it)
106     {"REQUIRE_AUTH",        CMDFLAG_REQUIRE_AUTH},      //The command requires the user to be authenticated
107     {"REQUIRE_GOD",         CMDFLAG_REQUIRE_GOD},       //The command requires the user to have security override enabled
108     {"REQUIRE_REGISTERED",  CMDFLAG_REGISTERED_CHAN},   //The command requires the channel to be registered (database entry)
109     {"CHECK_AUTH",          CMDFLAG_CHECK_AUTH},        //WHO the user if no auth is known, yet
110     {"CHANNEL_ARGS",        CMDFLAG_CHAN_PARAM},        //don't interpret channel arguments as channel - just pass them as a string
111     {"LOG",                 CMDFLAG_LOG},
112     {"OPLOG",               CMDFLAG_OPLOG},
113     {"FUNCMD",              CMDFLAG_FUNCMD},
114     {"ESCAPED_ARGS",        CMDFLAG_ESCAPE_ARGS},       //allows arguments to be escaped ("a\ b" = "a b" as one argument)
115     {"NO_CROSSCHAN",        CMDFLAG_NO_CROSSCHAN},
116     {NULL, 0}
117 };
118
119 static int global_cmd_modcmd_flags(struct UserNode *user, struct cmd_binding *cbind, char *value) {
120     char flags[MAXLEN];
121     int flagpos = 0;
122     int ret = 0;
123     unsigned int visible_flags = 0;
124     int i = 0;
125     while(global_cmd_modcmd_show_flags[i].name) {
126         if(cbind->func->flags & global_cmd_modcmd_show_flags[i].flag) {
127             flagpos += sprintf(flags + flagpos, (flagpos ? " %s" : "\00314%s"), global_cmd_modcmd_show_flags[i].name);
128         }
129         visible_flags |= global_cmd_modcmd_show_flags[i].flag;
130         i++;
131     }
132     if(flagpos) 
133         flags[flagpos++] = '\003';
134     if(value) {
135         int add = 1;
136         unsigned int current_flag = 0;
137         if(value[0] == '+') {
138             value++;
139         } else if(value[0] == '-') {
140             add = 0;
141             value++;
142         }
143         if(*value) {
144             i = 0;
145             while(global_cmd_modcmd_show_flags[i].name) {
146                 if(!stricmp(global_cmd_modcmd_show_flags[i].name, value)) {
147                     current_flag = global_cmd_modcmd_show_flags[i].flag;
148                     break;
149                 }
150                 i++;
151             }
152         }
153         if(cbind->func->flags & current_flag) {
154             reply(getTextBot(), user, "NS_MODCMD_STATIC_FLAG");
155             return 0;
156         }
157         if(add)
158             cbind->flags |= current_flag;
159         else
160             cbind->flags &= ~current_flag;
161         if(cbind->botid == 0)
162             printf_mysql_query("UPDATE `bot_binds` SET `flags` = '%u' WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (cbind->flags & visible_flags), cbind->clientid, escape_string(cbind->cmd));
163         else
164             printf_mysql_query("UPDATE `bot_binds` SET `flags` = '%u' WHERE `botclass` = '%d' AND `command` = '%s'", (cbind->flags & visible_flags), cbind->botid, escape_string(cbind->cmd));
165         ret = 1;
166     }
167     i = 0;
168     while(global_cmd_modcmd_show_flags[i].name) {
169         if(cbind->flags & global_cmd_modcmd_show_flags[i].flag) {
170             flagpos += sprintf(flags + flagpos, (flagpos ? " %s" : "%s"), global_cmd_modcmd_show_flags[i].name);
171         }
172         i++;
173     }
174     flags[flagpos] = '\0';
175     reply(getTextBot(), user, "\002FLAGS      \002 %s", flags);
176     return ret;
177 }
178
179 static int global_cmd_modcmd_caccess(struct UserNode *user, struct cmd_binding *cbind, char *value) {
180     char caccess[MAXLEN];
181     int ret = 0;
182     if(value) {
183         if(!strcmp(value, "*")) 
184             value = NULL;
185         bind_botwise_set_channel_access(cbind->botid, cbind->clientid, cbind->cmd, value);
186         if(cbind->botid == 0)
187             printf_mysql_query("UPDATE `bot_binds` SET `chan_access` = %s%s%s WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->clientid, escape_string(cbind->cmd));
188         else
189             printf_mysql_query("UPDATE `bot_binds` SET `chan_access` = %s%s%s WHERE `botclass` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->botid, escape_string(cbind->cmd));
190         
191         ret = 1;
192     }
193     if(cbind->flags & CMDFLAG_OVERRIDE_CHANNEL_ACCESS)
194         sprintf(caccess, "%s", cbind->channel_access);
195     else
196         sprintf(caccess, "\00314%s\003", (cbind->func->channel_access ? cbind->func->channel_access : "0"));
197     reply(getTextBot(), user, "\002CACCESS    \002 %s", caccess);
198     return ret;
199 }
200
201 static int global_cmd_modcmd_oaccess(struct UserNode *user, struct cmd_binding *cbind, char *value) {
202     char oaccess[MAXLEN];
203     int ret = 0;
204     if(value) {
205         if(!strcmp(value, "*")) 
206             value = NULL;
207         bind_botwise_set_global_access(cbind->botid, cbind->clientid, cbind->cmd, atoi(value));
208         if(cbind->botid == 0)
209             printf_mysql_query("UPDATE `bot_binds` SET `global_access` = %s%s%s WHERE `botclass` = '0' AND `botid` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->clientid, escape_string(cbind->cmd));
210         else
211             printf_mysql_query("UPDATE `bot_binds` SET `global_access` = %s%s%s WHERE `botclass` = '%d' AND `command` = '%s'", (value ? "'" : ""), (value ? escape_string(value) : "NULL"), (value ? "'" : ""), cbind->botid, escape_string(cbind->cmd));
212         
213         ret = 1;
214     }
215     if(cbind->flags & CMDFLAG_OVERRIDE_GLOBAL_ACCESS)
216         sprintf(oaccess, "%d", cbind->global_access);
217     else
218         sprintf(oaccess, "\00314%d\003", (cbind->func->global_access ? cbind->func->global_access : 0));
219     reply(getTextBot(), user, "\002OACCESS    \002 %s", oaccess);
220     return ret;
221 }
222