1 | #include "mysql_driver.h"
2 | #include "access_control.h"
3 | #include "thread.h"
4 | #include "constants.h"
5 | #include "properties.h"
6 | #include "protocol_config.h"
7 | #include "protocol_whois.h"
8 | #include "ta.h"
9 | #include "pc_commands.h"
10 |
11 | #include "er_paths.h"
12 | #include "er_macro.h"
13 |
14 | /* this is for purify - to display the memory allocation records */
15 | extern void purify_new_inuse(void);
16 |
17 |
18 |
19 | /*++++++++++++++++++++++++++++++++++++++
20 |
21 | All functions in this file share the same interface: they take the
22 | arguments to the command given by the user, pointer to a dynamic
23 | GString to which the command output should be appended and the
24 | connection data, so that some things can be displayed directly to it,
25 | bypassing the GString.
26 |
27 | int <command_something> return code. 0 indicates success.
28 | PC_RET_QUIT is a reserved code
29 | that indicates that the connection
30 | should be closed.
31 |
32 | char *input command arguments
33 |
34 | GString *output (dynamic) output string
35 |
36 | sk_conn_st *condat connection data
37 |
38 | ++++++++++++++++++++++++++++++++++++++*/
39 |
40 | /*++++++++++++++++++++++++++++++++++++++
41 |
42 | Relay functions for composed commands (eg. "set counter").
43 |
44 | They run the second word as a command from a specific array
45 | (show/set/stop/whatever). The hardcoded text is used only for help
46 | messages, printed in case the command is wrong as
47 |
48 | "<hardcoded> commands are: <list of possible commands>".
49 |
50 | ++++++++++++++++++++++++++++++++++++++*/
51 | int command_show(char *input, GString *output, sk_conn_st *condat) {
52 | return command_execute(show, "show ", input, output, condat);
53 | }
54 |
55 | int command_set( char *input, GString *output, sk_conn_st *condat) {
56 | return command_execute(set, "set ", input, output, condat);
57 | }
58 |
59 | int command_stop(char *input, GString *output, sk_conn_st *condat) {
60 | return command_execute(stop, "stop ", input, output, condat);
61 | }
62 |
63 |
64 | /*++++++++++++++++++++++++++++++++++++++
65 |
66 | Display available commands.
67 |
68 | ++++++++++++++++++++++++++++++++++++++*/
69 | int command_help(char *input, GString *output, sk_conn_st *condat)
70 | {
71 | /* by the time it came here, the "help" bit is already taken away. */
72 | return show_commands(command, "", output);
73 |
74 | }
75 |
76 |
77 | /*++++++++++++++++++++++++++++++++++++++
78 |
79 | Quit the config session.
80 |
81 | ++++++++++++++++++++++++++++++++++++++*/
82 | int command_quit(char *input, GString *output, sk_conn_st *condat) {
83 | /* Administrator wishes to quit. */
84 | return PC_RET_QUIT;
85 | } /* command_quit() */
86 |
87 | /*++++++++++++++++++++++++++++++++++++++
88 |
89 | Display the memory allocation records of purify(tm).
90 | The #define must be changed to activate this.
91 | The program will link only with purify.
92 |
93 | ++++++++++++++++++++++++++++++++++++++*/
94 | int command_purify(char *input, GString *output, sk_conn_st *condat)
95 | {
96 | #if 0
97 | purify_new_inuse();
98 | #else
99 | g_string_append(output, "NOP");
100 | #endif
101 |
102 | return 0;
103 | }
104 |
105 |
106 | /*++++++++++++++++++++++++++++++++++++++
107 |
108 | Display a specific constant of the CO module.
109 |
110 | Argument: name of the constant.
111 |
112 | ++++++++++++++++++++++++++++++++++++++*/
113 | int show_const(char *input, GString *output, sk_conn_st *condat) {
114 | /* Administrator wishes to show constants. */
115 | char *result, *name, *cursor;
116 | int res = 0;
117 |
118 | if( strlen(input) > 0 ) {
119 | cursor = input;
120 | name = (char *)strsep(&cursor, " ");
121 |
122 | if( (result = CO_const_to_string(name)) != NULL ) {
123 | g_string_append(output, result);
124 | wr_free(result);
125 | }
126 | else {
127 | g_string_append(output, "unknown constant");
128 | res = PC_RET_ERR;
129 | }
130 | }
131 | else {
132 | g_string_append(output, "name required");
133 | res = PC_RET_ERR;
134 | }
135 |
136 | return res;
137 |
138 | } /* show_const() */
139 |
140 |
141 | /*++++++++++++++++++++++++++++++++++++++
142 |
143 | Display all the constants of the CO module.
144 |
145 | ++++++++++++++++++++++++++++++++++++++*/
146 | int show_consts(char *input, GString *output, sk_conn_st *condat)
147 | {
148 | /* Administrator wishes to show constants. */
149 | char *s = CO_to_string();
150 | g_string_append(output, s);
151 | free(s);
152 | return 0;
153 | } /* show_consts() */
154 |
155 |
156 | /*++++++++++++++++++++++++++++++++++++++
157 |
158 | Display all the properties of the PR module.
159 |
160 | ++++++++++++++++++++++++++++++++++++++*/
161 | int show_props(char *input, GString *output, sk_conn_st *condat)
162 | {
163 | /* Administrator wishes to show properties. */
164 | char *s = PR_to_string();
165 | g_string_append(output, s);
166 | free(s);
167 | return 0;
168 | } /* show_props() */
169 |
170 |
171 | /*++++++++++++++++++++++++++++++++++++++
172 |
173 | Display all running threads registered with the TA module.
174 |
175 | ++++++++++++++++++++++++++++++++++++++*/
176 | int show_threads(char *input, GString *output, sk_conn_st *condat)
177 | {
178 | /* Administrator wishes to show thread information. */
179 | char *s = TA_tostring();
180 | g_string_append(output, s);
181 | free(s);
182 | return 0;
183 | } /* show_thread() */
184 |
185 |
186 | /*++++++++++++++++++++++++++++++++++++++
187 |
188 | Switch the session to a whois session.
189 |
190 | ++++++++++++++++++++++++++++++++++++++*/
191 | int show_whois(char *input, GString *output, sk_conn_st *condat)
192 | {
193 | /* Go to whois mode */
194 | PW_interact(condat->sock);
195 | return 0;
196 | } /* show_whois() */
197 |
198 |
199 | /*++++++++++++++++++++++++++++++++++++++
200 |
201 | Display the statistics about the server.
202 |
203 | ++++++++++++++++++++++++++++++++++++++*/
204 | int show_uptime(char *input, GString *output, sk_conn_st *condat)
205 | {
206 | char timestring[26];
207 | extern time_t SV_starttime;
208 |
209 | ctime_r(&SV_starttime, timestring);
210 | SK_cd_printf( condat,
211 | "System running since %sUptime in seconds: %ld \n\n",
212 | timestring,
213 | time(NULL) - SV_starttime);
214 |
215 | return 0;
216 | }
217 |
218 | /*++++++++++++++++++++++++++++++++++++++
219 |
220 | Display the whois access statistics from the AC module.
221 |
222 | ++++++++++++++++++++++++++++++++++++++*/
223 | int show_access(char *input, GString *output, sk_conn_st *condat)
224 | {
225 | int cnt = AC_print_access(output);
226 |
227 | g_string_sprintfa(output, "Found %d nodes\n", cnt);
228 |
229 | return 0;
230 | } /* show_access() */
231 |
232 |
233 | /*++++++++++++++++++++++++++++++++++++++
234 |
235 | Display the whois access control list from the AC module.
236 |
237 | ++++++++++++++++++++++++++++++++++++++*/
238 | int show_acl(char *input, GString *output, sk_conn_st *condat)
239 | {
240 | int cnt = AC_print_acl(output);
241 |
242 | g_string_sprintfa(output, "Found %d nodes\n", cnt);
243 |
244 | return 0;
245 | } /* show_acl() */
246 |
247 |
248 | /*++++++++++++++++++++++++++++++++++++++
249 |
250 | Modify the whois access control list in the AC module.
251 |
252 | Arguments: IP[/prefixlength] column=value,column=value...
253 |
254 | Column names as in acl display. Unset columns are inherited.
255 |
256 | ++++++++++++++++++++++++++++++++++++++*/
257 | int set_acl(char *input, GString *output, sk_conn_st *condat)
258 | {
259 | int res = 0;
260 |
261 | /* first 8 characters ("set acl ") are already skipped */
262 | if( ! NOERR( AC_asc_acl_command_set( input, "Manual"))) {
263 | g_string_append(output, "Error!\n");
264 | res = PC_RET_ERR;
265 | }
266 | return res;
267 | }
268 |
269 | /*++++++++++++++++++++++++++++++++++++++
270 |
271 | Reset the deny counter in the access tree to 0 (after reenabling)
272 | (AC module).
273 |
274 | Argument: IP address.
275 |
276 | ++++++++++++++++++++++++++++++++++++++*/
277 | int set_nodeny(char *input, GString *output, sk_conn_st *condat) {
278 |
279 | /* first 11 characters ("set nodeny ") are already skipped */
280 |
281 | if( ! NOERR( AC_asc_set_nodeny(input) )) {
282 | g_string_append(output, "Error\n");
283 | return PC_RET_ERR;
284 | }
285 | else {
286 | return 0;
287 | }
288 |
289 | } /* set_nodeny() */
290 |
291 |
292 | /*++++++++++++++++++++++++++++++++++++++
293 |
294 | Pause/resume update capability of the UD module.
295 |
296 | Argument: the word "pause" or "resume".
297 |
298 | ++++++++++++++++++++++++++++++++++++++*/
299 | int set_updates(char *input, GString *output, sk_conn_st *condat)
300 | {
301 | char argstr[17];
302 | int pause=0, resume=0;
303 | int res = 0;
304 |
305 | if( sscanf(input, "%16s", argstr) == 1) {
306 | pause = (strcmp(argstr,"pause") == 0);
307 | resume = (strcmp(argstr,"resume") == 0);
308 | }
309 |
310 | if( !pause && !resume ) {
311 | g_string_append(output, "syntax error.");
312 | res = PC_RET_ERR;
313 | }
314 | else {
315 | /* all params ok. just set the property */
316 | char *value = pause ? "0" : "1";
317 |
318 | if (CO_set_const("UD.do_update", value) == 0) {
319 | g_string_append(output, "Constant successfully set\n");
320 | }
321 | else {
322 | g_string_append(output, "Could not set\n");
323 | res = PC_RET_ERR;
324 | }
325 | }
326 | return res;
327 | }
328 |
329 |
330 | /*++++++++++++++++++++++++++++++++++++++
331 |
332 | Reset the "session time" and "# of tasks"
333 | of a specific thread registered with the TA module.
334 |
335 | ++++++++++++++++++++++++++++++++++++++*/
336 | int set_counter(char *input, GString *output, sk_conn_st *condat)
337 | {
338 | unsigned thr_id;
339 |
340 | if( sscanf(input, "%d", &thr_id) == 1) {
341 | TA_reset_counters(thr_id);
342 | }
343 | return 0;
344 | }
345 |
346 |
347 |
348 | /*++++++++++++++++++++++++++++++++++++++
349 |
350 | Execute a command in the ER path processor of the ER module.
351 | (first subject to macro expansion of the first word).
352 |
353 | Argument is passed entirely to ER_macro_spec().
354 |
355 | ++++++++++++++++++++++++++++++++++++++*/
356 | int set_err(char *input, GString *output, sk_conn_st *condat)
357 | {
358 | char *erret = NULL;
359 | int res;
360 |
361 | res = ER_macro_spec(input, &erret);
362 | g_string_append(output, erret);
363 | free(erret);
364 |
365 | return res;
366 | }
367 |
368 |
369 | /*++++++++++++++++++++++++++++++++++++++
370 |
371 | Show the current setup of the ER path system of the ER module.
372 |
373 | ++++++++++++++++++++++++++++++++++++++*/
374 | int show_err(char *input, GString *output, sk_conn_st *condat)
375 | {
376 | char *erret = NULL;
377 |
378 | er_print_paths(&erret);
379 | g_string_append(output, erret);
380 | free(erret);
381 |
382 | return 0;
383 | }
384 |
385 |
386 | /*++++++++++++++++++++++++++++++++++++++
387 |
388 | Show the currently defined macros for the ER path system of the ER module.
389 |
390 | ++++++++++++++++++++++++++++++++++++++*/
391 | int show_macros(char *input, GString *output, sk_conn_st *condat)
392 | {
393 | ER_macro_list(condat);
394 | return 0;
395 | }
396 |
397 |
398 |
399 | /*++++++++++++++++++++++++++++++++++++++
400 |
401 | (re)define a macro for the ER path processor.
402 |
403 | Arguments: The first word is treated as a macro name.
404 | The rest of the line is treated as a macro definition.
405 |
406 | ++++++++++++++++++++++++++++++++++++++*/
407 | int set_macro(char *input, GString *output, sk_conn_st *condat)
408 | {
409 | char *name, *body;
410 |
411 | if( strlen(input) > 0 ) {
412 | body = input;
413 | name = (char *)strsep(&body, " ");
414 |
415 | ER_make_macro( name, body );
416 | }
417 |
418 | return 0;
419 | }
420 |
421 |
422 |
423 |
424 | /*++++++++++++++++++++++++++++++++++++++
425 |
426 | Trigger running of the socket watchdog actions for a specific thread
427 | (typically resulting in shutting down of a query thread).
428 |
429 | Arguments are "<socket_id> <thread_id>" as in the output of "show threads".
430 |
431 | Assumes the command is like "stop query 11 17".
432 | This is to limit ambiguities (a new thread on the same socket, for example).
433 | .
434 | ++++++++++++++++++++++++++++++++++++++*/
435 | int stop_query(char *input, GString *output, sk_conn_st *condat)
436 | {
437 | int fd;
438 | unsigned thr;
439 |
440 |
441 | if( sscanf(input, "%d %ud", &fd, &thr) < 2 ) {
442 | g_string_append(output,"error!!");
443 | return PC_RET_ERR;
444 | }
445 | else {
446 | TA_trigger("whois", fd, thr);
447 | return 0;
448 | }
449 | }