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 */