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