1 | /******************
2 | Copyright (c) 1999,2000,2001,2002 RIPE NCC
3 |
4 | All Rights Reserved
5 |
6 | Permission to use, copy, modify, and distribute this software and its
7 | documentation for any purpose and without fee is hereby granted,
8 | provided that the above copyright notice appear in all copies and that
9 | both that copyright notice and this permission notice appear in
10 | supporting documentation, and that the name of the author not be
11 | used in advertising or publicity pertaining to distribution of the
12 | software without specific, written prior permission.
13 |
14 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
16 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
17 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
18 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 | ***************************************/
21 |
22 | #include "rip.h"
23 |
24 | /* this is for purify - to display the memory allocation records */
25 | extern void purify_new_inuse(void);
26 |
27 |
28 | /*++++++++++++++++++++++++++++++++++++++
29 |
30 | All functions in this file share the same interface: they take the
31 | arguments to the command given by the user, pointer to a dynamic
32 | GString to which the command output should be appended and the
33 | connection data, so that some things can be displayed directly to it,
34 | bypassing the GString.
35 |
36 | int <command_something> return code. 0 indicates success.
37 | PC_RET_QUIT is a reserved code
38 | that indicates that the connection
39 | should be closed.
40 |
41 | char *input command arguments
42 |
43 | GString *output (dynamic) output string
44 |
45 | sk_conn_st *condat connection data
46 |
47 | ++++++++++++++++++++++++++++++++++++++*/
48 |
49 | /*++++++++++++++++++++++++++++++++++++++
50 |
51 | Relay functions for composed commands (eg. "set counter").
52 |
53 | They run the second word as a command from a specific array
54 | (show/set/stop/whatever). The hardcoded text is used only for help
55 | messages, printed in case the command is wrong as
56 |
57 | "<hardcoded> commands are: <list of possible commands>".
58 |
59 | ++++++++++++++++++++++++++++++++++++++*/
60 | int command_save(char *input, GString *output, sk_conn_st *condat) {
61 | return command_execute(save, "save ", input, output, condat);
62 | }
63 |
64 | int command_show(char *input, GString *output, sk_conn_st *condat) {
65 | return command_execute(show, "show ", input, output, condat);
66 | }
67 |
68 | int command_set( char *input, GString *output, sk_conn_st *condat) {
69 | return command_execute(set, "set ", input, output, condat);
70 | }
71 |
72 | int command_stop(char *input, GString *output, sk_conn_st *condat) {
73 | return command_execute(stop, "stop ", input, output, condat);
74 | }
75 |
76 |
77 | /*++++++++++++++++++++++++++++++++++++++
78 |
79 | Display available commands.
80 |
81 | ++++++++++++++++++++++++++++++++++++++*/
82 | int command_help(char *input, GString *output, sk_conn_st *condat)
83 | {
84 | /* by the time it came here, the "help" bit is already taken away. */
85 | return show_commands(command, "", output);
86 |
87 | }
88 |
89 |
90 | /*++++++++++++++++++++++++++++++++++++++
91 |
92 | Quit the config session.
93 |
94 | ++++++++++++++++++++++++++++++++++++++*/
95 | int command_quit(char *input, GString *output, sk_conn_st *condat) {
96 | /* Administrator wishes to quit. */
97 | return PC_RET_QUIT;
98 | } /* command_quit() */
99 |
100 | /*++++++++++++++++++++++++++++++++++++++
101 |
102 | Display the memory allocation records of purify(tm).
103 | The #define must be changed to activate this.
104 | The program will link only with purify.
105 |
106 | ++++++++++++++++++++++++++++++++++++++*/
107 | int command_purify(char *input, GString *output, sk_conn_st *condat)
108 | {
109 | #if 0
110 | purify_new_inuse();
111 | #else
112 | g_string_append(output, "NOP");
113 | #endif
114 |
115 | return 0;
116 | }
117 |
118 | int save_access_tree(char *input, GString *output, sk_conn_st *condat) {
119 | er_ret_t ret_err;
120 |
121 | ret_err = AC_persistence_save();
122 |
123 | switch (ret_err) {
124 | case AC_OK:
125 | g_string_append(output, "Save successful");
126 | break;
127 | case AC_SAVING:
128 | g_string_append(output, "Already saving");
129 | break;
130 | default:
131 | g_string_append(output, "Unknown error");
132 | return PC_RET_ERR;
133 | }
134 | return 0;
135 | }
136 |
137 | /*++++++++++++++++++++++++++++++++++++++
138 |
139 | Display a specific constant of the CO module.
140 |
141 | Argument: name of the constant.
142 |
143 | ++++++++++++++++++++++++++++++++++++++*/
144 | int show_const(char *input, GString *output, sk_conn_st *condat) {
145 | /* Administrator wishes to show constants. */
146 | char *result, *name, *cursor;
147 | int res = 0;
148 |
149 | if( strlen(input) > 0 ) {
150 | cursor = input;
151 | name = (char *)strsep(&cursor, " ");
152 |
153 | if( (result = CO_const_to_string(name)) != NULL ) {
154 | g_string_append(output, result);
155 | UT_free(result);
156 | }
157 | else {
158 | g_string_append(output, "unknown constant");
159 | res = PC_RET_ERR;
160 | }
161 | }
162 | else {
163 | g_string_append(output, "name required");
164 | res = PC_RET_ERR;
165 | }
166 |
167 | return res;
168 |
169 | } /* show_const() */
170 |
171 |
172 | /*++++++++++++++++++++++++++++++++++++++
173 |
174 | Display all the constants of the CO module.
175 |
176 | ++++++++++++++++++++++++++++++++++++++*/
177 | int show_consts(char *input, GString *output, sk_conn_st *condat)
178 | {
179 | /* Administrator wishes to show constants. */
180 | char *s = CO_to_string();
181 | g_string_append(output, s);
182 | UT_free(s);
183 | return 0;
184 | } /* show_consts() */
185 |
186 |
187 | /*++++++++++++++++++++++++++++++++++++++
188 |
189 | Display all the properties of the PR module.
190 |
191 | ++++++++++++++++++++++++++++++++++++++*/
192 | int show_props(char *input, GString *output, sk_conn_st *condat)
193 | {
194 | /* Administrator wishes to show properties. */
195 | char *s = PR_to_string();
196 | g_string_append(output, s);
197 | UT_free(s);
198 | return 0;
199 | } /* show_props() */
200 |
201 |
202 | /*++++++++++++++++++++++++++++++++++++++
203 |
204 | Display all running threads registered with the TA module.
205 |
206 | ++++++++++++++++++++++++++++++++++++++*/
207 | int show_threads(char *input, GString *output, sk_conn_st *condat)
208 | {
209 | /* Administrator wishes to show thread information. */
210 | char *s = TA_tostring();
211 | g_string_append(output, s);
212 | UT_free(s);
213 | return 0;
214 | } /* show_thread() */
215 |
216 |
217 | /*++++++++++++++++++++++++++++++++++++++
218 |
219 | Switch the session to a whois session.
220 |
221 | ++++++++++++++++++++++++++++++++++++++*/
222 | int show_whois(char *input, GString *output, sk_conn_st *condat)
223 | {
224 | /* Go to whois mode */
225 | PW_interact(condat->sock);
226 | return 0;
227 | } /* show_whois() */
228 |
229 |
230 | /*++++++++++++++++++++++++++++++++++++++
231 |
232 | Display the statistics about the server.
233 |
234 | ++++++++++++++++++++++++++++++++++++++*/
235 | int show_uptime(char *input, GString *output, sk_conn_st *condat)
236 | {
237 | char timestring[26];
238 | extern time_t SV_starttime;
239 |
240 | ctime_r(&SV_starttime, timestring);
241 | SK_cd_printf( condat,
242 | "System running since %sUptime in seconds: %ld \n\n",
243 | timestring,
244 | time(NULL) - SV_starttime);
245 |
246 | return 0;
247 | }
248 |
249 | /*++++++++++++++++++++++++++++++++++++++
250 |
251 | Display the whois access statistics from the AC module.
252 |
253 | ++++++++++++++++++++++++++++++++++++++*/
254 | int show_access(char *input, GString *output, sk_conn_st *condat)
255 | {
256 | int cnt = AC_print_access(output);
257 |
258 | g_string_sprintfa(output, "Found %d nodes\n", cnt);
259 |
260 | return 0;
261 | } /* show_access() */
262 |
263 |
264 | /*++++++++++++++++++++++++++++++++++++++
265 |
266 | Display the whois access control list from the AC module.
267 |
268 | ++++++++++++++++++++++++++++++++++++++*/
269 | int show_acl(char *input, GString *output, sk_conn_st *condat)
270 | {
271 | int cnt = AC_print_acl(output);
272 |
273 | g_string_sprintfa(output, "Found %d nodes\n", cnt);
274 |
275 | return 0;
276 | } /* show_acl() */
277 |
278 | /*++++++++++++++++++++++++++++++++++++++
279 |
280 | Display the access tree auto save state.
281 |
282 | ++++++++++++++++++++++++++++++++++++++*/
283 | int show_auto_save(char *input, GString *output, sk_conn_st *condat)
284 | {
285 | g_string_sprintfa(output, "Auto save is %d\n", ac_auto_save);
286 |
287 | return 0;
288 | } /* show_auto_save() */
289 |
290 |
291 | /*++++++++++++++++++++++++++++++++++++++
292 |
293 | Modify the whois access control list in the AC module.
294 |
295 | Arguments: IP[/prefixlength] column=value,column=value...
296 |
297 | Column names as in acl display. Unset columns are inherited.
298 |
299 | ++++++++++++++++++++++++++++++++++++++*/
300 | int set_acl(char *input, GString *output, sk_conn_st *condat)
301 | {
302 | int res = 0;
303 |
304 | /* first 8 characters ("set acl ") are already skipped */
305 | if( ! NOERR( AC_asc_acl_command_set( input, "Manual"))) {
306 | g_string_append(output, "Error!\n");
307 | res = PC_RET_ERR;
308 | }
309 | return res;
310 | }
311 |
312 | /*++++++++++++++++++++++++++++++++++++++
313 |
314 | Sets the auto save status of the access tree.
315 |
316 | Arguments: 0 = don't auto save, 1 = auto save
317 |
318 | ++++++++++++++++++++++++++++++++++++++*/
319 | int set_auto_save(char *input, GString *output, sk_conn_st *condat)
320 | {
321 | int res = 0;
322 |
323 | /* Lame */
324 | switch (input[0]) {
325 | case '0':
326 | ac_auto_save = 0;
327 | printf("0\n");
328 | break;
329 | case '1':
330 | ac_auto_save = 1;
331 | printf("1\n");
332 | break;
333 | default:
334 | printf("X\n");
335 | res = PC_RET_ERR;
336 | }
337 | return res;
338 | }
339 |
340 | /*++++++++++++++++++++++++++++++++++++++
341 |
342 | Reset the deny counter in the access tree to 0 (after reenabling)
343 | (AC module).
344 |
345 | Argument: IP address.
346 |
347 | ++++++++++++++++++++++++++++++++++++++*/
348 | int set_nodeny(char *input, GString *output, sk_conn_st *condat) {
349 |
350 | /* first 11 characters ("set nodeny ") are already skipped */
351 |
352 | if( ! NOERR( AC_asc_set_nodeny(input) )) {
353 | g_string_append(output, "Error\n");
354 | return PC_RET_ERR;
355 | }
356 | else {
357 | return 0;
358 | }
359 |
360 | } /* set_nodeny() */
361 |
362 |
363 | /*++++++++++++++++++++++++++++++++++++++
364 |
365 | Pause/resume update capability of the UD module.
366 |
367 | Argument: the word "pause" or "resume".
368 |
369 | ++++++++++++++++++++++++++++++++++++++*/
370 | int set_updates(char *input, GString *output, sk_conn_st *condat)
371 | {
372 | char argstr[17];
373 | int pause=0, resume=0;
374 | int res = 0;
375 |
376 | if( sscanf(input, "%16s", argstr) == 1) {
377 | pause = (strcmp(argstr,"pause") == 0);
378 | resume = (strcmp(argstr,"resume") == 0);
379 | }
380 |
381 | if( !pause && !resume ) {
382 | g_string_append(output, "syntax error.");
383 | res = PC_RET_ERR;
384 | }
385 | else {
386 | /* all params ok. just set the property */
387 | char *value = pause ? "0" : "1";
388 |
389 | if (CO_set_const("UD.do_update", value) == 0) {
390 | g_string_append(output, "Constant successfully set\n");
391 | }
392 | else {
393 | g_string_append(output, "Could not set\n");
394 | res = PC_RET_ERR;
395 | }
396 | }
397 | return res;
398 | }
399 | /*++++++++++++++++++++++++++++++++++++++
400 |
401 | Pause/resume queries.
402 |
403 | Argument: the word "pause" or "resume".
404 |
405 | ++++++++++++++++++++++++++++++++++++++*/
406 | int set_queries(char *input, GString *output, sk_conn_st *condat)
407 | {
408 | char argstr[17];
409 | int pause=0, resume=0;
410 | int res = 0;
411 |
412 | if( sscanf(input, "%16s", argstr) == 1) {
413 | pause = (strcmp(argstr,"pause") == 0);
414 | resume = (strcmp(argstr,"resume") == 0);
415 | }
416 |
417 | if( !pause && !resume ) {
418 | g_string_append(output, "syntax error.");
419 | res = PC_RET_ERR;
420 | }
421 | else {
422 |
423 | if(pause){
424 | PW_stopqueries();
425 | g_string_append(output, "Queries are stopped\n");
426 | }else {
427 | PW_startqueries();
428 | g_string_append(output, "Queries are unblocked\n");
429 | }
430 | }
431 | return res;
432 | }
433 |
434 |
435 | /*++++++++++++++++++++++++++++++++++++++
436 |
437 | Reset the source.
438 |
439 | Reloads the radix tree.
440 |
441 | Argument: the source name.
442 |
443 | ++++++++++++++++++++++++++++++++++++++*/
444 | int set_initrx(char *input, GString *output, sk_conn_st *condat)
445 | {
446 | ca_dbSource_t *source_hdl;
447 | int res = 0;
448 |
449 | source_hdl = ca_get_SourceHandleByName(input);
450 | if (source_hdl == NULL){
451 | g_string_append(output, "Unknown source");
452 | res = PC_RET_ERR;
453 | }
454 | else if(RP_init_trees( source_hdl ) != RP_OK ) {
455 | g_string_append(output, "Could not re-initialize radix trees");
456 | res = PC_RET_ERR;
457 | }
458 | else if(RP_sql_load_reg( source_hdl ) != RP_OK ) {
459 | g_string_append(output, "Could not load radix trees");
460 | res = PC_RET_ERR;
461 | }
462 | else {
463 | g_string_append(output, "radix trees reloaded successfully\n");
464 | }
465 | return res;
466 | }
467 | /*++++++++++++++++++++++++++++++++++++++
468 |
469 | Reset the "session time" and "# of tasks"
470 | of a specific thread registered with the TA module.
471 |
472 | ++++++++++++++++++++++++++++++++++++++*/
473 | #if 0
474 |
475 | /*
476 | XXX:
477 | I've removed this function because it is supposed to pass a pthread_t
478 | to the TA_reset_counters() function. But pthread_t is an opaque
479 | type - on FreeBSD it is a pointer to a structure, so you can't simply
480 | use sscanf() to get one!
481 |
482 | Shane
483 | 2001-09-05
484 |
485 | int set_counter(char *input, GString *output, sk_conn_st *condat)
486 | {
487 | unsigned thr_id;
488 |
489 | if( sscanf(input, "%d", &thr_id) == 1) {
490 | TA_reset_counters(thr_id);
491 | }
492 | return 0;
493 | }
494 | */
495 | #endif /* 0 */
496 |
497 |
498 |
499 | /*++++++++++++++++++++++++++++++++++++++
500 |
501 | Execute a command in the ER path processor of the ER module.
502 | (first subject to macro expansion of the first word).
503 |
504 | Argument is passed entirely to ER_macro_spec().
505 |
506 | ++++++++++++++++++++++++++++++++++++++*/
507 | int set_err(char *input, GString *output, sk_conn_st *condat)
508 | {
509 | char *erret = NULL;
510 | int res;
511 |
512 | res = ER_macro_spec(input, &erret);
513 | g_string_append(output, erret);
514 | UT_free(erret);
515 |
516 | return res;
517 | }
518 |
519 |
520 | /*++++++++++++++++++++++++++++++++++++++
521 |
522 | Show the current setup of the ER path system of the ER module.
523 |
524 | ++++++++++++++++++++++++++++++++++++++*/
525 | int show_err(char *input, GString *output, sk_conn_st *condat)
526 | {
527 | char *erret = NULL;
528 |
529 | er_print_paths(&erret);
530 | g_string_append(output, erret);
531 | UT_free(erret);
532 |
533 | return 0;
534 | }
535 |
536 |
537 | /*++++++++++++++++++++++++++++++++++++++
538 |
539 | Show the currently defined macros for the ER path system of the ER module.
540 |
541 | ++++++++++++++++++++++++++++++++++++++*/
542 | int show_macros(char *input, GString *output, sk_conn_st *condat)
543 | {
544 | ER_macro_list(condat);
545 | return 0;
546 | }
547 |
548 |
549 |
550 | /*++++++++++++++++++++++++++++++++++++++
551 |
552 | (re)define a macro for the ER path processor.
553 |
554 | Arguments: The first word is treated as a macro name.
555 | The rest of the line is treated as a macro definition.
556 |
557 | ++++++++++++++++++++++++++++++++++++++*/
558 | int set_macro(char *input, GString *output, sk_conn_st *condat)
559 | {
560 | char *name, *body;
561 |
562 | if( strlen(input) > 0 ) {
563 | body = input;
564 | name = (char *)strsep(&body, " ");
565 |
566 | ER_make_macro( name, body );
567 | }
568 |
569 | return 0;
570 | }
571 |
572 |
573 |
574 |
575 | /*++++++++++++++++++++++++++++++++++++++
576 |
577 | Trigger running of the socket watchdog actions for a specific thread
578 | (typically resulting in shutting down of a query thread).
579 |
580 | Arguments are "<socket_id> <thread_id>" as in the output of "show threads".
581 |
582 | Assumes the command is like "stop query 11 17".
583 | This is to limit ambiguities (a new thread on the same socket, for example).
584 | .
585 | ++++++++++++++++++++++++++++++++++++++*/
586 | #if 0
587 | /*
588 | XXX:
589 | I've removed this function because it is supposed to pass a pthread_t
590 | to the TA_trigger() function. But pthread_t is an opaque
591 | type - on FreeBSD it is a pointer to a structure, so you can't simply
592 | use sscanf() to get one!
593 |
594 | Shane
595 | 2001-09-05
596 |
597 | int stop_query(char *input, GString *output, sk_conn_st *condat)
598 | {
599 | int fd;
600 | unsigned thr;
601 |
602 |
603 | if( sscanf(input, "%d %ud", &fd, &thr) < 2 ) {
604 | g_string_append(output,"error!!");
605 | return PC_RET_ERR;
606 | }
607 | else {
608 | TA_trigger("whois", fd, thr);
609 | return 0;
610 | }
611 | }
612 | */
613 | #endif /* 0 */