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